Alternative SpaceGame 3D Steuerung

Übersicht BlitzBasic FAQ und Tutorials

Neue Antwort erstellen

Bob

Betreff: Alternative SpaceGame 3D Steuerung

BeitragFr, März 04, 2005 12:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Leute,

habe für die 3D Anfänger mal eine Art Tutorial (ehr ein Codeschnipsel) erstellt, um eine 3D Steuerung für eine 3D Spacegame vorzustellen.
Ziel ist es eine Handgelenkschonende, einfache Steuerung zu erstellen mit der jeder sofort klar kommt. Ich hoffe es bringt euch etwas.

Das Problem bei einer Standardsteuerung, wie sie hier schon oft gezeigt wurde, ist das man Mousspeed Werte nimmt um die Camera oder das FirstPerson Object zu bewegen. Anschliesend wird die Maus wieder zurück in die Bildschimmitte gesetzt. Das heisst aber das man die die Maus selbst bei eine wilden Verfolgung z.B, immer wieder anheben und neu Absetzen muss weil man keine 5 meter langen Arme hat.
Mit disem Code hier wird mal eine alternative gezeigt.
(Hoffe sowas ist nicht schon längst vorhanden)

Den Code (inkl. Grafiken ca. 284KB, ist so groß wegen der SkyFake Nebula Map) gibt’s auch noch mal unter unter.

http://www.iomagic.de/bb/Space3DSteuerung.zip

Danke an Silizium-Net für die Planeten Texturen.
Die SkyMap ist von mir selbst erstellt. Ihr dürft sie natürlich, wie den gesamten Code auch, frei verwenden.

Falls dies hier am falschen Platz ist, bitte verschieben lieber Moderator.
Wusste nicht genau wohin damit.
Bob


Code: [AUSKLAPPEN]

;Space Game 3D Steuerung von BOB 


;Variablen Deklaration
Const ScreenX = 800       ;Horizontale Auflösung
Const ScreenY = 600         ;Vertikale Auflösung
Const cDepth  = 32         ;Farbtiefe z.B. 16,24,32
Const hScreenX = ScreenX /2   ;Halbe Horizontale Auflösung
Const hScreenY = ScreenY /2   ;Halbe Vertikale Auflösung
Const MausRange = 150      ;150 Pixel in alle Richtungen vom Bildschirmmittelpunkt dienen als "SensorFeld" für die Steuerung
                     ;Kann man natürlich auch variieren


Global MX#,MY#         ;Variblen um die Mauskoordinaten zu Speichern.
                  ;Sie sind eigentlich nicht notwendig zeigen uns aber zu Testzwecken die Koordinaten an.
Global ShowMausRange =1 ;Boolean Variable um den MausBereich sichtbar zu mchen. Taste M auf dem Keyboard
Global Cursor         ;Bitmap für Mauscursor
Global FlipMode = 1      ;Variable um Flipmode auf 0oder 1 zu setzen um FPS zu Testen
Global speed#         ;Geschwindigkeit und....
Global Roll#         ;Rollwinkel unseres Schiffes. Hier einfach zum leichtern nachvollziehen als Global eingestellt.
                  ;Sollten in komplexeren Spielen ein Field von z.B. einem Type Schiffe sein.
                  ;in dem alle Daten des Schiffs gehalten werden.

Global Camera         ;Unsere Camera
Global Light         ;Ein Licht (Directional)
Global FPSSEC = MilliSecs(), FPS, FRAMES ; Einige Variablen für Frams per Second FPS

;2Variablen für langsames Abfangen einer Rollbewegung des Schiffes
Global RollBack = False
Global Rolling = False

;3D INitialisierung mit Doublebuffering, Ab Hier sollte erstmal alles Klar sein
Graphics3D ScreenX,ScreenY,cDepth,2
SetBuffer BackBuffer()


InitCamera            ;Eine Funktion um alle Cameradaten Einzustellen
Light=CreateLight()
TurnEntity Light,0,0,45


NebulaBG = Create_FakeSky(camera,"nebula.jpg")  ;Eine Function um den Hintergrund zu erstellen.


;Damit's im All nicht so leer ist werden 2 Planeten Erstellet
Planet1 = CreateSphere(32)
Planet1Tex = LoadTexture ("planet1.jpg")
EntityTexture Planet1,Planet1Tex
PositionEntity Planet1,70,200,700
ScaleEntity Planet1,100,100,100,1

Planet2 = CopyEntity(Planet1)
Planet2Tex = LoadTexture ("planet2.jpg")
EntityTexture Planet2,Planet2Tex
ScaleEntity Planet2,50,50,50
PositionEntity Planet2,-60,900,1500

MoveMouse(hScreenX,hScreenY)       ;Die Maus in die Mitte Des Bildschirms bringen
HidePointer()                   ;Die Maus Abschalten    
Cursor = LoadImage("cursor.png")   ;Einen eigenen Mauscursor Laden   
MidHandle Cursor               ;und das Handle ins Zentrum verschieben   

;Unser Mainloop --------------------------------------------------------------------
While Not KeyDown(1)
   CheckKeys                  ;Überprüft alle Tastatureingaben
   CheckMouse                  ;   "       die Maus
   If RollBack Then StopRolling   ;Rollbewegung abfangen wenn notwendig

   RenderWorld

   ;2D Bereich
   DrawImage cursor,hScreenX+mx, hScreenY-my   ;Unser Mauscursor
   If ShowMausRange Then                  ;MausBereich
      Rect hScreenX-Mausrange,hScreenY-MausRange,MausRange*2,MausRange*2,0
   EndIf
   
   Text 0,0, "Mouse: " +mx + "/" +my
   Text 0,20,"Speed: " +Speed
   Text 0,40,"FPS: " +fps(1)
   Text 0,60,"Keys: Alle Cursor und M"

   Flip FlipMode
Wend
End


