Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

06.01.2007, 12:59

Opengl: Steuerung eines Raumschiffes

Hallo.
Ich probiere gerade ein kleines Spiel zu schreiben (so ähnlich wie Galactica).
Jetzt habe ich ein problem mit der Steuerung.
Hmm.
Ich schätze mal das da wieder viel mathematik ins Spiel kommen wird.
Ich hatte jetzt hier schon im Forum gesucht und eine Autosteuerung gefunden und diese schonmal übernommen.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
tVertex3D vDirection = tVertex3D(sinf(fWinkel), 0.0f, cosf(fWinkel)); 

if((GetKeyState(VK_UP) & 0x80) || (GetKeyState('W') & 0x80))
    {   
        Pos.x += speed * vDirection.x;
        Pos.y += speed * vDirection.y;
        Pos.z += speed * vDirection.z;
    }

    if((GetKeyState(VK_DOWN) & 0x80) || (GetKeyState('S') & 0x80))
    {
        Pos.x -= speed * vDirection.x;
        Pos.y -= speed * vDirection.y;
        Pos.z -= speed * vDirection.z;
    }

    if((GetKeyState(VK_LEFT) & 0x80) || (GetKeyState('A') & 0x80))
    {   
        fWinkel+=speed;
        
    }

    if((GetKeyState(VK_RIGHT) & 0x80) || (GetKeyState('D') & 0x80))
    {
        fWinkel-=speed;
        
    }

Doch ich kann ja nicht eine Auotsteuerung benutzen!
Deswegen bräuchte ich ein bisschen hilfe.
Die aktuelle Mausposition soll das Schiff lenken.
Mit w soll man den Schub betätigen und mit s abbremsen.
mit d un a soll sich das Schiff um die z achse drehen.

Vorallem habe ich das problem mit der Maus.
Ich hatte schon ein ähnlichen code gesucht und den hier gefunden.
Doch er ist eigentlich nur für die ego-shooter-Sicht geschrieben worden.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
POINT mousePos; 
    int mid_x = wndWidth  >> 1; 
    int mid_y = wndHeight >> 1; 
    float angle_y  = 0.0f;              
    float angle_z  = 0.0f;                          
    
    GetCursorPos(&mousePos);    // Get the 2D mouse cursor (x,y) position                   

    
    if( (mousePos.x == mid_x) && (mousePos.y == mid_y) ) return;

    SetCursorPos(mid_x, mid_y); // Set the mouse cursor in the center of the window                     


    // Get the direction from the mouse cursor, set a resonable maneuvering speed

    angle_y = (float)( (mid_x - mousePos.x) ) / 1000;       
    angle_z = (float)( (mid_y - mousePos.y) ) / 1000;


    mView.y += angle_z * 2;


    if((mView.y - mPos.y) > 8)  mView.y = mPos.y + 8;
    if((mView.y - mPos.y) <-8)  mView.y = mPos.y - 8;
    
    Rotate_View(-angle_y); // Rotate


Leider kann ich mit dem Code eher weniger etwas anfangen weil ich nicht verstehe was dort gemacht wird.
:?
Wie soll das gehen?
Gruß Flo

2

06.01.2007, 13:52

Re: Opengl: Steuerung eines Raumschiffes

Zitat von »"F-Wölkchen"«


Leider kann ich mit dem Code eher weniger etwas anfangen weil ich nicht verstehe was dort gemacht wird.
:?


Warum übernimmst du einen Code, den du nicht verstehst? :?:
Sprachen: C/C++, C#, Assembler (16-Bit), QuickBASIC

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

3

06.01.2007, 14:54

Die Idee, die dahinter steht, ist folgende:

Man bestimmt, wie weit die Maus vom Bildschirmmittelpunkt entfernt ist. Daraus erhält man zwei Steuerausschläge dx und dy, bezogen auf die Bildschirmauflösung. Das ist in etwas das gleiche, als würde man den Lenkausschlag eines Joystick abfragen.

Aus diesen Steuerausschlägen bestimmt man, wie weit sich das Raumschiff um die entsprechende Achse drehen soll. Je größer der Ausschlag, desto weiter kann auch rotiert werden. Für dx z.B. die Achse, die senkrecht durch das Schiff (meist y-Achse, oder yaw) läuft und für dy die Querachse (meist x-Achse, oder pitch). Die Längsachse ist die Bewegungsrichtung (meist z-Achse, oder roll), um die das Schiff rollen kann.

Bedenke dabei: wenn ich um eine Achse rotiere, bleibt die Achse selbst unverändert; betroffen sind jeweils nur die beiden anderen Achsen.

Die Rotation kann man für DX9 z.B. mit D3DXMatrixRotationYawPitchRoll berechnen lassen. Für GL gibt es vermutlich auch sowas in der Richtung. Wenn ich also meine Rotationen durchgeführt habe, gibt es eine neue Ausrichtung des Schiffes. Die Position bestimmt sich aus der Längsachse und der aktuellen Geschwindigkeit.

