Tutorialserie by Schranz0r

Previous topic - Next topic

Schranz0r

Hier ein kleines Tutorial zum Thema Tilemaps und das "nur" zeichnen der sichbaren Tiles.
Soll ich mehr erklären, oder reicht der Quellcode + Kommentare schon aus?!
Eure Meinung bitte!

Code (glbasic) Select
// --------------------------------- //
// Project: Map-Tutorial
// Start: Saturday, July 02, 2011
// IDE Version: 10.001


SETCURRENTDIR("Media") // Mediadateien-Ordner


// Laden von einer Grastextur
LOADSPRITE "grasseg.png", 1

// Setzen der Lokalen Variablen
LOCAL MaxTilesX=1000, MaxTilesY=1000, TileSize=32, ScreenX, ScreenY, TilesPerScreenX, TilesPerScreenY
GETSCREENSIZE ScreenX, ScreenY

// tiles die rein rechnerisch zu sehen sind auf der map, was beim Scrollen aber so nicht ganz stimmt, mehr dazu weiter unten!
TilesPerScreenX = ScreenX / TileSize
TilesPerScreenY = ScreenY / TileSize

// Erstelle das Maparray
LOCAL Map[]
DIM Map[MaxTilesX][MaxTilesY] // setze Mapgröße ( Mal ein Test mit so schlappen 1.Mio Tiles! )

FOR x = 0 TO MaxTilesX-1
FOR y = 0 TO MaxTilesY-1

Map[x][y] = RND(1) // Map per Zufall füllen

NEXT
NEXT


// Setzen der Lokalen Variablen ( habe ich gesplitted, der Übersicht halber :) )
LOCAL ScrollX, ScrollY, MaxScrollX, MaxScrollY, ScrollStartX, ScrollStartY, VisibleTilesOnScreenX, VisibleTilesOnScreenY, ScrollSpeed = 6

// Ausrechnen was man als maximalen Scrollwert haben darf, ausgehend vom Teil oben links!
MaxScrollX = (MaxTilesX-TilesPerScreenX)*TileSize
MaxScrollY = (MaxTilesY-TilesPerScreenY)*TileSize



WHILE TRUE


IF KEY(203) // links scrollen

IF ScrollX > 0  // wenn größer Null, darf nach links gescrolled werden
DEC ScrollX,ScrollSpeed
ELSE
ScrollX = 0
ENDIF

ENDIF

IF KEY(205) // rechts scrollen

IF ScrollX < MaxScrollX // wenn kleiner maximaler Scrollwert darf nach rechts gescrollt werden
INC ScrollX,ScrollSpeed
ELSE
ScrollX = MaxScrollX // wenn größer als Maximaler Scrollwert, dann Scrollwert = maximaler Scrollwert
ENDIF

ENDIF



// Hoch und runter verhält sich wie links und rechts!
IF KEY(200) // hoch scrollen

IF ScrollY > 0
DEC ScrollY,ScrollSpeed
ELSE
ScrollY = 0
ENDIF

ENDIF

IF KEY(208) //runter scrollen

IF ScrollY < MaxScrollY
INC ScrollY,ScrollSpeed
ELSE
ScrollY = MaxScrollY
ENDIF

ENDIF

// ausrechnen welches das aktuelle sichbare linke/obere Tile ist!
// INTEGER() weil wir eine Ganzzahl(Integer) brauchen
ScrollStartX = INTEGER(ScrollX / TileSize)
ScrollStartY = INTEGER(ScrollY / TileSize)


// Fixen des unschönen aufpoppens der Tiles am rechten und unteren Rand
IF ScrollStartX+TilesPerScreenX < MaxTilesX // ist die aktuelle scrollposition+der sichtbaren Tiles auf dem Screen kleiner als die Mapgröße
VisibleTilesOnScreenX = TilesPerScreenX + 1 // fixe das problem indem wir immer ein Tile vorraus mitzeichen!
ELSE
VisibleTilesOnScreenX = TilesPerScreenX // Ist die Position+Sichtbare Tile größer dann zeichen wir nur das, was wir auch sehen
ENDIF

// das gleiche wie in X-Richtung
IF ScrollStartY+TilesPerScreenY < MaxTilesY
VisibleTilesOnScreenY = TilesPerScreenY + 1
ELSE
VisibleTilesOnScreenY = TilesPerScreenY
ENDIF


FOR x = ScrollStartX TO ScrollStartX+VisibleTilesOnScreenX-1 // Zeichne vom ersten sichtbaren Tile bis zum letzten sichtbaren in X-Richtung
FOR y = ScrollStartY TO ScrollStartY+VisibleTilesOnScreenY-1 // Zeichne vom ersten sichtbaren Tile bis zum letzten sichtbaren in Y-Richtung

SELECT Map[x][y] // was spuckt uns die Map aus
CASE 1 // wenn 1 dann zeichne ein stück Gras
DRAWSPRITE 1, x*TileSize-ScrollX, y*TileSize-ScrollY  // X-Position der Map * TileSize - ScrollX-Position...  Minus wird hier gemacht weil es schöner ist mit Positiven Zahlen zu rechnen :D
ENDSELECT

NEXT
NEXT

// ein paar Debugauswürfe auf den Screen, um zu schauen ob auch alles wirklich funzt.
// VisibleTilesOnScreenX + ScrollStartX = Tilenummer auf rechter Seite +1
// ausser die Map ist am ende dann ist es einfach nur Tilenummmer

PRINT "VisibleTilesOnScreenX: "+VisibleTilesOnScreenX, 10, 10
PRINT "VisibleTilesOnScreenY: "+VisibleTilesOnScreenY, 10, 20

PRINT "ScrollStartX: "+ScrollStartX, 10,40
PRINT "ScrollStartY: "+ScrollStartY, 10,50


PRINT "Tile auf rechter Seite : "+(ScrollStartX+TilesPerScreenX),10,70
PRINT "Tile auf unterer Seite : "+(ScrollStartY+TilesPerScreenY),10,80

SHOWSCREEN
WEND
END


[attachment deleted by admin]
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

S.O.P.M.

#1
Super! Bin gerade dabei, den Code zu verstehen. Die Performance ist bombastisch, ich erreiche trotz meiner begrenzten Hardware an die 200 fps. Was ich schonmal feststelle ist, dass du mit noch mehr Variablen arbeitest, um jegliche Berechnung während des Zeichnens zu sparen, somit rechnest du schon vorher aus, wieviele Tiles je Richtung auf den Screen passen, während ich diese Berechnung mit in die 2-fach verschachtelte Schleife für das Zeichnen eingebaut habe.

Zum besseren Verständnis wäre es hilfreich, die Funktionen der Variablen am Anfang zu erläutern, genau, wie ich das gemacht habe. Am besten alle untereinander schreiben und dahinter dann per Kommentar die Funktion.
Notebook PC Samsung E372 Core i5 @ 2,6 GHz; 4 GB RAM; Win 7 Home Premium

Schranz0r

Hi, ja das mit den Funktionen der Variablen machen ich später noch rein.
Glaube nich, das eine Rechnung in einer zweifachen FOR-Schleife böse ins Gewicht fällt, hab nur der Übersichthalber vorberechnet :)
Ich hab halt geschaut den Variablen gleich sinnvolle Namen zu geben, so das es für mich dachte ich schlüssig ist was sie machen.

OK Multilayer damit zu machen ist ja auch einfach, soll ich das nochmal einfügen, oder bringt das jeder selber so hin?
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard