Alternative SpaceGame 3D Steuerung
Übersicht BlitzBasic FAQ und Tutorials
BobBetreff: Alternative SpaceGame 3D Steuerung |
Fr, März 04, 2005 12:36 Antworten mit Zitat |
|
---|---|---|
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 |
Fr, Okt 21, 2005 23:20 Antworten mit Zitat |
|
---|---|---|
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 |
Sa, Okt 22, 2005 1:17 Antworten mit Zitat |
|
---|---|---|
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 |
||
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon Gewinner des BCC #57 User posted image |
stfighter01 |
So, Okt 23, 2005 22:55 Antworten mit Zitat |
|
---|---|---|
jo, die steuerung ist cool, aber da du gefragt hast ob es die schon gibt:
dieses spiel verwendet sie http://www.microsoft.com/games/freelancer/ mfg stfighter |
||
Denken hilft! |
Krischan |
So, Nov 06, 2005 16:48 Antworten mit Zitat |
|
---|---|---|
Ich habe diese Raumschiffsteuerung mal ein wenig erweitert, wer früher Elite gezockt hat wird sich sicher über den Scanner freuen 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.
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 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... 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 Genug gelabert, hier nun der fertige Code: BlitzBasic: [AUSKLAPPEN] ;--------------------------------------------------------------------------------------------------- |
||
Übersicht BlitzBasic FAQ und Tutorials
Powered by phpBB © 2001 - 2006, phpBB Group