Function CheckMouse()
   ;Die Eigentliche Steuerung mit der Maus.
   ;Sorgt dafür das wir unser Raumschiff lässig aus dem Handgelenk Steueren können ohne bei Wilden Verfolgungen
   ;Die Maus wieder in die Mitte des Mauspads setzen zu müssen.
   ;Wie man Sieht wird hier simpelste Mathe angewand. Sollte eigentlich für jeden nachvollziehbar sein.
   ;Im Ersten Block wird dafür gesorgt das die Maus sich nur in einem Quadratischen Bereich von MausRange ab der Bildschirmmitte Bewegt
   
   ;Hier mal die Erste Zeile als Pseudocod zum besseren verständnis.
   ;Ist die Maus X Position  größer als die halbe Bildschirmbreite(hScreenX) + 150 (MausRange), ...
   ;dann Positioniere die MausXY an X = Halbe Bildschirmbreite + MausRange , Y = Aktuelle Y Position.
   ;Mit andern Worten. Überschreite den Bereich nicht.
   If MouseX() > hScreenX + MausRange Then MoveMouse(hScreenX + MausRange,MouseY())
   If MouseX() < hScreenX - MausRange Then MoveMouse(hScreenX - MausRange,MouseY())
   If MouseY() > hScreenY + MausRange Then MoveMouse(MouseX(),hScreenY + MausRange)
   If MouseY() < hScreenY - MausRange Then MoveMouse(MouseX(),hScreenY - MausRange)
   

   ;Hier werden die absoltuten Maus X Y Koordinaten in einen Bereich von  -150 bis +150 umgerechnet
   mx# = MouseX() - hScreenX
   my# = MouseY() - hScreenY

   mxS# = mx / Mausrange ;da MX, MY nun im Bereich von -150 +150 liegen, und wir diese durch 150 Teilen
   myS# = my / Mausrange ;erhalten wir Werte im Bereich von -1.0 bis  1.0. Also Sinus - Cosinus Werte ohne diese Funktionen(sin , cos) zu verwenden.
    ;Je näher wir dem äusseren Bereiche unseres MausBereichs kommen, desto schneller bewegt sich das Schiff in diese Position
   ;DebugLog "Mausspeed X|Y: " + mxs + " | " + mys

   
   ;Nun bringen wir die Camera an die erechnete Position
   ;Man beachte das die x,y Koordinaten hier vertauscht und negativiert werden.
   TurnEntity camera,-mys,-mxs,Roll
   MoveEntity camera,0,0,Speed
   
   ;Ein Optimierungsvorschlag
   ;Definiere einen 2ten, kleineren Bereich von z.b. 20 *20.
   ;Wen sich die Maus in diesem Bereich befindet verändert sie mxs und mys nicht mehr.
   ;Somit ist es leichter das Schiff auf Kurs zu halten.

End Function




Function CheckKeys()

   ;Ein / Aus blenden des Mausbereichs
   If KeyHit(50) Then                        ;Taste M
      showMausRange = 1 - ShowMausRange
   EndIf
   
   ;Beschleunigung bzw. Bremsen
   If KeyDown(200) Then Speed = speed + 0.01      ;Cursor Up
   If KeyDown(208) Then Speed = speed - 0.01      ;Cursor Down
   If Speed > 20 Then speed = 20
   If Speed < -0 Then speed = 0
   
   ;Rollen des Schiffs
   RollBack = True
   If KeyDown(205) Then                     ;Cursor Left  Rollen des Schiffs
       Rolling = 1
       RollBack = False
       Roll= Roll + 0.01
      If Roll >  2 Then Roll = 2
   EndIf
      
      
   If KeyDown(203) Then                     ;Cursor Right Rollen des Schiffs
       Rolling = -1
       RollBack = False      
       Roll= Roll - 0.01
         If Roll < -2 Then Roll = -2
   EndIf
   
End Function

Function StopRolling()   
                           ;Sorgt für einen weicheren Stillstand wenn die Rolltasten
   If rolling <> 0 Then         ;nicht mehr gedrückt werden
      If Rolling = 1 Then         ;lässt sich bestimmt viel eleganter lösen
         Roll= Roll - 0.05
         If Roll < 0Then
            Roll =  0
            Rolling = 0
         EndIf
      EndIf
      If Rolling = -1 Then
         Roll= Roll + 0.05
         If Roll > 0 Then
            Roll =  0
            Rolling = 0
         EndIf
      EndIf
   EndIf
End Function


Function InitCamera()
   Camera = CreateCamera(cam)
   CameraFogMode camera,1            ;Nebel Einscahlten
   CameraFogRange camera,1,5000   
   CameraRange camera,0.1,20000         
   CameraZoom camera,1.5
   CameraFogColor camera, 80,125,200
   CameraClsColor camera, 80,125,200
End Function




Function Create_FakeSky(Parent,TexFile$)
   ;Diese Function erstellt eine einzelnes Sprite das uns als SkyBox dient.
   ;Tatsächlich wird keine SkyBox erstellt sondern gefakt.
   ;D.h. wir befinden uns nicht in einem SkyBox Würfel sondern haben nur das Sprite das immer direkt vor der Camera klebt.

   
   sprite = CreateSprite(Parent)      ;Das Sprite mit der Camera als Parent
   ScaleSprite sprite, 100,100         ;Großzügig scalieren damit es den ganzen Sichtbereich der Camera abdeckt.
   PositionEntity sprite,0,0,110      ;. nach hinten verschieben damit sich der Nebel auch aut das Sprite auswirkt
   tex = LoadAnimTexture(TexFile,128,512,512,0,6)  ; Unser SkyTextur mit 6 Bilden, wichtig ist der Parameter 128
   SetCubeFace tex,0                        ; Statbild (1 bei dieser texture = frontansicht)
    SetCubeMode tex,3   ;Der Befehl SETCUBEMODE schaltet Darstellungsmodus einer Cubemap-Textur um. Die Textur muss den Flag 128 haben
   EntityTexture sprite,tex ;Textur aufbringen
   EntityOrder sprite,1   ;Durch Diesen Befehl erscheint der FakeSky immer hinter andern Objectn.
   Return sprite         ;Liefert den Komletten Fakesky zurück
End Function


Function FPS(MODE) ;----------------------------------------------------------------------------
   If MODE = 1 Then
      FRAMES = FRAMES + 1
      If MilliSecs() - FPSSEC => 1000 Then
         FPS = FRAMES
         FRAMES = 0
         FPSSEC = MilliSecs()
      EndIf
   EndIf
   Return FPS
End Function






P.S. Habe grade schon in der Vorschau gesehne das die Umbrüche im Code teilweise Falsch sind.
Beim Copy and Paste wird aber alles Richtig gesetzt

Herr Vorragend

BeitragFr, Okt 21, 2005 23:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey.
Dachte eigentlich das wäre das was ich gesucht hätte, habe allerdings
bei:
SetCubeFace tex,0 eine Fehlermeldung Function not found bekommen.
Wo liegt mein Fehler?

Firstdeathmaker

BeitragSa, Okt 22, 2005 1:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Also bei mir funzt der Code perfekt. Die Steuerung ist wirklich gut, nur das rollen ist ein wenig zu träge und die invertierte Steuerung ist gewöhnungsbedürftig, so finde ich sie besser:



