GLB:Gegner und Objekte

Aus PandoraWiki

Wechseln zu: Navigation, Suche

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  TObject

Dann 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 ObjectHANDLER

den 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]

Als nächstes beschäftigen wir uns mit der Kollisionsabfrage