3D-Space-Game-015.bb


;------------------------------------------------------- ; ; 3D Space Game Tutorial ; ; (C) by Turgut Frank Temucin alias TFT ; ; Alle Rechte verbleiben beim Autor. Die Veröffentlich- ; ung außerhalb des BlitzForums ist nur mit Genehmigung ; gestattet. Der Source-Code ist Freeware, und darf für den ; privaten Gebrauch frei verwendet werden. ; ;------------------------------------------------------- ; File: 3D-Space-Game-015 ; Date: 31.07.03 ;------------------------------------------------------- ; BB3D: 1.83 ;------------------------------------------------------- ; Mein Dank an: Markus und Hot-Bit ;------------------------------------------------------- ; ; Nachdem wir jetzt wissen, wie wir ein Portal einbinden ; können, folgt als nächstes die Selektion der Portal-Art ; und die Reaktion darauf. Wir werden erst mal einen ; Hangar coden. Dazu wird die Data-Sektion wieder ein mal ; erweitert. Und die Funktionen "portal" sowie "hangar" ; eingeführt. Da die Änderungen im Code immer massiver ; werden, schaut ihn euch genau an. Die Portal-Sphere ; wird gegen ein Pivot ersetzt. Jetzt kann man in den Hangar ; einfliegen und die Kollisions-Funktionen werden in ; den Hangar-Mode übergehen. Auf diese Weise lassen sich ; etliche verschiedene Reaktionen auf das Betreten eines ; Portales erzeugen. ; ------------------------------------------------------ ; ; Als erstes werden ein paar Konstanten definiert. Diese ; sind unveränderbar und immer Global. Const screen_x=640 Const screen_y=480 Const screen_m=2 ; Bildschirm Modus ; 2=Fenster 1=Fullscreen Const screen_t=16; 16 Bit oder 32 Bit Bildschirm Global hispeed ; Schalter-Variable. Zum Ein- und Aus-schalten ; der Schnellen Geschwindigkeit. Global location ; enthält -1 oder die Nummer der Lokation in der ;sich das Schiff gerade befindet. Innerhalb ;der LoKation funktioniert kein High-Speed. ;******* ; Global ot ; Objekt-Type bei Gefahr oder -1 Global inHangar ; Schalter-Variable, ob sich das Schiff in einem ; Hangar befindet. Global SchiffAlpha=1 ; ist das Schiff sichtbar oder nicht ; ;******* Global gefahr ; Global tod ; Global t2,t3,c1 ; Timing-Anzeige für Monitor-Funktion ; Dann wird der Bildschirm geöffnet ; Graphics3D screen_x,screen_y,screen_t,screen_m ; Den Bildschirm öffnen SetBuffer BackBuffer() ; das Double-Buffering aktivieren ; Ein Objekt, welches mit DOGA L1 erstellt wurde, wird geladen Global schiff=LoadMesh("schiff.x") ; Schiff-Objekt laden PositionEntity schiff,0,0,0 ; Position beliebig EntityType schiff,1 ; Kollisions-Type EntityRadius schiff,1 ; Kollisions-Radius ; Danach die Kamera- und Licht- Einstellungen ; Global cammerap=CreatePivot(schiff) ; Drehpunkt für Außenansicht Global Cammera=CreateCamera(cammerap) ; Ohne Kamera sieht man nichts ; und es wird an das Schiff angebunden CameraRange cammera,1,600000 ; Sichtweite der Kamera anpassen MoveEntity cammera,0,.5,-4 ; Da die Kamera mitten im Schiff liegt, ; wird sie etwas nach hinten verschoben. CameraZoom cammera,2 ; Fischaugen korrigieren Global plp=CreatePivot() ; Einen Sammel-Punkt für das Verschieben des ganzen ; Systems anlegen Global licht=CreateLight(2,plp) ; Für das richtige Ambiente muß eine ordentliche ; Lichtquelle her. PositionEntity licht,80000,0,0 ; Licht positionieren LightRange licht,100000 ; Reichweite des Lichtes AmbientLight 100,100,100 ; Umgebungslicht verstärkt oder schwächt den Kontrast ; Die Sky-Box wird erstellt ; Global skay=CreateSphere(12) ; Eine Kugel erstellen Global skay_tex=LoadTexture("all.jpg") ; Die All-Textur laden EntityTexture skay,skay_tex ; und dem Objekt zuweisen ScaleEntity skay,500000,500000,500000 ; Den Weltraum vergrößern FlipMesh skay ; Von innen sichtbar EntityOrder skay,1 ; Immer als erstes darstellen EntityFX skay,1 ; Kein Licht-Effekt für die Sky-Box ; Das Sonnen-System erzeugen ; Restore planeten_system_daten Dim pl(10) ; enthält die Handler der Planeten-Objekte Dim plt(10) ; Zeiger auf Planeten-Textur Dim plr#(10) ; Eigen-Rotation Dim plsc(10) ; Speicher für Planeten/Lokation Durchmesser ; Für das Abschalten des High-Speed Dim plg(10) ; Gefahren-Grenze Dim pld(10) ; Kollisions-Grenze (Game-Over) für Planeten etc... Dim pln(10) ; Sortier-Nummer der Planeten/Objekte damit ; eine Identifikation im Ereignisfall möglich ist ;****** ; Dim plb(10) ; Objekt-Bindung ; ;****** Global anz_pl ; Anzahl der Planeten im System i=0 ; Das erste Objekt ist die Sonne Read anz_pl ; Anzahl Planeten ohne Sonne For i1=0To anz_pl Read t$,sc,x,y,z,r#,sch,scg,scd,ty,i,b,nn$ ; Objekt-Daten holen If ty=0 ; Erzeuge Sonne plt(i)=LoadTexture(t$,2) ; Sonnen-Textur laden pl(i)=CreateCube(plp) ; Objekt erzeugen EntityTexture(pl(i),plt(i)) ; Textur aufbringen EntityAlpha(pl(i),.9) ; Sonne etwas transparent machen PositionEntity(pl(i),x,y,z) ; Im Raum positionieren ScaleEntity(pl(i),sc,sc,1) ; Vergrößern EntityFX pl(i),1 ; Kein Licht-Effekt für die Sonne EntityRadius pl(i),sc Else If ty=1 ; erzeuge Planeten pl(i)=CreateSphere(16,plp) ; Eine Kugel erstellen plt(i)=LoadTexture(t$) ; Die Welt-Textur laden EntityTexture pl(i),plt(i) ; und dem Objekt zuweisen ScaleEntity pl(i),sc,sc,sc ; Den Planet vergrößern PositionEntity pl(i),x,y,z ; Und vor die Kamera stellen EntityRadius pl(i),sc ; Else If ty=2 ; erzeuge Stationen pl(i)=LoadMesh("station.x",plp) ; Station-Objekt laden PositionEntity pl(i),x,y,z,1 ; Position beliebig EntityType pl(i),2 Else If ty=3 pl(i)=CreatePivot(pl(b)) ;CreateSphere(5,pl(b)) ScaleEntity pl(i),sc,sc,sc ;******* ; ; Da das Objekt mit absoluten 3D-Cords positioniert wird, ; muß dies beim nachfolgenden Befehl auch angegeben werden. ; Beim Anbinden eines Objektes muß dieser Umstand immer ; mitbedacht werden. PositionEntity pl(i),x,y,z,1 ; ;******* EntityType pl(i),3 EntityRadius pl(i),sc EndIf plsc(i)=sc+sch ; Lokation-Durchmesser plg(i)=sc+scg ; Gefahren-Grenze pld(i)=sc+scd ; Todes-Grenze plr(i)=r ; Planeten-Rotation pln(i)=i ; Objekt-Nummer ;******* ; plb(i)=b ; Objekt-Bindung NameEntity(pl(i),nn$) ; Info-String zuordnen ; ;******* Next ; Nun kommt der Main Loop ; Repeat t1=MilliSecs() ; Zeit-Nahme vor allen Berechnungen auto_rotation() ; Objekte,welche sich um die eigene Achse drehen, aktualisieren bewege_schiff() ; Funktions-Aufruf für die Schiffs-Bewegung kolision1() ; Kollisions-Kontrolle vor Berechnung UpdateWorld RenderWorld ; Bild berechnen und zeichnen kolision2() ; Kollisions-Kontrolle nach Berechnung hangar() ; Wenn sich das Schiff in einem Hangar befindet monitor() ; Zur Kontrolle bestimmter Werte t3=MilliSecs()-t1 ; Zeit in Millisekunden t2=t2+t3 ; Für Zwischensumme aufrechnen t4=MilliSecs()+25-t3 ; Warte-Schleife berechnen Repeat Until MilliSecs()=>t4 ; Warten bis Zeit in ms abgelaufen Flip 1 ; Seite wechseln Until KeyHit(1) ; Abrechen, wenn ESC gedrückt ; Und zum Schluß das Ende ; End ; Alles beenden Function bewege_schiff() Local MSF#,x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#,x4#,y4#,z4#,i ;***** ; ; Die Steuerung sollte nur außerhalb des Hangars möglich sein If inHangar=0 ; Steuerung nur außerhalb des Hangars ; ;***** If KeyHit(60) ; Taste F2 hispeed=Not hispeed ; Ein- und Aus-schalten des Hochgeschwindigkeits- ; Modus. EndIf ; Ereignis-Auswertung für Lokation-Entfernung ; location=-1 gefahr=-1 tod=-1 For i=0To anz_pl x1=EntityDistance(schiff,pl(i)) If x1< plsc(i) ; Abschalt-Entfernung erreicht hispeed=0 location=i If x1< plg(i) ; Gefahren-Grenze erreicht gefahr=pln(i) ; Objekt-Nummer für Ereignis-Steuerung If x1< pld(i) ; Game-Over-Grenze erreicht tod=i EndIf EndIf EndIf Next ; Geschwindigkeits-Kontrolle und Steuerung ; x1=EntityX(schiff) ; hole alte Schiffs-Position in Bewegungs-Ebene 1 y1=EntityY(schiff) z1=EntityZ(schiff) If KeyDown(29)=0 ; Taste Strg If hispeed=1 MSF#=100 ; Maximale High-Speed- Geschwindigkeit x1=EntityX(schiff) ; hole alte Schiffs-Position in Bewegungs-Ebene 1 y1=EntityY(schiff) z1=EntityZ(schiff) ; Die Bewegungs-Richtung für High-Speed ist nur vorwärts ; MoveEntity schiff,0,0,MSF x2=EntityX(schiff)-x1 ; Differenz neu-alte Schiffs-Position y2=EntityY(schiff)-y1 z2=EntityZ(schiff)-z1 x3=EntityX(plp) ; Aktuelle Position des System-Sammel-Punktes ; merken y3=EntityY(plp) z3=EntityZ(plp) x4=x3-x2 ; Bewegungs-Differenz des Schiffes vom ; Sammel-Punkt abziehen y4=y3-y2 z4=z3-z2 PositionEntity plp,x4,y4,z4 ; Das ganze System auf neue Position bringen ; Die Schiffs-Position langsam wieder auf 0,0,0 rücksetzen ; i=1 ; Rücksetz-Geschwindigkeit If x1>i x1=x1-i Else If x1<-i x1=x1+i Else If x1-i x1=0 EndIf If y1>i y1=y1-i Else If y1<-i y1=y1+i Else If y1-i y1=0 EndIf If z1>i z1=z1-i Else If z1<-i z1=z1+i Else If z1-i z1=0 EndIf PositionEntity schiff,x1,y1,z1 ; Alte Schiffs-Position übernehmen inklusive ; Verschiebung nach 0,0,0 Else MSF#=1 ; Maximale Schiffs-Bewegung in der ersten Ebene If KeyDown(200) ; Taste Pfeil auf TurnEntity schiff,.8,0,0 Else If KeyDown(208) ; Taste Pfeil ab TurnEntity schiff,-.8,0,0 Else If KeyDown(205) ; Taste rechts TurnEntity schiff,0,-.8,0 Else If KeyDown(203) ; Taste links TurnEntity schiff,0,.8,0 EndIf If KeyDown(17) ; Taste W MoveEntity schiff,0,0,MSF Else If KeyDown(31) ; Taste S MoveEntity schiff,0,0,-MSF EndIf If KeyDown(30) ; Taste A TurnEntity schiff,0,0,.4 Else If KeyDown(32) ; Taste D TurnEntity schiff,0,0,-.4 EndIf EndIf PositionEntity skay,EntityX(schiff),EntityY(schiff),EntityZ(schiff) ; Sky-Box immer Schiff-relativ ohne Drehung PointEntity pl(0),schiff ; Sonne zeigt immer in Richtung Schiff Else If KeyDown(205) ; rechts TurnEntity cammerap,0,.8,0 Else If KeyDown(203) ; links TurnEntity cammerap,0,-.8,0 EndIf EndIf EndIf End Function Function monitor() Color $ff,$ff,0 c1=c1+1 ; Counter für Zwischen-Summe If c1=5 ; Counter-Ende erreicht c1=0 ; Counter zurück setzen t3=t2/6 ; Durchschnitt berechen t2=0 EndIf Text 10,screen_y-20,"ms : "+Str$(t3) ; Anzeige, wieviel ms die gesamte Main-Schleife benötigt If hispeed<>0 Text screen_x-100,10,"High Speed" EndIf If location=>0 Text screen_x-125,10,"No High Speed" EndIf If gefahr=>0 Text screen_x-125,20,"Gefahr" EndIf If tod=>0 Text screen_x-125,30,"Game Over" EndIf End Function Function auto_rotation() Local i For i= 1 To anz_pl TurnEntity pl(i),0,plr(i),0 ; Die Planeten / Objekt Drehung Next End Function Function kolision1() Local i ;******* ; ot=-1 If gefahr>0 i=GetEntityType(pl(gefahr)) If i=2 ; Station in Reichweite ot=i ; Kollisions-Abfrage aktiv ; Freigabe für kolision2 Collisions 1,2,2,1 ; Kollision Schiff / Station Collisions 1,3,1,1 ; Kollision Schiff / Portal EndIf EndIf ; ;******* End Function Function kolision2() Local i,i1,i2 If ot>0 ; Objekt in Reichweite i=CountCollisions(schiff) If i>0 ; Eine Kollision mit dem Schiff liegt an i1=CollisionEntity(schiff,i) ; Objekt-Zeiger holen i2=GetEntityType(i1) ;****** ; If i2=3 ; Objekt-Typ= portal portal(i1) ; dann Ereignis, Zum Beispiel Handels-Schirm etc... Else If i2=2 ; Objekt-Typ= Station ; Kollision und Abprall-Bewegung EndIf ; ;****** EndIf EndIf End Function ;****** ; Function portal(i) Local i1$ i1$=EntityName(i) ; Hole Objekt Infostring If Instr(i1$,"Hangar") ; Ist das Portal ein Hangar ? inHangar=i ; den Objekt-Zeiger als ein/aus Schalter übergeben EndIf End Function Function hangar() If inHangar>0 ; wenn das Schiff sich im Hangar befindet ; Eine andere Ansicht einbleneden EntityAlpha schiff,0 ; Schiffs-Ansicht aus SchiffAlpha=0 ; Zustand merken PositionEntity cammera,0,0,-500 ; neue Kamera-Position TurnEntity cammerap,0,.1,0 ; Rotation um die Station If KeyHit(61) ; Taste F3 inHangar=0 ; Hangar verlassen RotateEntity schiff,0,180,0 ; Schiff drehen MoveEntity schiff,0,0,50 ; von der Station weg bewegen EndIf Else If SchiffAlpha=0 ; Schiff noch nicht zu sehen SchiffAlpha=1 ; Schiff wieder sichtbar EntityAlpha schiff,1 ; RotateEntity cammerap,0,0,0 ; Kamera-Rotation auf 0 PositionEntity cammera,0,.5,-4 ; Alte Position hinter dem Schiff einnehmen EndIf EndIf End Function ; ;****** ; 1. Anzahl Planeten ; Daten für erstes Planeten-Objekt ; 1. Planeten Textur/FileName ; 2. Durchmesser des Planeten/Objekt für die Skalierung ; 3. x,y,z, Position ; 6. Eigen-Rotation ; 7. High-Speed Ausschaltungs-Entfernung (2+7) ; 8. Gefahren-Warnung (2+8) ; 9. Kollisions-Abstand (2+9) : Nur Planeten und Sonne ; 10. Objekt-Type : 0=Sonne / 1=Planet / 2=Station / 3= Portal ; 11. Objekt-Nummer für Ereignis-Identifizierung ; 12. Objekt-Nummer an die dieses Objekt angebunden werden soll ; 13. Object-Name. Info String. .Planeten_System_Daten Data 5 Data "sonne.jpg",10000,80000,0,0,0,5000,4500,4300,0,0,0,"EM 0012" Data "welt.jpg",1000,0,0,2000,0.01,1000,200,50,1,1,0,"Atika 1" Data "welt.jpg",1000,180000,0,2000,0.01,1000,200,50,1,2,0,"Atika 2" Data "welt.jpg",1000,-30000,1500,-10000,0.01,1000,200,50,1,3,0,"Horus" Data "station.x",1,0,0,100,0,1000,200,-1,2,4,1,"New Berlin" Data "portal",8,-5,-7,90,0,0,50,0,3,5,4,"Hangar 1/New Berlin/Atika 1/EM 0012" ; ------------------------------------------------------ ; ; Das geht ja richtig gut voran. Im nächsten Teil möchte ; ich ein weiteres Objekt einführen. Dazu benötigen wir ; ein Objekt, welches einen Transporter darstellt. Es sollte ; 5 mal so lang sein wie das Schiff, aber genau so breit. ; Da die Code-Länge immer mehr zunimmt, und ich das Board ; nicht überlasten will, wird das Ganze im übernächsten ; Teil anders strukturiert. Und irgendwann später kommt ; dann noch ein Editor für die Planeten_System_Daten dazu. ; ; -> Weiter mit 3D-Space-Game-016.bb
Created on 20.08.2005
Zurueck