BlitzBasic: [AUSKLAPPEN]
;Variablen Deklaration
Const ScreenX = 800 ;Horizontale Auflösung
Const ScreenY = 600 ;Vertikale Auflösung
Const cDepth = 32 ;Farbtiefe z.B. 16,24,32
Const hScreenX = ScreenX /2 ;Halbe Horizontale Auflösung
Const hScreenY = ScreenY /2 ;Halbe Vertikale Auflösung
Const MausRange = 150 ;150 Pixel in alle Richtungen vom Bildschirmmittelpunkt dienen als \"SensorFeld\" für die Steuerung
;Kann man natürlich auch variieren


Global MX#,MY# ;Variblen um die Mauskoordinaten zu Speichern.
;Sie sind eigentlich nicht notwendig zeigen uns aber zu Testzwecken die Koordinaten an.
Global ShowMausRange =1 ;Boolean Variable um den MausBereich sichtbar zu mchen. Taste M auf dem Keyboard
Global Cursor ;Bitmap für Mauscursor
Global FlipMode = 1 ;Variable um Flipmode auf 0oder 1 zu setzen um FPS zu Testen
Global speed# ;Geschwindigkeit und....
Global Roll# ;Rollwinkel unseres Schiffes. Hier einfach zum leichtern nachvollziehen als Global eingestellt.
;Sollten in komplexeren Spielen ein Field von z.B. einem Type Schiffe sein.
;in dem alle Daten des Schiffs gehalten werden.

Global Camera ;Unsere Camera
Global Light ;Ein Licht (Directional)
Global FPSSEC = MilliSecs(), FPS, FRAMES ; Einige Variablen für Frams per Second FPS

;2Variablen für langsames Abfangen einer Rollbewegung des Schiffes
Global RollBack = False
Global Rolling = False

;3D INitialisierung mit Doublebuffering, Ab Hier sollte erstmal alles Klar sein
Graphics3D ScreenX,ScreenY,cDepth,2
SetBuffer BackBuffer()


InitCamera ;Eine Funktion um alle Cameradaten Einzustellen
Light=CreateLight()
TurnEntity Light,0,0,45


