GLB:Gegner und Objekte
Aus PandoraWiki
Im 5. Teil kommen wir nun zu dem wichtigsten Bestandteil dieses Tutorials, den Objekten. Wenn ihr diesen Teil verstanden habt, werdet ihr sehen, dass die Gameprogrammierung eigentlich gar keine allzu grosse Hexerei ist.
Im Beispielcode ( http://dl.openhandhelds.org/cgi-bin/pandora.cgi?0,0,0,0,46,30 ) befinden sich neu die Grafikdaten isdo/gfx/player.png für unsere Objekte und enemies.gbas. Dies können z.B. sein:
- Gegner
- Powerups
- Effekte
- gegnerische Schüsse
In isdo.gbas fügen wir einen neuen Typ hinzu:
TYPE TObject State%[32] Typ%[32] PosX[32] PosY[32] Timer%[32] Count% = 32 ENDTYPE
damit definieren wir einen Typ für 32 Objekte. D.h. wir werden maximal 32 Objekte gleichzeitig anzeigen können. State beschreibt den aktuellen Objektstatus, PosX und PosY die Position und Timer ist wieder ein Animationszähler. Count ist die Anzahl der maximalen Objekte. Weiter unten erstellen wir die dazugehörige Variable.
GLOBAL Object AS TObjectDann erweitern wir unsere SpriteID's noch um
GLOBAL SPR_ENEMY1% = 512 GLOBAL SPR_ENEMY2% = 514
Da wir bei einem Spiel viele verschiedene Objekte verwenden, ist es von Vorteil, jedem Objekt eine Konstante zuzuweisen.
// object ID's GLOBAL ID_ENEMY1% = 0x11 GLOBAL ID_ENEMY2% = 0x12
Wir definieren einmal 2 Gegner:
ENEMY1 gelber Gegner ENEMY2 roter Gegner
In level00.gbas laden wir unsere Objektgrafik und "grabben" die einzelnen Sprites heraus.
// make objects LOADSPRITE "./isdo/gfx/object.png",0 id=512 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
Dann erweitern wir unsere Levelschleife mit dem ObjectHANDLER
GOSUB ObjectHANDLERden wir wiederum in der library.gbas finden.
//============================================================================= SUB ObjectHANDLER: //============================================================================= LOCAL ix% FOR ix=0 TO Object.Count-1 IF Object.State[ix] SELECT Object.Typ[ix] CASE ID_ENEMY1 EnemyScripts(ix) CASE ID_ENEMY2 EnemyScripts(ix) ENDSELECT ENDIF NEXT ENDSUB // ObjectHANDLER
Dieser kurze Programmabschnitt ist tatsächlich ein Hauptbestandteil von unserem Programm! Wie bei den Schüssen durchlaufen wir eine Liste und prüfen als Erstes, ob der entsprechende Listeneintrag noch frei ist. Falls ja, schauen wir um was für einen Objekttyp es sich handelt. Je nach Objektyp verweisen wir dann auf ein Objektscript, wo dann das Objekt separat behandelt wird (Verhalten, Bewegung, Kollision etc.). Beim Aufruf der Funktion EnemyScripts übergeben wir mit ix den aktuellen Objektlistenindex und somit die Kontrolle über das entsprechende Objekt.
Zu diesem Zeitpunkt sind schone mehrere Objekteinträge vorhanden, da wir mit
IF ScrollX=128 THEN ObjectADD(ID_ENEMY1,320,120) IF ScrollX=160 THEN ObjectADD(ID_ENEMY2,320,120)
in level00.gbas bereits Objekte zu unserer Szene hinzugefügt haben. Mit diesem Befehl übergeben wir den Typ und die Position eines neuen Objekts an den ObjectHANDLER.
//============================================================================= FUNCTION ObjectADD: typ%,posX,posY //============================================================================= LOCAL ix% ix=0 Loop1: IF ix=Object.Count THEN RETURN IF Object.State[ix]=0 Object.State[ix]=1 Object.Typ[ix]=typ Object.PosX[ix]=posX Object.PosY[ix]=posY ELSE INC ix,1 GOTO Loop1 ENDIF RETURN ENDFUNCTION // ObjectADD
Schauen wir uns ein Script nun etwas genauer an. Die wichtigste Variable ist Object.State. Sie beschreibt die Phase in der sich das Objekt befindet. In unserem Beispiel sind das 3 Phasen. In jeder dieser Phasen verändern wir z.B. die Position. Wenn wir die letzte Phase durchlaufen haben, geben wir das Objekt wieder frei.
CASE 1 IF Object.PosX[ix] > 160 DEC Object.PosX[ix],2 ELSE Object.State[ix]=2 ENDIF CASE 2 IF Object.PosX[ix] > 64 DEC Object.PosX[ix],2 DEC Object.PosY[ix],1 ELSE Object.State[ix]=3 ENDIF CASE 3 IF Object.PosX[ix] > -16 DEC Object.PosX[ix],2 ELSE Object.State[ix]=0 ENDIF
Nun brauchen wir das Objekt nur noch zu zeichnen
DRAWSPRITE SPR_ENEMY1+frame,Object.PosX[ix],Object.PosY[ix]

