Google Translate

Hungarian English French German Italian Portuguese Russian Spanish

Játékírás - Space War

Bevezető

Ebben a Tutorial-ban egy kezdőknek szánt egyszerű Visual Basic 6 játék elkészítését fogom bemutatni lépésről-lépésre. Ha nincs kedved végigcsinálni a lépéseket, és inkább csak böngésznéd vagy kipróbálnád a megoldást, a játék EXE forráskóddal együtt letölthető a cikk végén.

A játékban a képernyő alján egy űrhajót mozgat a játékos a nyilakkal, és a SPACE-el lő. A képernyő felső részén pedig űrlények vannak amiket el kell találni. Háromféle űrlény van, és mindegyikért más-más mennyiségű pontot kap a játékos ha eltalálja. Az űrlények egyre jobban közelednek az űrhajó felé, és ha ütköznek vele vége a játéknak. Ennyire egyszerű lenne a koncepció. A cikk végén olvashatsz néhány továbbfejlesztési lehetőséget, ha van kedved próbáld megvalósítani őket.

Az EXE futtatásához szükség van a VB6 futásidejű DLL-re (más dependencia nincs). A Windows 7-ig mellékelve van a szükséges DLL, tehát elvileg futnia kell, de ha gondod van írj bátran nekem

Important notice for english readers: "Hit()" is meant to be a method name, but google translates it because "hit" is a word for "belief" and "faith" in the hungarian language... Of course, there are many other mistranslations as well. Consider this while reading the tutorial. Thanks.

Tartalom

Új projekt tartalom

Indítsd el a VB6 IDE-t, és hozz létre egy új "Standard Exe" típusú projektet. Ekkor megnyílik a szerkesztő, és el is kezdhetjük a munkát. A projektet elmentheted most, vagy bármikor később a fejlesztés során.

A Form beállításai tartalom

Mivel a vezérlők jelentős részét futásidőben fogjuk elkészíteni, ezért nincs sok teendő a Form-on. Írd át a Form tulajdonságok panelen a következőket:

  • name = Main
  • BackColor = &H00000000& (fekete)
  • BorderStyle = 1 - Fixed Single
  • Caption = Space War
  • StartUpPosition = 2 - CenterScreen
  • Height = 4845
  • Width = 4800

Vezérlők tartalom

Helyezz el egy Shape vezérlőt az űrlap alsó részére, az alábbi képen látható módon. A Shape tulajdonságait is módosítsd:

  • BackColor = &H00800000& (kék)
  • BackStyle = 1 - Opaque
  • BorderStyle = 0 - Transparent
  • Width = 4695
  • Height = 375

Most jön a pontszám felirat, amihez egy Label verzérlőt fogunk használni. Tulajdonságok:

  • Name = score
  • Alignment = 1 - Right Justify
  • Appearance = 0 - Flat
  • BackStyle = 0 - Transparent
  • Font = Courier New, Bold, 16 (egy dialóg ablakon lehet beállítani)
  • ForeColor = &H0000FFFF& (sárga)
  • Caption = 0

Végül egy időzítőt (Timer) is helyezz el az űrlapon, tetszés szerinti helyre. Ez a vezérlő mindvégig láthatatlan lesz, és mint neve is sugallja események időzítéséhez fogjuk használni. Tulajdonságok:

  • Name = timer
  • Interval = 1

Osztályok megírása tartalom

Az objektum orientált programozásról egy későbbi cikkben fogok bővebben írni. Jelenleg elég annyit megértened (és elfogadnod), hogy az osztályok lényegében kód sablonok, és csak az osztályon belül definiált változókkal és függvényekkel (metódusokkal) tudnak műveleteket végezni. Az osztályokból tetszés szerinti példány (objektum) készíthető. Ezeket a példányokat objektum típusú változókban lehet tárolni. A példa során látni fogod ez miért jobb mint a hagyományos procedurális paradigma (ahol van egy rakás változód, egy rakás függvényed, és neked mint programozó kell összehangolni mindent).

Tehát, gondoljuk végig milyen "dolgok", egységekből épül fel a játék: a játékos egy űrhajót irányít, és vannak ellenségek. Valósítsuk meg őket osztály formában.

A VB6 IDE egy barátságos Osztály Varázslót is ad, így elég fele annyit kódolnod majd, a sablonos részeket le fogja neked generálni.