NebulaBG = Create_FakeSky(camera,\"nebula.jpg\") ;Eine Function um den Hintergrund zu erstellen.


;Damit's im All nicht so leer ist werden 2 Planeten Erstellet
Planet1 = CreateSphere(32)
Planet1Tex = LoadTexture (\"planet1.jpg\")
EntityTexture Planet1,Planet1Tex
PositionEntity Planet1,70,200,700
ScaleEntity Planet1,100,100,100,1

Planet2 = CopyEntity(Planet1)
Planet2Tex = LoadTexture (\"planet2.jpg\")
EntityTexture Planet2,Planet2Tex
ScaleEntity Planet2,50,50,50
PositionEntity Planet2,-60,900,1500

MoveMouse(hScreenX,hScreenY) ;Die Maus in die Mitte Des Bildschirms bringen
HidePointer() ;Die Maus Abschalten
Cursor = LoadImage(\"cursor.png\") ;Einen eigenen Mauscursor Laden
MidHandle Cursor ;und das Handle ins Zentrum verschieben

;Unser Mainloop --------------------------------------------------------------------
While Not KeyDown(1)
CheckKeys ;Überprüft alle Tastatureingaben
CheckMouse ; \" die Maus
If RollBack Then StopRolling ;Rollbewegung abfangen wenn notwendig

RenderWorld

;2D Bereich
DrawImage cursor,hScreenX+mx, hScreenY+my ;Unser Mauscursor
If ShowMausRange Then ;MausBereich
Rect hScreenX-Mausrange,hScreenY-MausRange,MausRange*2,MausRange*2,0
EndIf

Text 0,0, \"Mouse: \" +mx + \"/\" +my
Text 0,20,\"Speed: \" +Speed
Text 0,40,\"FPS: \" +fps(1)
Text 0,60,\"Keys: Alle Cursor und M\"

Flip FlipMode
Wend
End


Function CheckMouse()
;Die Eigentliche Steuerung mit der Maus.
;Sorgt dafür das wir unser Raumschiff lässig aus dem Handgelenk Steueren können ohne bei Wilden Verfolgungen
;Die Maus wieder in die Mitte des Mauspads setzen zu müssen.
;Wie man Sieht wird hier simpelste Mathe angewand. Sollte eigentlich für jeden nachvollziehbar sein.
;Im Ersten Block wird dafür gesorgt das die Maus sich nur in einem Quadratischen Bereich von MausRange ab der Bildschirmmitte Bewegt

;Hier mal die Erste Zeile als Pseudocod zum besseren verständnis.
;Ist die Maus X Position größer als die halbe Bildschirmbreite(hScreenX) + 150 (MausRange), ...
;dann Positioniere die MausXY an X = Halbe Bildschirmbreite + MausRange , Y = Aktuelle Y Position.
;Mit andern Worten. Überschreite den Bereich nicht.
If MouseX() > hScreenX + MausRange Then MoveMouse(hScreenX + MausRange,MouseY())
If MouseX() < hScreenX - MausRange Then MoveMouse(hScreenX - MausRange,MouseY())
If MouseY() > hScreenY + MausRange Then MoveMouse(MouseX(),hScreenY + MausRange)
If MouseY() < hScreenY - MausRange Then MoveMouse(MouseX(),hScreenY - MausRange)


;Hier Werden die Absoltuten Maus X Y Koordinaten in einen Bereich von -150 bis +150 Umgerechnet
mx# = MouseX() - hScreenX
my# = MouseY() - hScreenY

mxS# = mx / Mausrange ;da MX, MY nun im Bereich von -150 +150 liegen, und wir diese durch 150 Teilen
myS# = my / Mausrange ;Erhalten wir Werte im Bereich von -1.0 bis 1.0. Also Sinus - Cosinus Werte ohne diese Funktionen(sin , cos) zu verwenden.
;Je näher wir uns den äusseren Bereichen unseres MausBereichs kommen, desto schneller wgegt sich das Schiff in diese Position
;DebugLog \"Mausspeed X|Y: \" + mxs + \" | \" + mys


;Nun Bringen wir die Camera an die erenchnete Position
;Man Beachte das die x,y Koordinaten hier vertauscht und negativiert werden.
TurnEntity camera,mys,-mxs,Roll
MoveEntity camera,0,0,Speed

;Ein Optimierungsvorschlag
;Definiere einen 2ten, kleineren Bereich von z.b. 20 *20.
;Wen sich die Maus in diesem Bereich befindet verändert sie mxs und mys nicht mehr.
;Somit ist es leichter das Schiff auf Kurs zu halten.

End Function




Function CheckKeys()

;Ein / Aus blenden des Mausbereichs
If KeyHit(50) Then ;Taste M
showMausRange = 1 - ShowMausRange
EndIf

;Beschleunigung bzw. Bremsen
If KeyDown(200) Then Speed = speed + 0.01 ;Cursor Up
If KeyDown(208) Then Speed = speed - 0.01 ;Cursor Down
If Speed > 20 Then speed = 20
If Speed < -0 Then speed = 0

;Rollen des Schiffs
RollBack = True
If KeyDown(205) Then ;Cursor Left Rollen des Schiffs
Rolling = 1
RollBack = False
Roll= Roll + 0.01
If Roll > 2 Then Roll = 2
EndIf


If KeyDown(203) Then ;Cursor Right Rollen des Schiffs
Rolling = -1
RollBack = False
Roll= Roll - 0.01
If Roll < -2 Then Roll = -2
EndIf

End Function

Function StopRolling()
;Sorgt für einen weicheren Stillstand wenn die Rolltasten
If rolling <> 0 Then ;nicht mehr gedrückt werden
If Rolling = 1 Then ;lässt sich bestimmt viel eleganter lösen
Roll= Roll - 0.05
If Roll < 0Then
Roll = 0
Rolling = 0
EndIf
EndIf
If Rolling = -1 Then
Roll= Roll + 0.05
If Roll > 0 Then
Roll = 0
Rolling = 0
EndIf
EndIf
EndIf
End Function


Function InitCamera()
Camera = CreateCamera(cam)
CameraFogMode camera,1 ;Nebel Einscahlten
CameraFogRange camera,1,5000
CameraRange camera,0.1,20000
CameraZoom camera,1.5
CameraFogColor camera, 80,125,200
CameraClsColor camera, 80,125,200
End Function




Function Create_FakeSky(Parent,TexFile$)
;Diese Function erstellt eine einzelnes Sprite das uns als SkyBox dient.
;Tatsächlich wird keine SkyBox erstellt sondern gefakt.
;D.h. wir befinden uns nicht in einem SkyBox Würfel sondern haben nur das Sprite das immer direkt vor der Camera klebt.


sprite = CreateSprite(Parent) ;Das Sprite mit der Camera als Parent
ScaleSprite sprite, 100,100 ;Großzügig scalieren damit es den ganzen Sichtbereich der Camera abdeckt.
PositionEntity sprite,0,0,110 ;. nach hinten verschieben damit sich der Nebel auch aut das Sprite auswirkt
tex = LoadAnimTexture(TexFile,128,512,512,0,6) ; Unser SkyTextur mit 6 Bilden, wichtig ist der Parameter 128
SetCubeFace tex,0 ; Statbild (1 bei dieser texture = frontansicht)
SetCubeMode tex,3 ;Der Befehl SETCUBEMODE schaltet Darstellungsmodus einer Cubemap-Textur um. Die Textur muss den Flag 128 haben
EntityTexture sprite,tex ;Textur aufbringen
EntityOrder sprite,1 ;Durch Diesen Befehl erscheint der FakeSky immer hinter andern Objectn.
Return sprite ;Liefert den Komletten Fakesky zurück
End Function


Function FPS(MODE) ;----------------------------------------------------------------------------
If MODE = 1 Then
FRAMES = FRAMES + 1
If MilliSecs() - FPSSEC => 1000 Then
FPS = FRAMES
FRAMES = 0
FPSSEC = MilliSecs()
EndIf
EndIf
Return FPS
End Function

www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image

stfighter01

BeitragSo, Okt 23, 2005 22:55
Antworten mit Zitat
Benutzer-Profile anzeigen
jo, die steuerung ist cool, aber da du gefragt hast ob es die schon gibt:

dieses spiel verwendet sie Neutral
http://www.microsoft.com/games/freelancer/

mfg stfighter
Denken hilft!
 

Krischan

BeitragSo, Nov 06, 2005 16:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe diese Raumschiffsteuerung mal ein wenig erweitert, wer früher Elite gezockt hat wird sich sicher über den Scanner freuen Mr. Green Ausserdem habe ich so ziemlich alles verändert was mir in den Sinn gekommen ist und jetzt habe ich hier für Euch eine Raumschiffsteuerung, aus der man sogar ein nettes Spiel machen könnte.

user posted image

Steuerung:
Pfeiltasten oben/unten = vor/zurück
Pfeiltasten links/rechts = rollen links / rechts herum
Linke Maustaste = Geschwindigkeit x 10
Rechte Maustaste = Bremse
rechte STRG-Taste gedrückt = Zoom bis 10x, loslassen = standard
F1 = FPS-Limit ein/aus
F2 = Scannerzoom unendlich oder nur bis 500 Entfernung

Anmerkung: wer die am Anfang des Codes befindliche .decl einbindet und dann das ; bei CatchMouse entfernt kann mit seiner Intellimouse auch mit den seitlichen Maustasten rollen. Wer halt mag...


Download
Das Programm braucht natürlich Texturen/Grafiken, Ihr könnt alles hier herunterladen (Code ist darin enthalten): Spaceflight3D.zip
Wer lieber eine fertige EXE angucken will, die gibts hier: Spaceflight3D.exe


Starflight-Schriftart
Die Schriftart habe ich übrigens selbst erstellt (Pixel für Pixel von einem WinUAE-Screenshot mit Starflight 1 abgezeichnet und was nicht zu sehen war möglichst im Fontstil ergänzt), wer sie verwenden mag, bitte.


Scanner
Der Scanner zeigt alle bekannten Objekte an, egal wie weit sie weg sind. Er arbeitet mit einer exponentiellen Formel, d.h. wenn ein Objekt sehr nahe ist, erscheint es auch nah am Raumschiff, wenn es weiter weg ist, klebt es am Rand vom Scanner. Ich habe versucht, dass soweit wie möglich verständlich darzustellen, es war aber nicht leicht, also wenn das jemand verbessern kann/möchte, bitte Smile Für Nahbereichsabtastung kann man aber umschalten.

Die Stäbchen zeigen, ob ein Objekt über oder unter der "Ekliptik" des Raumschiffes ist, also ein Strich oberhalb heisst, dass es unter uns und ein Strich unterhalb dass es über uns ist. Das Dreieck nach oben zeigt ungefähr den FOV der Kamera an, zoomt man, ändert sich dieser dynamisch mit, ist aber nicht 100% exakt.


Einschwenken in Planetenorbit
Das Einschwenken in eine Planetenumlaufbahn gestaltete sich ebenfalls schwierig, ich habe das jetzt mal so schnell reingebastelt, dass wenn man mit dem Entityradius des Objektes kollidiert, die Geschwindigkeit auf 0 gesetzt wird und man langsam auf eine etwas höhere Umlaufbahn transportiert wird. Zum Verlassen einfach den Rückwärtsgang einlegen, vorwärts ist dann verboten. Auch hier, wer da was cooleres basteln möchte, bitte.


Technisches
Der Scanner ist ein Sprite, welches immer an derselben Position gehalten wird, quasi 2D auf 3D gemalt wird. Darüber wird jeden Hauptschleifendurchgang ein Bild gelegt, welches die Positionen der Zielobjekte berechnet. Der Scanner passt sich übrigens der Grafikauflösung an, bei 1024 oder 1280 sieht er am Besten aus, man kann aber auch kleinere/grössere Auflösungen einstellen.


Entfernungs-Bug
Was ich noch nicht gemacht habe ist einen üblen Bug zu bereinigen. Wenn man so Daumen mal Pi 1.000.000 von 0,0,0 weit weg ist fangen die Meshes an, inkonsistent zu werden (kann man sehen, wenn man zoomt, die Skybox flackert oder ist ganz weg). Man müsste den Code so umschreiben, dass sich nicht die Kamera sondern alles drumherum bewegt, hab ich noch nicht angefasst. Wer möchte... Wink


Code
Zum Schluss noch der Code, der mittlerweile recht gross geworden ist. Ich habe viel kommentiert und versucht, möglichst sinnvolle Variablennamen zu verwenden. Ein paar Stellen sind etwas unübersichtlich und es sind bestimmt auch noch ein paar grobe Anfängerfehler drin. Geschwindigkeitsmässig habe ich ein paar Stellen optimiert, andere wiederum nicht. Bei mir (P4 3.2GHz mit Radeon 9800Pro) bekomme ich so 250-300 FPS auf der 1024er Fensterauflösung, wer da noch ein paar FPS herausholen kann, der soll Smile

Genug gelabert, hier nun der fertige Code:

BlitzBasic: [AUSKLAPPEN]
;---------------------------------------------------------------------------------------------------
;
;Dieser Teil ist nur erforderlich, wenn die 4./5. Maustaste abgefragt werden soll!
;siehe Funktion Catchmouse(), dort dann das \";\" vor dem Code entfernen
;
;User32.decls Anfang -------------------------------------------------------------------------------
;
;.lib \"user32.dll\"
;api_GetAsyncKeyState% (vKey%) : \"GetAsyncKeyState\"
;
;User32.decls Ende ---------------------------------------------------------------------------------

;Variablen------------------------------------------------------------------------------------------


;Konstanten
Const ScreenX = 640 ;horizontale Auflösung
Const ScreenY = 480 ;vertikale Auflösung
Const ScreenC = 32 ;Farbtiefe
Const ScreenM = 2 ;Fenster/Vollbild
Const hScreenX = ScreenX/2 ;halbe horizontale Auflösung
Const hScreenY = ScreenY/2 ;halbe vertikale Auflösung
Const MausRangeX = ScreenX/2 ;Laufweite der Maus X
Const MausRangeY = ScreenY/2 ;Laufweite der Maus Y


;Globale Parameter
Global FlipMode = 1 ;Bufferflip-Modus
Global radarzoom = 0 ;Zoom des Radars (0=unendlich, 1=bis 500)
Global radarrange = 500 ;Radarweite bei radarzoom=1
Global camzoom# = 1.5 ;Kamerazoom
Global minzoom# = 1.5 ;Kamerazoom minimal
Global maxzoom# = 10 ;Kamerazoom maximal
Global mousespeed# = 2 ;Mausgeschwindigkeit (1=schnell, 10=langsam)
Global fmousespeed# = 2 ;Mausgeschwindigkeitshilfsvariable
Global rise# = 255 ;Farbwert am Anfang des Blinkens auf dem Radar
Global testplaneten = 10 ;Dummyplaneten-Anzahl
Global RollBack = 1 ;Gegenroll-Flag
Global Rolling = 1 ;Roll-Flag
Global ScreenF# = ScreenX/1024.0 ;Verhältnisfaktor für bestimmte Werte auf 1024 normalisiert
Global RadarX = 400*ScreenF# ;z.B. die Breite des Radars
Global RadarY = 200*ScreenF# ;z.B. die Höhe des Radars
Global orbitname$ = \"?\" ;Standardorbitname
Global brake# = .0001 ;Bremsfaktor


;Globale Variablen
Global MX# ;Hilfsvariable Maus
Global MY# ;Hilfsvariable Maus
Global speed# ;Geschwindigkeit
Global Roll# ;Rollfaktor
Global FPSSEC = MilliSecs() ;FPS-Berechnungsstart
Global FPS ;FPS-Wert
Global FRAMES ;Frames-Wert
Global risecol# ;Radarblinken
Global zoomfaktor# ;Zoomfaktor
Global showziel ;Ziel für Pick
Global Zielname$ ;Zielname
Global Zieldistanz# ;Zielentfernung zur Kamera
Global font ;Customfont
Global stufe# ;Geschwindigkeitsstufe
Global kollision ;Kollisionsflag
Global edz# ;Entfernungshilfsvariable

;Globale Objekte
Global Camera ;unsere Kamera
Global stern ;Sternhintergrund
Global tex_stern ;Sternhintergrund-Textur
Global nebel ;Nebelhintergrund
Global tex_nebel ;Nebelhintergrund-Textur


;Felder dimensionieren
Dim testp(testplaneten) ;Feld für Testplaneten
Dim ziele(3+testplaneten) ;Feld für Radarziele
Dim zielro(3+testplaneten) ;Feld für Radarzielfarbenanteil Rot
Dim zielgr(3+testplaneten) ;Feld für Radarzielfarbenanteil Grün
Dim zielbl(3+testplaneten) ;Feld für Radarzielfarbenanteil Blau
Dim zielsi(3+testplaneten) ;Feld für Radarzielgrösse
Dim zielra#(3+testplaneten) ;Feld für Radarzielradius


;Programmstart--------------------------------------------------------------------------------------


;Programmstart
Graphics3D ScreenX,ScreenY,ScreenC,ScreenM
AppTitle \"Spaceflight 3D Demo 1.0 by Krischan\"
SetBuffer BackBuffer()
SeedRnd MilliSecs()


;Schriftart laden
font=LoadFont(CurrentDir()+\"media\starflt.fon\")
title=LoadFont(CurrentDir()+\"media\starflt.fon\",18)
SetFont title

;Titelscreen zeigen
Text hScreenX,hScreenY,\"Loading Spaceflight 3D Demo 1.0\",1,1
Text hScreenX,hScreenY+FontHeight(),\"by Krischan\",1,1
Flip
SetBuffer BackBuffer()

;normale Schriftgrösse setzen
SetFont font


;Sprites laden und verstecken
spr_sonne=LoadSprite(CurrentDir()+\"media\sonne.png\",1)
spr_raster=LoadSprite(CurrentDir()+\"media\raster.png\",2)
HideEntity spr_sonne
HideEntity spr_raster


;Texturen laden
tex_erde=LoadTexture(CurrentDir()+\"media\erde.jpg\",1)
tex_mond=LoadTexture(CurrentDir()+\"media\mond.jpg\",1)
tex_planet=LoadTexture(CurrentDir()+\"media\planet.jpg\",1)
tex_nebel=LoadTexture(CurrentDir()+\"media\nebel.jpg\")
tex_stern=LoadTexture(CurrentDir()+\"media\sterne.png\")
tex_wolken=LoadTexture(CurrentDir()+\"media\wolken.png\",2)


;Kamera, Licht und Skybox erstellen
InitCamera
InitLight
InitSkybox(tex_nebel,tex_stern)


;Hauptobjekte erstellen
sonne1 = NewSprite(\"Sonne\",0,spr_sonne,140,0,0,-1500,1.0,0,0,0)
sonne2 = NewObject(0,\"Sonne\" ,0 ,0 , 32,0,100.00, 100.00, 0,0,-1500,0, 0,0,0,0,0,0.0,2,1,1)
planet1 = NewObject(0,\"Erde\" ,sonne2 ,tex_erde , 32,0, 1.00, 1.00, 0,0, 0,0, 0,0,0,0,0,1.0,2,1,1)
planet2 = NewObject(0,\"Mond\" ,planet1,tex_mond , 32,0, 0.30, 0.30, 0,0, 0,0, 0,0,3,0,0,1.0,2,1,1)
clouds = NewObject(0,\"Wolken\" ,planet1,tex_wolken, 32,0, 1.01, 0.00, 0,0, 0,0, 0,0,0,0,0,1.0,0,0,0)
sphere = NewObject(0,\"Sphäre\" ,camera ,0 , 32,0, 0.10, 1.00,-5,0, -5,0,-45,0,0,0,0,0.0,1,0,0)


;Werte fürs Radar zuweisen
ziele(0)=planet2:zielro(0)=128:zielgr(0)=128:zielbl(0)=128:zielsi(0)=2:zielra#(0)=1
ziele(1)=planet1:zielro(1)= 0:zielgr(1)=128:zielbl(1)=255:zielsi(1)=4:zielra#(1)=3
ziele(2)=sonne2 :zielro(2)=255:zielgr(2)=255:zielbl(2)= 0:zielsi(2)=4:zielra#(2)=125


;Testplaneten hinzufügen
For i=1 To testplaneten
x=Rnd(-i*100,i*100):y=Rnd(-i*100,i*100):z=Rnd(-i*100,i*100)
testp(i)=NewObject(0,\"Testplanet \"+i,sonne2,tex_planet,32,0,1.0,2.0,x,y,z,0,0,0,0,0,0,1,2,1,1)
ziele(2+i)=testp(i)
zielro(2+i)=255
zielgr(2+i)=0
zielbl(2+i)=255
zielsi(2+i)=4
zielra#(2+i)=5
Next


;Radar erstellen mit 75% Alpha
raster=NewSprite(\"Raster\",camera,spr_raster,200*ScreenF#,0,-hscreenY,hscreenx*camzoom#,0.75,0,0,0)


;Mauscursor ändern
MoveMouse(hScreenX,hScreenY)
HidePointer()
Cursor=LoadImage(\"media\cursor.png\")
MidHandle Cursor


;Kollisionsabfrage scharfschalten
Collisions 1,2,2,2


;Zeichenreihenfolge ändern
EntityOrder raster,-1
EntityOrder nebel,3
EntityOrder stern,3


;Hauptschleife--------------------------------------------------------------------------------------


;Mainloop
While Not KeyDown(1)


;alte Kameraposition speichern
oldx#=EntityX(camera)
oldy#=EntityY(camera)
oldz#=EntityZ(camera)

;Rollbewegung abfangen wenn notwendig
If RollBack Then StopRolling

;Eigenbewegungen
If bug=0 Then MoveEntity sphere,0,0,.1:bug=1
TurnEntity planet1,0,1,0
TurnEntity clouds,-.01,.01,0
TurnEntity sonne2,0,.0005,0

;Zielplaneten-Radius abhängig von der Entfernung zur Kamera
For i=1 To testplaneten
TurnEntity testp(i),0,.5,0
ed#=EntityDistance(camera,testp(i))
EntityRadius testp(i),1+ed#/50
Next

fspeed#=fps(1)


;Kollisionen abfragen
Collisions 1,2,2,2

;Kollisionen durchführen
UpdateWorld

;bei Kollision in Orbit um Ziel einschwenken
If CountCollisions(sphere) Then

;Kamera-Stop und neuen Parent zuweisen
PositionEntity sphere,0,0,0
PositionEntity camera,oldx#,oldy#,oldz#
zielorbit=CollisionEntity(sphere,1)
orbitname$=EntityName(zielorbit)
EntityParent camera,zielorbit

;Orbitradius berechnen
For i=0 To testplaneten+2
orbit#=0
If ziele(i)=zielorbit Then
orbit#=zielra#(i)
speed#=0
Exit
EndIf
Next

EndIf

;Rückwärtsgang mit Sinus bei Orbiteinschwenkung
If zielorbit<>0 Then
edz#=EntityDistance(camera,zielorbit)

;Hilfswert für Sinus-Einschwenken erhöhen
back#=back+.01:If back#>180 Then back#=-180

;falls innerhalb des Orbits langsam einschwenken
If edz#<orbit#-(orbit#/100) Then
MoveEntity camera,0,0,-Sin(back#)
kollision=1
Else kollision=0:back#=0
EndIf

;bei Verlassen des Orbits alles rücksetzen
If edz#>orbit# Then
zielorbit=0
EntityParent camera,0
orbitname$=\"?\"
EndIf
EndIf

;Tastaturabfrage
CheckKeys

;Mausabfrage
CheckMouse

;Rastersprite immer an die gleichen Stelle zeichnen
PositionEntity raster,0,-hScreenY,hScreenx*camzoom#

;Szene Rendern
RenderWorld

;Radarblip-Grafik einzeichnen
radar=ZeichneRadar()
DrawImage radar,(ScreenX-RadarX)/2,ScreenY-RadarY

;Werte in verständlichen Text übertragen
If radarzoom=0 Then radartext$=\"unendlich\" Else radartext$=\"bis 500\"
If Flipmode=0 Then fpstext$=fspeed#+\" (maximal)\" Else fpstext$=fspeed#+\" (fixed)\"

;Textausgabe
Color 255,255,255
Text 5, 5,\"Speed:\" :Text 150, 5,Speed#
Text 5,20,\"FPS:\" :Text 150,20,fpstext$
Text 5,35,\"Ziel:\" :Text 150,35,Zielname$
Text 5,50,\"Entfernung:\" :Text 150,50,Zieldistanz#
Text 5,65,\"Zoomfaktor:\" :Text 150,65,zoomfaktor#
Text 5,80,\"Radarzoom:\" :Text 150,80,radartext$
Text 5,95,\"Im Orbit von:\":Text 150,95,orbitname$

;Zielnamen auf Objekt anzeigen
Zielname

;Mauscursor einzeichnen
DrawImage cursor,hScreenX+mx, hScreenY+my

;Bufferflip
Flip Flipmode

;Radarbild wieder löschen sonst gibt's Speicherüberlauf!
FreeImage radar

;Kollisionspuffer löschen
ClearCollisions

Wend

End


;Funktionen-----------------------------------------------------------------------------------------


;Ziele mittels neuem Bild über das Radarsprite zeichnen
Function ZeichneRadar()

;Bild für Radardarstellung erzeugen
radar=CreateImage(RadarX,RadarY)
MaskImage radar,0,0,0

;Puffer sperren
SetBuffer ImageBuffer(radar)
LockBuffer ImageBuffer(radar)

;dynamisches FOV einzeichnen
winkel#=52/(camzoom#/1.5)+(camzoom#/3)
Color 0,0,192
Line (RadarX/2)+1,(RadarY/2)-1,(RadarX/2)+1-(Tan(winkel#)*(75*ScreenF#)),Tan(winkel#-camzoom#/3)^2*((7*ScreenF#)*camzoom#^1.9)
Line (RadarX/2)+1,(RadarY/2)-1,(RadarX/2)+1+(Tan(winkel#)*(75*ScreenF#)),Tan(winkel#-camzoom#/3)^2*((7*ScreenF#)*camzoom#^1.9)

;Objekte einzeichnen
For i=0 To testplaneten+2
RadarZiel(RadarX+1,RadarY-1,ziele(i),camera,zielro(i),zielgr(i),zielbl(i),zielsi(i))
Next

;Raumschiff in die Mitte als roten Punkt
RadarBlip RadarX/2+1,RadarY/2-1,255,0,0,4

;Puffer freigeben
UnlockBuffer ImageBuffer(radar)
SetBuffer BackBuffer()

;Bild zurückgeben
Return radar

End Function


;Mausbewegung/tasten abfragen
Function CheckMouse()

;linke Maustaste=Turbo
If MouseDown(1) Then stufe#=.01 Else stufe#=0.001

;rechte Maustaste=Bremse
If MouseDown(2) Then Bremse

;Berechnungen für die Bewegung
If MouseX() > hScreenX + MausRangeX Then MoveMouse(hScreenX + MausRangeX,MouseY())
If MouseX() < hScreenX - MausRangeX Then MoveMouse(hScreenX - MausRangeX,MouseY())
If MouseY() > hScreenY + MausRangeY Then MoveMouse(MouseX(),hScreenY + MausRangeY)
If MouseY() < hScreenY - MausRangeY Then MoveMouse(MouseX(),hScreenY - MausRangeY)
mx# = MouseX() - hScreenX
my# = MouseY() - hScreenY
mxS# = mx / MausrangeX
myS# = my / MausrangeY

;mit Mausgeschwindigkeit korrigieren
mxS#=Sin(mxS#*90)/camzoom#*5/mousespeed#
myS#=Sin(myS#*90)/camzoom#*5/mousespeed#

;bei Kollisionsrückwärtsgang Geschwindigkeit verhindern
If kollision=1 Then speed#=0

;Raumschiffbewegung durchführen
TurnEntity camera,mys,-mxs,Roll
MoveEntity camera,0,0,Speed#

;Skybox immer relativ zur Kamera positionieren
PositionEntity nebel,EntityX(camera,1),EntityY(camera,1),EntityZ(camera,1)
PositionEntity stern,EntityX(camera,1),EntityY(camera,1),EntityZ(camera,1)

End Function


;Tastendrücke abfragen
Function CheckKeys()

;F1: FPS-Begrenzung ein/aus
If KeyHit(59) Then flipmode=1-flipmode

;Pfeiltaste rauf/runter: Beschleunigung bzw. Bremsen
If KeyDown(200) Then Speed# = speed# + stufe#
If KeyDown(208) Then Speed# = speed# - stufe#

;Geschwindigkeit immer weiter erhöhen
speed#=speed#*1.0001

;und begrenzen
If Speed# > 100 Then speed# = 100
If Speed# < -100 Then speed# = -100

;F2: Radarbereich verringern
If KeyHit(60) Then radarzoom=1-radarzoom

;rechte STRG: Zoomen
If KeyDown(157) Then ZoomIn Else ZoomOut

;Rollen des Schiffs
RollBack = True

;Pfeiltaste links oder X-Maustaste links: links herum rollen
If KeyDown(205) Or CatchMouse(5) Then
Rolling=1
RollBack=False
Roll=Roll+0.01
If Roll>2 Then Roll=2
EndIf

;Pfeiltaste rechts oder X-Maustaste rechts: rechts herum rollen
If KeyDown(203) Or CatchMouse(6) Then
Rolling=-1
RollBack=False
Roll=Roll-0.01
If Roll<-2 Then Roll=-2
EndIf

End Function


;Zoom erhöhen
Function ZoomIn()

zoomfaktor#=zoomfaktor#+.25
If zoomfaktor#>=maxzoom# Then zoomfaktor#=maxzoom#:EntityAlpha stern,1
Zoom

End Function


;Zoom verringern
Function ZoomOut()

zoomfaktor#=zoomfaktor#-.5
If zoomfaktor<=0 Then zoomfaktor#=0:EntityAlpha stern,1
Zoom

End Function


;Zoom durchführen
Function Zoom()

sz#=1+zoomfaktor#
ScaleTexture tex_stern,1/sz#,1/sz#
camzoom#=minzoom#+zoomfaktor#
CameraZoom camera,camzoom#

End Function


;Rollen weich abstoppen
Function StopRolling()

If rolling<>0 Then
If Rolling=1 Then
Roll=Roll-0.05
If Roll<0 Then
Roll=0
Rolling=0
EndIf
EndIf
If Rolling=-1 Then
Roll=Roll+0.05
If Roll>0 Then
Roll= 0
Rolling=0
EndIf
EndIf
EndIf

End Function


;FPS Counter
Function FPS(MODE)
If MODE = 1 Then
FRAMES = FRAMES + 1
If MilliSecs() - FPSSEC => 1000 Then
FPS = FRAMES
FRAMES = 0
FPSSEC = MilliSecs()
EndIf
EndIf
Return FPS
End Function


;weitere Maustasten abfragen (z.b. die 4./5. bei der Intellimouse)
Function CatchMouse(x)

;If MouseX()>0 And MouseX()<ScreenX And MouseY()>0 And MouseY()<ScreenY Then Return api_GetAsyncKeyState%(x)/$8000

End Function


;Kamera erstellen
Function InitCamera()

Camera = CreateCamera(cam)
CameraRange camera,0.1,1000000
CameraZoom camera,camzoom#
PositionEntity camera,-5.0,0,-5.0
TurnEntity camera,0,-45,0

End Function


;Licht erstellen
Function InitLight()

Light=CreateLight(2)
LightRange light,1000
PositionEntity light,0,0,-1500
TurnEntity Light,0,0,0
AmbientLight 0,0,0

End Function


;Skybox mit Sternen und Nebel erstellen
Function InitSkybox(tex_nebel,tex_stern)

;Nebelkugel erstellen und leuchten lassen
nebel=NewObject(0,\"Nebel\",0,tex_nebel,32,1,10000,0,0,0,0,0,0,0,0,0,0,0.33,0,0,0)
EntityFX nebel,1

;Sternbox erstellen, leuchten lassen und überblenden
stern=NewObject(1,\"Sterne\",0,tex_stern,0,1,10000,0,0,0,0,0,0,0,0,0,0,1.0,0,0,0)
EntityFX stern,1
EntityBlend stern,3

End Function


;Hilfsfunktion für Spriteerstellung
Function NewSprite(name$,parent,quelle,scale#,posx#,posy#,posz#,alpha#,typ,pick1,pick2)
sprite=CopyEntity(quelle)
NameEntity sprite,name$
ScaleSprite sprite,scale#,scale#
EntityRadius sprite,scale#
PositionEntity sprite,posx#,posy#,posz#
EntityAlpha sprite,alpha#
EntityType sprite,typ
EntityPickMode sprite,pick1,pick2
EntityParent sprite,parent
Return sprite
End Function


;Hilfsfunktion für Objekterstellung
Function NewObject(art,name$,parent,textur,faces,flippen,scale#,radius#,posx#,posy#,posz#,rotx#,roty#,rotz#,movx#,movy#,movz#,alpha#,typ,pick1,pick2)
If art=1 Then planet=CreateCube() Else planet=CreateSphere(faces)
NameEntity planet,name$
If textur Then EntityTexture planet,textur
If flippen Then FlipMesh planet
ScaleEntity planet,scale#,scale#,scale#
EntityRadius planet,radius#
PositionEntity planet,posx#,posy#,posz#
MoveEntity planet,movx#,movy#,movz#
TurnEntity planet,rotx#,roty#,rotz#
EntityAlpha planet,alpha#
EntityType planet,typ
EntityPickMode planet,pick1,pick2
EntityParent planet,parent
Return planet
End Function


;Radarziel berechnen
Function RadarZiel(w,h,ziel,kamera,r,g,b,size)

;Distanz zum Ziel holen
ed#=EntityDistance(kamera,ziel)

;Radarmodus abfragen (bei Radarweitenbegrenzung einfach die entfernten Objekte überspringen,
;sowie die Skala entsprechend verringern
If radarzoom=1 And ed#>radarrange Then Goto skip
If radarzoom=1 Then scale#=.1 Else scale#=1

;Faktor für exponentielle Darstellung berechnen
faktor#=ed#/(150*ScreenF#)+((scale#/Exp(ed#^.00001*(scale#^2))))

;relative Position berechnen
TFormPoint (EntityX(ziel,1),EntityY(ziel,1),EntityZ(ziel,1),0,kamera)
rX#=(0-TFormedX())/faktor#*1.1
rY#=TFormedY()/faktor#
rZ#=TFormedZ()/faktor#/1.95

;Stäbchenhöhe berechnen
hx#=rY#/3.5

;Position des Ziels berechnen
px=w/2-rx#
py=h/2-rz#

;Farben umsetzen
r2=r
g2=g
b2=b

;Ziel blinken lassen
If showziel=ziel Then
risecol#=risecol#+rise#
If risecol#>=255 Then risecol#=255:rise#=-25
If risecol#<=0 Then risecol#=0:rise#=25
r2=risecol#
g2=risecol#
b2=risecol#
EndIf

;Stäbchen einzeichnen
rgb=(r2*$10000)+(g2*$100)+b2
For i=0 To Abs(hx#)+(size/2)
ix=-i:If hx#>=0 Then ix=-ix
WritePixelFast px,py-ix,rgb
Next

;Punkt zeichnen
RadarBlip px,py,r2,g2,b2,size

.skip

End Function


;Radarblip zeichnen
Function RadarBlip(x,y,r,g,b,size)

;Farbe berechnen
rgb=(r*$10000)+(g*$100)+b

;Quadrat zeichnen und die Ecken auslassen = gefaktes Oval :-)
For i=0 To size
For j=0 To size
If size>2 Then
If i=0 And j=0 Then Goto skip
If i=size And j=0 Then Goto skip
If i=0 And j=size Then Goto skip
If i=size And j=size Then Goto skip
EndIf
WritePixelFast x-(size/2)+i,y-(size/2)+j,rgb
.skip
Next
Next

End Function


;Objekt im Fadenkreuz identifizieren
Function Zielname()

;Kamerapickmode starten
showziel=CameraPick(camera,hScreenX+MX, hScreenY+MY)

;bei Treffer
If showziel Then

;Name und Distanz zum Ziel holen
Zieldistanz#=EntityDistance(camera,showziel)
Zielname$=EntityName(showziel)
breite=Len(Zielname$)*FontWidth()

;Text auf Zielposition ausrichten
CameraProject camera,EntityX(showziel,1),EntityY(showziel,1),EntityZ(showziel,1)
x=ProjectedX()
y=ProjectedY()-FontHeight()/4

;sofern Ziel innerhalb des Bildschirms
If x<>0 And y<>0 Then
Color 0,192,0
Text x,y,\"|\",1,0
Text x,y+FontHeight(),\"|\",1,0
Text x,y+FontHeight()*2,Zielname$,1,0
Text x,y+FontHeight()*3,EntityDistance(camera,showziel),1,0
EndIf

Else

;sonst kein Ziel bekannt
Zieldistanz#=0
Zielname$=\"?\"

EndIf

End Function


;exponentielle Bremse
Function Bremse()

;Bremsfaktor immer weiter erhöhen
fakt#=fakt#+brake#
brake#=brake#*1.05

;Geschwindigkeit um berechneten Faktor verringen
If speed#<>0 Then
If speed#>0 Then
speed#=speed#-fakt#
If speed#<0 Then speed#=0:brake#=0.0001
EndIf
If speed#<0 Then
speed#=speed#+fakt#
If speed#>0 Then speed#=0:brake#=0.0001
EndIf
EndIf

End Function

Neue Antwort erstellen


Übersicht BlitzBasic FAQ und Tutorials

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group