BlitzBasic-Community-Tutorial/ Wir programmieren einen 3D SpaceShooter
Einen Space-Shooter zu coden, ist an sich nicht so schwer. Die eigenen Vorstellungen sind oft das größere Hindernis. Wie bei allen Spielen werden auch hier Dinge benötigt, die aus verschiedenen Disziplinen stammen. Code, Musik, Grafik, Modelle, Geschichte. Da selten eine Person alle Disziplinen beherrscht, sind die zu erwartenden Ergebnisse von vornherein erheblich tiefer anzusetzen. Ausnahmen sind natürlich Teams. Aber davon gibt es nicht viele, die es über einen längeren Zeitraum zusammen schaffen. Ich gehe hier davon aus, dass der Leser schon ein wenig Erfahrung mit Blitz3D hat und alleine arbeitet. Es ist außerdem nützlich, über ein aktuelles Original zu verfügen.
Eine der wichtigsten Dinge, die man beim Coden berücksichtigen muss, ist die Disziplin. Bestimmte Dinge muss man sich einfach von vorne herein angewöhnen.
- Erstellung einer Variablenliste mit Kommentaren zur Funktion einer jeden Variable.
- Erstellung einer Liste, die Erklärungen zu Funktionen enthält.
- Ein Konzept für das Spiel (obwohl ein solches vor allem von Hobbyentwicklern selten erstellt wird).
Was soll es denn werden?
BearbeitenDiese Frage muss man sich in jedem Fall stellen. Ansonsten wird es aus dem Projekt ganz schnell ein unendlich andauerndes Unterfangen.
Wir brauchen:
- einen Ort in Form eines Sonnensystems
- eine Station, in der man Parken kann
- Gegner, die einen angreifen (z.B. Piraten)
- Waffen und Raketen
- Tolle Schiffe
- variablen Schwierigkeitsgrad
- eine Kollisionserkennung
- fetzigen Sound und GFX
- ein Startintro
- eine Cockpit-Ansicht
- Radar und sonstige Kontrollen
Sieht ganz nach einem ELITE-Klon aus... Aber eigentlich sind fast alle 3D-Weltraum-Spiele daran angelehnt.
Na dann mal los...
Programme, die wir brauchen
BearbeitenDa ich davon ausgehe, dass der Leser alleine codet, sind hier vor allem Programme gefragt die man schnell und leicht bekommen und benutzen kann.
PaintShopPro 4 zum Zeichnen von Texturen und Sprites DOGA L2 zum Erzeugen von 3D Objekten nach dem Lego Prinzip Blitz3D um alles als Code zusammenzubinden Edit zum erstellen von Notizen , !!! ganz wichtig !!!
Die Grundstruktur
BearbeitenGrundsätzlich sind diese bei allen Spielen gleich.
- Initialisierung
- Bildschirm öffnen
- 3D Umgebung einrichten
- Hauptschleife
- Funktionen
- Datas
Eine mögliche Grundstruktur könnte so aussehen:
;(1)----------------------------------------------------------------- sx=600 ; Screen x sy=400 ; Screen y ;(2)----------------------------------------------------------------- Graphics3D sx,sy,32,2 ; Bildschirm im Fenstermodus öffnen SetBuffer BackBuffer() ; Das Doublebuffering aktivieren ;(3)----------------------------------------------------------------- camp=CreatePivot() ; Ein Drehpunkt für die Kamera cam=CreateCamera(camp) ; Eine Kamera einrichten MoveEntity cam,0,0,-5 ; Die Kamera vom Nullpunkt wegbewegen light=CreateLight(1) ; Eine Lichtquelle erzeugen obj=CreateCube() ; Ein Objekt erzeugen ;(4)----------------------------------------------------------------- Repeat ; die Hauptschleife If KeyHit(1) Then en=1 ; auf ESC-Taste reagieren = Exit TurnEntity camp,.5,0,0 ; Den Drehpunkt der Kamera drehen RenderWorld() ; Szene zeichen Flip ; Bildschirm wechseln mit WaitSysnc Until en=1 ; Exit wenn Taste ESC gedrückt wurde End ; Programm Ende ;(5)---------------------------------------------------------------- ;(6)----------------------------------------------------------------
Der Spieler
Bearbeiten- Hier fehlen noch Inhalte! Bitte ergänzen!
Gegner kommen ins Spiel
BearbeitenGegner definieren
BearbeitenFür Gegner sollte man am besten Types verwenden da man bei einem Type sehr einfach viele Gegner erstellen kann.
TYPE enemy FIELD xpos FIELD ypos FIELD health FIELD name END TYPE
Mit diesem Code wird ein neuer Type erstellt mit dem Namen Enemy und den ganzen Daten die ein Gegner haben sollte.
Natürlich könnte man auch einen Array anlegen und darin die Daten lagern aber so etwas geht vielleicht bei einem Pac-Man Spiel wo es immer 4 Gegner gibt. Bei unserem Shooter jedoch sollen es viele sein und mit Array ist das schwer zu machen deswegen werde ich auch nicht weiter auf diesen Lösungsweg weiter eingehen.
Gegner anzeigen und dann wieder löschen
BearbeitenNatürlich muss der Gegner sich bewegen, und dazu immer als erst gezeichnet, dann wieder gelöscht und dann wieder gezeichnet usw. werden.
Dazu sollte man sich eine extra Funktion Schreiben in der alle Gegner angezeigt werden. Das Löschen macht man am Besten in einer For: Next Schleife in der auch Sachen wie die Kollision überprüft werden.
Eine recht simple Funktion zum Anzeigen aller Gegner sieht wie folgt aus:
FUNCTION enemy_draw FOR enemy.enemy = EACH enemy DRAWIMAGE gegnergrafik,enemy\xpos,enemy\ypos NEXT END FUNCTION
Schüsse
BearbeitenSo... Wer noch keine Ahnung von Types hat, sollte sich erst einmal ein kleines Tutorial dazu anschauen, oder sich einfach hieran versuchen (Grundwissen wird hier vorausgesetzt). Schüsse sollten immer mit Types (oder zur Not auch Dims) realisiert werden und ungefähr so aussehen:
Type Schuss ; unser Type heißt "Schuss", so kann man auf ihn zugreifen Field Photon ; Spaceshooter-Schiffe schießen immer mit Photonen ;-) Field objektdauer ; wie lange unsere Schüsse im Spiel sein sollen End Type ; "beendet" den Type
... Bravo! Unser Type ist im Spiel. Er bringt nur noch nicht viel! Wie wäre es denn, wenn man durch Drücken der linken Maustaste den Schuss abfeuern könnte? Dafür setzen wir Folgendes in die Hauptschleife:
If MouseHit(1) Then FeuerSchuss()
... FeuerSchuss() ist eine Funktion (siehe dazu andere Tutorials), die wir jetzt benennen müssen (natürlich außerhalb der Schleife ;-) ):
Function FeuerSchuss() ;benennt unsere Funktion s.Schuss = New Schuss ;ein neuer Type wird mit allem drum und dran erstellt s\photon = CreateSphere() ;s\ zeigt, im welchem Type wir uns befinden EntityParent Photon,0 ;kein Parameter PositionEntity s\photon,EntityX(Spieler),EntityY(Spieler),EntityZ(Spieler)+3 ;sollte klar sein s\objektdauer = 100 End Function
Super! Unser Photon existiert nun! Nun soll es etwas machen. Funktionen helfen uns dabei:
In der Schleife:
For s.Schuss = Each Schuss ; für jeden Schuss mach das und das... UpdateSchuss(s) Next
Außerhalb der Schleife:
Function UpdateSchuss(s.Schuss) MoveEntity p\obj,0,0,100 RotateSprite p\obj,Rnd(310) If CountCollisions(p\obj) Then If EntityCollided(p\obj, TYPE_TERRAIN) Then EmitSound Explo, p\obj einschlagX# = EntityX(p\obj) einschlagY# = EntityY(p\obj) einschlagZ# = EntityZ(p\obj) TFormPoint(einschlagX#, EinschlagY#, EinschlagZ#,0,terrain) hoehe = TerrainHeight( terrain, TFormedY(),TFormedZ() ) If hoehe>0 hoehe=hoehe-2:If hoehe<0 Then hi=0 ModifyTerrain terrain,TFormedY(),TFormedZ(),hoehe,True EndIf Explosion ( p ) FreeEntity p\obj Delete p Return End If End If End Function