A jobb felső sarokban lévő projekt panelen kattints jobb gombbal a Main űrlapra, válaszd az "Add", majd a "Class Module" menüpontot.

A megnyiló dialógon pedig a második "VB Class Builder" nevű ikonra kattints.

Ellenségek (Alien) tartalom

Kattints jobb gombbal a bal oldali panelen a projekt nevére, majd "New", azon belül "Class..." menüpont.

Elég az osztály nevét megadni a megnyiló ablakon: "Alien", majd OK gomb.

Az osztály változókat a VB-ben Property-nek hívják. Hasonló módon mint amikor az osztályt hoztad létre kattints jobb gombbal az Alien-re majd a menüben válaszd a "New", majd "Property..." elemet. A megnyiló ablakon viheted be a változó tulajdonságait. Vidd fel a következő változókat:

Most kattints a második "Methods" fülre, hogy a metódusok listája jöjjön elő. A metódusok hasonlóan egyszerűen felvihetők. Csak kattints jobb gombbal az üres listán és "New Method..." menüpont. A dialóg ablakon a metódus neve alatt van egy lista a bementi paraméterek felviteléhez. A plusz gomb megnyomására bejön egy újabb ablak ahol megadhatod az új paraméter nevét és típusát. Ilyen módon, készítsd el az alábbi metódusokat:

Ha megvagy mindezzel, a fő menüben válaszd a Fájl -> Update Project menüpontot. Ekkor az IDE létrehozza a szükséges kódot, és felbukkan egy kódszerkesztő ablak az Alien osztályhoz. Bezárhatod a varázslót. Ideje kidolgozni a metódusokat.

A create metódust közvetlenül a Main ablak betöltésekor fogjuk végrehajtani, és a feladata az lesz hogy az ellenséget alaphelyzetbe hozza, valamint hozzáadjon egy kép vezérlőt az ablakhoz. Mivel sok ellenséget fogunk csinálni, és mindegyik egy külön kép vezérlő lesz az ablakon, és a vezérlőknek egyedi név kell, ezért a bemeneti index paramétert fogjuk a név generálásához használni. Természetesen létrehozáskor az ellenség él (alive), beállítjuk a pozícióját, és kinézetét. A kinézete egy bmp képfájlból fog jönni, a creed paraméter alapján ami lehet 1,2,3. A számot hozzáfűzzük a fájlnév végéhez.

Alien osztály - create metódus
Public Sub create(index As Integer)
  alive = True
  Set sprite = Main.Controls.Add("VB.Image", "alien" & index)
  sprite.Left = x
  sprite.Top = y
  sprite.Picture = LoadPicture(App.Path & "/alien" & creed & ".bmp")
  sprite.Visible = True
End Sub

A képek a projekt mappában:

A die() metódus akkor fog meghívódni, ha lézerrel eltaláljuk az ellenséget. Beállítjuk hogy a szörny kipurcant, ne látszódjon többé, és a creed alapján kap bizonyos mennyiségű pontot a játékos.

Alien osztály - die metódus
Public Sub die()
  alive = False
  sprite.Visible = False
  Main.score = CStr(CInt(Main.score) + creed ^ 2)
End Sub

Nos, a fly metódust hivatott, hogy az ellenségek mozogjanak is, különben irtó könnyű eltalálni őket ugyebár.. Sajnos erre nem igazán szántam időt, ezért kicsit kaotikus mozgást eredményez. Próbáld meg saját ötleted alapján átírni!

Alien osztály - fly metódus
Public Sub fly(dir As Integer)
  y = y + 2
  If (dir Mod 6) > 0 Then x = x + 1 Else x = x - 1
  sprite.Top = y
  sprite.Left = x
End Sub

Játékos (Player) tartalom

A játékos egy űrhajót fog irányítani, ami tud majd jobbra és balra mozogni, valamint lézersugarat lőni. Az ellenség osztály fejezetben megtanult módon készítsd el az osztály sablonját. Lásd az alábbi képeket.

Most is először a legfontosabb készítő, tehát create metódust fogjuk kifejteni. A sprite változó ismét egy kép vezérlő lesz, de ezúttal a spaceship.bmp-t fogjuk minden esetben betölteni. Megadjuk a kezdőpozíciót (képernyő alján a kék sáv fölött középen), és hogy látható az űrhajó.