In Bezug zur Autosteuerung gibt es einen sehr wesentlichen Unterschied. Beim Auto hat man nur einen Winkel, der die Richtung bestimmt. Im Raumschiff sind das drei unabhängige Winkel und die direkte Berechnung der Richtung, so wie sie im Autobeispiel steht, wäre recht unübersichtlich. Darum benutzt man für diesen Fall eben Matrix-Rechnung, mit der man ja transformieren kann.

Aus yaw-pitch-roll zusammen mit der neuen Position des Schiffes, kann ich mir nun eine Kamera-Transformation bauen, und alles sieht richtig aus. Man schaut entlang der z-Achse die genau durch die Bildschirmmitte läuft.

Der Mauszeiger wird hart wieder die Mitte gesetzt, damit man bei jeder Abfrage wieder die Maus bewegen muss, um weiterzusteuern (so als hätte man den Joystick wieder losgelassen). Wenn man das nicht macht, steuert man solange, wie die Maus nicht wieder auf die Startposition bewegt wurde; dann wird geradeausfliegen aber schwerer)

Der Unterschied zwischen einer (einfachen) Tastaturabfrage und der Mausposition (oder eines Joystick) ist einfach der, dass man mit der Tastatur immer einen konstanten Steuerausschlag bewirkt und mit der Maus eben je nach Bewegungsweite einen anderen.

Der Rest ist dann einfach die Mathematik, was eigentlich nicht schwer ist, wenn man gut weiss, was es mit Transformationen auf sich hat. Ohne diesen Hintergrund wird es allerdings schwierig, sowas umzusetzen.

Gruss,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

4

06.01.2007, 21:02

Zitat

Aus yaw-pitch-roll zusammen mit der neuen Position des Schiffes, kann ich mir nun eine Kamera-Transformation bauen, und alles sieht richtig aus. Man schaut entlang der z-Achse die genau durch die Bildschirmmitte läuft.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
POINT StartPos;    
float dx,dy; //Ausschlag

int mid_x = 1280  >> 1;    
int mid_y = 1024 >> 1;      //Der Mittelpunkt wurde generiert


GetCursorPos(&StartPos); //Die Mausposition wird aktuallisiert


if( (StartPos.x == mid_x) && (StartPos.y == mid_y) ) return;  //Wenn die Maus nicht in der Mitte ist gehts weiter!!


SetCursorPos(mid_x,mid_y); //Zeiger wird in die Mitte gesetzt! (startPos ist nicht verändert!)


dx=mid_x - StartPos.x; //Auschlag in x richtung

dy=mid_y - StartPos.y; //Auschlag in y richtung

Also hier ist es ein bisschen schwieriger.
Ich habe also jetzt den Auschlag in x und y richtung (glaub ich ;) ).
Wie gehts es jetzt weiter?
Wie kann ich daraus ein Winkel zum rotieren des Schiffes bekommen?
Wie steht das dann mit der Kamera?
Gruß Flo

Firefly

Alter Hase

Beiträge: 484

Wohnort: Irgendwoundnirgendwo

  • Private Nachricht senden

5

06.01.2007, 22:17

über trigonometrie...;)

willst du eigentlich einen winkel zwischen zwei vektoren wissen, oder nur wie man Vektoren rotiert/skaliert/trasnliert? (Stichwort Matrizen hierzu)

Firefly

Alter Hase

Beiträge: 484

Wohnort: Irgendwoundnirgendwo

  • Private Nachricht senden

6

06.01.2007, 22:19

hier noch ein nützlicher link zu einer Kameraklasse: http://www.gamedev.net/reference/articles/article2160.asp

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

7

07.01.2007, 09:36

Die Winkel sind eigentlich ganz einfach. Ich mach das mal für dx.

Bei Nullausschlag will ich auch 0 Grad rotieren. Bei Maximalausschlag definiere ich 30 Grad als Rotation (bezogen auf eine Sekunde). Da man aber nicht mit einer Sekunde auflöst (sondern höher), muss man auch noch den Zeitfaktor hinschreiben.

C-/C++-Quelltext

1
float winkel_x = delta_time * 30.0f * float (dx) / float (mid_x);


Schon fertig. Jetzt habe ich einen Winkel im Bereich -30 bis 30 Grad.

Für dy geht das entsprechend.

Mit der Kamera-Klasse aus dem Link von Firefly kannst du jetzt schon alles realisieren.

Gruss,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Firefly

Alter Hase

Beiträge: 484

Wohnort: Irgendwoundnirgendwo

  • Private Nachricht senden

8

07.01.2007, 11:10

aber Vorsicht mit den Winkeln! Die meisten Winkel nimmt der Computer nur als Bogenmaß!

Umrechnung hierzu:
180°=PI
1°=PI/180

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

9

07.01.2007, 12:35

Hupps, ja. Das wollte ich eigentlich auch noch sagen :)

Ausserdem will ich hier dann auch gleich noch einem Missverständnis vorbeugen. Wenn man die Winkel so berechnet, bedeutet das auch nicht, dass man hinterher an die Stelle schaut, wo die Maus war.

Da liesse sich auch realisieren, aber die Steuerung wäre dann extrem empfindlich, ausser das Spiel läuft nur mit 1FPS (oder weniger :))
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Werbeanzeige