Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Objekt mit begrenzter Geschwindigkeit zum Mauszeiger drehen


huuuuuh - Fr 04.02.11 21:17
Titel: Objekt mit begrenzter Geschwindigkeit zum Mauszeiger drehen
Ich programmiere seit einigen wochen, immer, wenn ich mal zeit hab, hobbymäßig ein spiel. soll ein Asteroids [http://www.scifiscoop.com/wp-content/uploads/2009/07/asteroids.jpg]-Klon werden, zumindest so in der Art ;)
das Problem, was ich jetz habe, und über das ich mir schon seit tagen den kopf zerbreche, betrifft das drehen des "raumschiffs" in die Richtung des Mauszeigers. also wo man mit der Maus hinzeigt, wird hingeschossen. An sich keine schwieriege sache, lässt sich mit dem Arcustangens relativ leicht ausrechnen. Allerdings soll das Schiff eine maximale Drehgeschwindigkeit haben, und das kriege ich nicht hin. Mein vielversprechendster versuch sieht so aus:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
 float temp =(float)Math.Atan2(actState.Y - Pos.Y, actState.X - Pos.X); //Winkel zum Mauszeiger ausrechnen

           
           float way = temp - Rotation; //Rotation ist der aktuelle Winkel des Schiffs
           if (Math.Abs(way) > turningSpeed) //turningSpeed ist die Drehgeschwindigkeit
           {
              
               
               if (way < 0)
                   Rotation -= turningSpeed;
               else
                   Rotation += turningSpeed;
           
               
           }

danke schonmal, das problem macht mich fertig :(


Tilo - Fr 04.02.11 21:31

Hallo huuuuuh,


Deine Funktion sieht fehlerfrei aus. Die Roation des Raumschiffes erfolgt immer um einen konstanten Winkel. Die Frage ist nun, wie häufig rufst Du diese Funktion auf? Wenn Du sie in einem festem Zeitintervall immer gleich oft aufrufst so wird sich das Objekt wahrscheinlich (für eine genauere Aussage ist mehr Code nötig!) mit einer konstanten Geschwindigkeit drehen.


huuuuuh - Fr 04.02.11 22:03

hi,

das Spiel programmiere ich mit XNA. Der betreffende Code wird also 60x in der Sekunde ausgeführt. Das drehen mit konstanter Geschwindigkeit funktioniert auch. was allerdings nicht funktioniert, ist die komplette drehung. ist wirklich schwer zu erklären, deshalb hier mal als grafik
das problem ist, das ich nicht über die schwelle von PI zu -PI komme und auch keine ahnung habe, wie ich das anstellen soll. PI und -PI sind werte, welche Math.Atan2 mir zurückliefert...


Kha - Sa 05.02.11 00:56

Du musst way nur noch in das Intervall [-pi,pi] bringen. Denn beispielsweise ist die "wirkliche" Differenz von pi zu -pi/2 nicht einfach -pi/2-pi (~Rechtsdrehung um 270°) sondern das +2pi (~Linksdrehung um 90°).


huuuuuh - Sa 05.02.11 12:45

vielen Dank. hat mich auf den richtigen Weg geführt ;)

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:
float temp =(float)Math.Atan2(actState.Y - Pos.Y, actState.X - Pos.X);

           
           float way = temp - Rotation;
           
          
           if (Math.Abs(way) > turningSpeed)
           {
               if (way < -Math.PI)
                   way += 2*(float)Math.PI;
               else if (way > Math.PI)
                   way -= 2*(float)Math.PI;
              
               if (way < 0)
                   Rotation -= turningSpeed;
               else
                   Rotation += turningSpeed;
           
                if (Rotation < -Math.PI)
                   Rotation += 2 * (float)Math.PI;
               else if (Rotation > Math.PI)
                   Rotation -= 2 * (float)Math.PI;
           }