A másik dolog ami részben kapcsolódik az űrhajóhoz a lézer amit kilő. A lézert egyébként ideálisabb egy külön osztályként megvalósítani, mert úgy flexibilisebben lehetne használni. Jelenleg mindig csak egy lézer lehet a képernyőn, és amíg célba nem talál, vagy el nem éri a képernyő tetejét a játékos nem tud újra lőni.

Tehát a jól bevált módon hozzáadunk egy kép vezérlőt az ablakhoz, de most eltüntetjük, hisz csak akkor kell látszódnia amikor épp lő a játékos.

Player osztály - create metódus
Public Sub create()
  Set sprite = Main.Controls.Add("VB.Image", "player")
  sprite.Left = 2040
  sprite.Top = 3580
  sprite.Picture = LoadPicture(App.Path & "/spaceship.bmp")
  sprite.Visible = True
 
  Set laser = Main.Controls.Add("VB.Image", "laser")
  laser.Picture = LoadPicture(App.Path & "/laser.bmp")
  laser.Visible = False
  laser.Top = 100
End Sub

Az űrhajót mozgásra bírni igazán könnyű lesz. Elég a sprite változó (tehát az ablakon lévő kép vezérlő) pozícióját megváltoztatni. Nyílván, hogy ne lehessen kimenni a képernyőn kívülre, egy ellenőrzést is végzünk az aktuális pozíción.

Figyeld meg, hogy ezek a metódusok mennyire nincsenek tudatában annak hogy hol fogják meghívni őket a forráskódban. Csak egy dologhoz értenek. A billentyű lenyomásokat nem ez a metódusok érzékeli!

Player osztály - mozgató metódusok
Public Sub moveLeft()
  If sprite.Left > 0 Then sprite.Left = sprite.Left - 50
End Sub
 
Public Sub moveRight()
  If sprite.Left < 4320 Then sprite.Left = sprite.Left + 50
End Sub

A lövés még hátravan. Egyáltalán nem állítom, hogy ez a legtökéletesebb megvalósítási mód, ráadásul a lézernyaláb eleve nem ebbe az osztályba való dolog. Normál esetben az űrhajónak csak létre kéne hoznia egy lézert, és elindítani.

Az én megoldásomhoz három metódus kell. A fire() fogjuk meghívni kívülről amikor a játékos lenyomja a space billentyűt. Itt leellenőrizzük hogy a lézer látszik -e, és ha nem akkor elindíthatjuk a lövést. A lézert láthatóvá tesszük és pontosan az űrhajó fölé helyezzük.

Player osztály - fire metódus
Public Sub fire()
  If laser.Visible = False Then
    laser.Visible = True
    laser.Top = sprite.Top - 395
    laser.Left = sprite.Left + 205
  End If
End Sub

A shoot metódust is kívülről fogjuk meghívni, minden egyes alkalommal amikor a timer (időzítő, emlékszel?) meghívja a saját esemény metódusát. Az időzítő intervallumát 1ms-ra állítottuk, tehát a shoot nagyon gyakran, lényegében folyamatosan le fog futni és teszi a dolgát. Ha a lézer látszik, de még nem talált el semmit, akkor a lézert kicsit feljebb helyezi a képernyőn. Ha célt talált a lézer akkor láthatatlanná teszi (a fire metódus csak akkor enged tüzelni ha a lézer láthatatlan).

A hit metódust hamarosan megírjuk. Ha igazat ad vissza a lézer már célt talált.

Player osztály - shoot metódus
Public Sub shoot()
  If hit() = False Then
    laser.Top = laser.Top - 200
  Else
    laser.Visible = False
  End If
End Sub

Ha a lézer elérte a képernyő tetejét, vagy eltalált egy ellenséget, a hit() igazat fog visszaadni. Az ellenségekkel való ütközésvizsgálatot a Main űrlap kódjában fogjuk megvalósítani, hisz a Player osztálynak csak saját magát kell kezelnie.

Player osztály - hit metódus
Public Sub hit()
  If laser.Top <= 70 Or Main.alien_hit(laser.Left, laser.Top) > -1 Then
    hit = True
  Else
    hit = False
  End If
End Sub

Játék logika tartalom

