GLB:Levelschleife und Scrolling
Aus PandoraWiki
Im dritten Teil gehts nun ans Eingemachte. Wir behandeln die Levelschleife und nehmen gleich noch das Scrolling mit hinzu.
Da manche Sachen nun im ersten Moment vielleicht etwas komplex erscheinen, kann ich euch folgende Tips geben:
- macht eine Ausdruck vom Code. Manche z.B. können auf Papier übersichtlicher lesen als auf dem Bildschirm.
- kreuzt an, was ihr vom Code bereits versteht bzw. was ihr noch nicht versteht.
- versucht mal den einen oder andern Wert zu verändern um zu sehen, was das bewirkt.
Aktuellen Code gibt es wie immer im Pandora-Datei-Archiv: http://dl.openhandhelds.org/cgi-bin/pandora.cgi?0,0,0,0,46,28
Neu hinzugekommen sind die beiden Dateien level00.gbas welche die Levelschleife beinhaltet, library.gbas die allgemeine Funktionen und Subroutinen beinhalten wird. Dann noch isdo/gfx/level00.png (enthält Hinter- und Vordergrundgrafik) sowie isdo/level00.dat wo die Indexlisten f?r die Tilemaps (siehe weiter unten) gespeichert sind.
So. In isdo.gbas "befreien" wir wieder unsere auskommentierte Zeile.
CASE AS_LEVEL00 ; AppState=RunLevel00()
Dann ändern wir folgende Zeile von AS_INTRO zu AS_MENU damit wir das Intro jeweils überspringen können.
GLOBAL AppState% = AS_MENUWir werden unsere Grafik nach jeder Anzeige wieder neu aufbauen und zwar in dieser Reihenfolge:
- Hintergrundgrafik (LayerBG)
- Vordergrundgrafik (LayerFG)
- Statusanzeige oben (im Moment nur schwarzes gefülltes Rechteck)
Dazu müssen wir einige neue TYPE's definieren.
TYPE TLayerFG Map%[4096] ENDTYPE
ist eine Index-Liste welche die Tilenummern der Vordergrundgrafik enthält.
TYPE TLayerBG Map%[2048] ENDTYPE
ist eine Index-Liste welche die Tilenummern der Hintergrundgrafik enthält. Die Tilegrafik ist in isdo/gfx/level00.png gespeichert und besteht aus 16x16 Tiles von welchen jedes 16x16 Pixel gross ist.
Unsere Tilemaps sind folgendermassen aufgebaut:
Vordegrund Hintergrund
[00][16][..][4080] [00][16][..][2032]
[01][17][..][4081] [01][17][..][2033]
[02][18][..][4082] [02][18][..][2034]
[03][19][..][4083] [03][19][..][2035]
[..][..][..][ .. ] [..][..][..][ .. ]
[..][..][..][ .. ] [..][..][..][ .. ]
[15][31][..][4095] [15][31][..][2047]Als Beispiel:
LayerFG[0]=255
Damit setzen wir das unterste rechte Tile an die oberste linken Stelle in unserer Tilemap (Vordergrund). Falls ihr zu den Tilemaps noch weitere Infos benötigt, dann fragt einfach nochmals nach.
TYPE TEvent Map%[4096] ENDTYPE
Diese Index-Liste enthält besondere Tilemap-Attribute auf welche wir erst zu einem späteren Zeitpunkt eingehen werden. Da sie aber auch in der Datei level00.dat integriert sind müssen wir sie schon jetzt definieren.
Nun müssen diese 3 Listen noch als globale Variablen definiert werden.
//============================================================================= // V A R I A B L E S //============================================================================= GLOBAL LayerFG AS TLayerFG GLOBAL LayerBG AS TLayerBG GLOBAL Event AS TEvent
Neu hinzugekommen ist noch die globale Variable AppTimer. Dies ist ein Zähler, der bei jedem Bildaufbau um 1 erhöht wird.
GLOBAL AppTimer% = 0
Dann gibt's noch die beiden globalen Variablen ScrollX und ScrollY die wir für das Scrolling benötigen.
GLOBAL ScrollX = 0 GLOBAL ScrollY = 0
Die globale Konstante COL_TRANSPARENT definiert unsere Transparent-Farbe. In unserem Programm wäre das RGB(248,0,248).
GLOBAL COL_TRANSPARENT = 0xF800F8... so, nochmals kurz durchatmen... und weiter...
Schauen wir uns mal die Datei level00.gbas an.
Zuerst erstellen wir einige lokale Hilfsvariablen.
LOCAL done% = FALSE LOCAL x%,y% LOCAL ix%,id%,p% LOCAL val%
Dann setzen wir die Scrollposition an den Anfangspunkt.
ScrollX=0 ScrollY=0
Mit den folgenden Zeilen laden wir die Leveldaten in unsere 3 Listen.
// load layers OPENFILE(1,"./isdo/level00.dat",TRUE) FOR p=0 TO 4095 READUWORD 1,VAL LayerFG.Map[p]=VAL NEXT FOR p=0 TO 2047 READUWORD 1,VAL LayerBG.Map[p]=VAL NEXT FOR p=0 TO 4095 READUWORD 1,VAL Event.Map[p]=VAL NEXT CLOSEFILE 1
Um die Leveldaten zu erstellen kann man sich entweder selbst einen Level-Editor basteln oder erstellt die Daten notfalls mit einem HEX-Editor.
Jetzt setzen wir die allgemeine Transparenzfarbe auf unseren vorgegebenen Wert.
SETTRANSPARENCY COL_TRANSPARENT
Mit
LOADBMP ""stellen wir sicher das der Hintergrundbuffer leer ist. Sonst kann sich die neue Grafik mit einer noch eventuell vorhandenen überlagern.
Nun laden wir unsere Tilegrafik und weisen jedem der 16x16 Pixel grossen Tiles eine eigene SpriteID zu. Dabei beginnen wir mit der Nummer 256 damit wir nach oben noch etwas Luft haben, falls wir später noch mehr Tiles benötigen werden.
LOADSPRITE "./isdo/gfx/level00.png",0 id=256 FOR y=0 TO 15 FOR x=0 TO 15 DRAWRECT 0,0,16,16,COL_TRANSPARENT DRAWSPRITE 0,-x*16,-y*16 GRABSPRITE id,0,0,16,16 INC id,1 NEXT NEXT
und löschen wieder das temporäre Sprite.
LOADSPRITE "",0
Ab jetzt folgt die Levelschleife. Das heisst, dass wir 60x pro Sekunde das Bild jedes Mal im Hintergrund aufbauen und anschließend auf dem Bildschirm anzeigen lassen.
//----------------------------------------------------------------------------- // M A I N L O O P //----------------------------------------------------------------------------- WHILE done=FALSE IF KEY(BUTTON_START) THEN RETURN AS_MENU INC AppTimer,1 INC ScrollX,0.5 GOSUB KeyHANDLER GOSUB LayerBGDRAW GOSUB LayerFGDRAW GOSUB StatusDRAW SHOWSCREEN WEND
Gehen wir das ganze Schritt für Schritt durch.
Zuerst programmieren wir uns einen Notausgang damit wir z.B. beim GP2X das Ger?t nicht immer ein- und ausschalten m?ssen. Also gelangen wir durch dr?cken des START-Buttons (GP2X) bzw. Eingabetaste (WIN) zur?ck zum Startmenu.
IF KEY(BUTTON_START) THEN RETURN AS_MENU
Bei jedem Bildaufbau erh?hen wir einen allgemeinen Z?hler jeweils um 1.
INC AppTimer,1
Danach legen wir fest um wieviele Pixel pro Bildaufbau sich der Vordergrund zur Seite bewegt. Ihr k?nnt ja Mal versuchen diesen Wert zu erh?hen oder zu senken.
INC ScrollX,0.5
Anschliessend lassen wir den KeyHANDLER in der library.gbas seine Arbeit verrichten. Dieser hat die Aufgebe alle Usereingaben zu verwalten.
//============================================================================= SUB KeyHANDLER: //============================================================================= // debug options IF KEY(2) THEN LIMITFPS 2 IF KEY(3) THEN LIMITFPS 30 IF KEY(4) THEN LIMITFPS 60 IF KEY(5) THEN LIMITFPS 80 ENDSUB // KeyHANDLER
Diese 4 Zeilen sind nur für Testzwecke gedacht. Durch die Tasten "1"-"4" kann die Bildwiederholfrequenz manuell geändert werden. Das hat den Nutzen, dass man zum Beispiel genauer sehen kann, ob etwa Kollisionen auch möglichst exakt ausgeführt werden. Mit
GOSUB LayerBGDRAW GOSUB LayerFGDRAW
rufen wir 2 Unterprogramme in der library.gbas auf, die unsere beiden Layer zeichnen.
Wir berechnen die Position in der LayerBG.Map von welchem wir das erste Tile oben links zeichnen.
// DRAW background layer p=INTEGER(ScrollX / 16 /2)*16
Dann berechnen wir die genaue Startposition in Pixeln, wo die erste Spalte gezeichnet werden soll.
dx=0-(bAND(ScrollX,31) /2)
Im Gegensatz zum Vodergrund müssen wir beim Hintergrund jeweils noch durch 2 teilen damit wir einen 2-Ebenen Effekt erzielen. Nun definieren wir wieviele Spalten gezeichnet werden müssen.
FOR x=0 TO 20
Da unsere Ausgabe eine Aufl?sung von 320x240 Pixeln hat ergibt sich dieser Wert durch: 320/16=20. Da aber je nach Scrollposition schon vor dem sichtbaren Ausschnitt gezeichnet wird, w?rde man auf der rechten Seite den Bidaufbau sehen, was nat?rlich unsch?n ist. Also zeichnen wir noch eine Spalte mehr.
dy=32
Das ist die genaue Startposition in Pixeln, wo die erste Zeile gezeichnet werden soll. (Statusanzeige 32 Pixel hoch) Wir zeichnen 13 Zeilen ((240-32)/16=13.
FOR y=0 TO 12
Hier müssen wir keine Zeile mehr dazu addieren, weil wir ja nicht nach oben oder unten scrollen. Nun zeichnen wir das errechnete Tile an den pixelgenauen Zielort.
DRAWSPRITE LayerBG.Map[p],dx,dy
Jetzt gehen wir Zeile für Zeile nach unten bis wir am unteren Rand der Bildausgabe angekommen sind.
INC dy,16 INC p,1 NEXT
Danach geht's zur nächsten Spalte.
INC dx,16 INC p,3 NEXT
Da unsere Layermap eine vertikale Dimension von 16 Zeilen hat, wir aber nur 13 Zeilen zeichnen, m?ssen wir noch 3 Listenpositionen ?berspringen.
Bleibt noch die Statusanzeige.
GOSUB StatusDRAWDa machen wir's uns im Moment noch einfach und zeichnen nur ein schwarz gef?lltes Rechteck und rufen das entsprechende Unterprogramm in userer Library auf.
DRAWRECT 0,0,320,32,RGB(0,0,0)
Hoffentlich ist das einigermassen verständlich erklärt.
Das nächste Mal kümmern wir uns um die Steuerung unseres Helden.