Kattints duplán az űrlap tervezőn az ablakra, és ekkor előjön az ahhoz tartozó kód szerkesztő.

A forrás legtetején betöltünk egy windows rendszer függvényt, amely lehetővé teszi hogy egyszerre több lenyomva lévő billentyűt észlelni tudjunk. Továbbá megadjuk, hogy a Main-ben használni akarunk majd egy Player példányt, és egy tömböt amiben Alien példányok lesznek.

Main - Deklarációk
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
 
Private ship As Player
Private aliens(23) As Object

Minden űrlap, így a Main is valójában egy speciális osztály. Vannak olyan metódusok amiket felül lehet írni. A Form_Load() akkor fut le - egyszer - amikor az űrlap először betöltődik. Itt fogjuk létrehozni az űrhajót és az ellenségeket. Az ellenségeket egy elég bénácska ciklus fogja létre hozni. Bátran kísérletezz ki valami jobbat!

Main - Betöltés
Private Sub Form_Load()
  Set ship = New Player
  ship.create
 
  i = 0
  xshift = 0
  For y = 1 To 4
    If CBool(y Mod 2) = True Then
        xshift = 0
    Else
        xshift = 520
    End If
    If y = 1 Then c = 3
    If y = 2 Then c = 2
    If y > 2 Then c = 1
    For x = 1 To 6
      Set aliens(i) = New Alien
      aliens(i).creed = c
      aliens(i).x = -480 + x * 520 + xshift
      aliens(i).y = -480 + y * 480
      aliens(i).create (i)
      i = i + 1
    Next x
  Next y
End Sub

A timer vezérlőnek is van egy speciális metódusa amit felül fogunk írni. Meghívjuk a shoot-ot, utasítjuk az ellenségeket hogy mozogjanak, és észleljük a billentyű lenyomásokat. Annak ellenére, hogy ez adja lényegében a játék fő logikáját, elég karcsú kódrészlet (hiszen csak utasításokat adunk, nem itt végezzük el a feladatokat, a példányok megoldják maguk).

Main - Fő játék logika
Private Sub timer_Timer()
  ship.shoot
  For i = 0 To 23
    aliens(i).fly (i)
  Next i
 
  If GetAsyncKeyState(vbKeyLeft) Then ship.moveLeft
  If GetAsyncKeyState(vbKeyRight) Then ship.moveRight
  If GetAsyncKeyState(vbKeySpace) Then ship.fire
End Sub

Emlékszel, hogy az űrhajónak szüksége van a hit() metódusra, hisz anélkül nem tudja hogy a lézer eltalált -e ellenséget vagy sem. Itt lényegében ellenőrizzük hogy a lézer átfedésben van -e valamelyik ellenséggel és ha igen True-val visszatér a függvény, valamint az ellenséget utasítjuk hogy ideje nyugovóra térni.

Main - Lézer ütközés vizsgálat
Public Function alien_hit(x, y) As Integer
  For i = 0 To 23
    If aliens(i).alive = True Then
      If y < aliens(i).y + 480 And x > aliens(i).x And x < aliens(i).x + 480 Then
        alien_hit = i
        aliens(i).die
      End If
    End If
  Next i
  alien_hit = -1
End Function

Nos, ennyiből áll megírni egy egyszerű játékot VB6-ban. Ha eljutottál idáig, és nem vesztetted el a fonalat - és nem adtad fel - gratulálok! A klasszikus Basic-ről áttérni az objektum orientált világba első nekifutásra nem könnyű, de mint látod, a kód sokkal kezelhetőbbé válik.

Egy másik cikkben bemutatom majd, hogy miként lehet új osztályokat öröklődés útján létrehozni. Ez akkor jön jól, ha pl. új ellenség típusokat akarsz csinálni. Végtére is az aliens() csak egy tömb, amibe bármilyen objektumot bele lehet pakolni.

Jó kódolást!


Letöltés: Space War (16,1 KB)

Zene

Google keresés

Váltó

Digitális Táregység


Számrendszer

#=

IMDb Keresés

Kód

Karakter

Szín

Szín kódtábla

Webmaster: GoobeMaster
Érvényes XHTML és CSS
Minden jog fenntartva! ® 2010 - 2017
Jogtulajdonos: United Voxels Ltd. (United Kingdom)

Check Google Page Rank

Technikai háttér: