Wie bewege ich eine Entität in eine Richtung?

10

Ich habe eine EntityInstanz, die bei jedem Spiel-Tick aktualisiert wird. Nehmen wir einfach an, dass sich die Entität ständig vorwärts bewegt. Ich möchte in der Lage sein, einer Funktion, die sie in diese Richtung bewegt, den Winkel der Entität zuzuweisen:

moveForward(90);sollte sie nach rechts bewegen. Wenn ich meine Rotation als global deklariert habe int, dann tun

moveForward(rotation);
rotation++;

würde es mit seiner Bewegung einen kleinen Kreis zeichnen lassen.

Wie kann ich das machen? Ich gehe davon aus, dass dies Vektormathematik beinhaltet; Ich kenne keine, daher wäre eine kurze Erklärung nett.

Shaun Wild
quelle

Antworten:

15

Nun, im einfachsten Sinne haben Sie so etwas.

   y  |\
      | \
   m  |  \         s
   o  |   \        p
   v  |(a) \       e
(y)e  |angle\      e
   m  |      \     d
   e  |       \
   n  |        \
   t  |         \
      |__________\
      x movement
        (x)

Die Geschwindigkeit ist jedoch so hoch, wie der Feind ist, und Sie können bestimmen, wie viel er sich in x-Richtung und wie viel in y-Richtung bewegen soll, indem Sie die Sünde oder den cos des Winkels nehmen und mit der Geschwindigkeit multiplizieren. Weil...

 sin(a) = x / speed

So:

 x = speed * sin(a)

Und:

cos(a) = y / speed

So:

y = speed * cos(a)

In Ihrem Beispiel moveForward(90)würde sich ergeben speed * sin(90)oder speed * 1in x-Richtung und speed * cos(90)oder 0in y-Richtung (Es sollte sich wie angegeben nach rechts bewegen). Damit sollten Sie im grundlegenden Sinne beginnen.

Allgemein machen:

moveForward(float angle)
{
    x += speed * sin(angle);
    y += speed * cos(angle);
}
Kevin DiTraglia
quelle
Ahh, das ist viel einfacher als ich es mir vorgestellt habe, vielen Dank :)
Shaun Wild
Ich bin mir ziemlich sicher, dass Sie y und x wechseln müssen. sin (alpha) = b / c.
JCora
@Bane es stimmt mit der Zeichnung überein, die ich SOH-CAH-TOA gemacht habe, sin ist entgegengesetzt zu Hypotenuse, die in der Zeichnung x / Geschwindigkeit ist. Wenn der Winkel auf der anderen Seite des Dreiecks wäre, würde er umgekehrt (und wenn das für den Zweck des Spieldesigns praktischer ist, könnte ich es ändern, aber ich denke, es ist alles willkürlich).
Kevin DiTraglia
Ich bin auf meinem Handy, daher war es ziemlich schwer, das zu interpretieren. Ich habe gerade die Formeln
überflogen
Das ist ein wirklich schönes Dreieck, das du da hast. +1
Bro Kevin D.
3

Die andere Antwort ist ab sofort falsch. Um sich basierend auf einer Drehung korrekt entlang einer Ebene zu bewegen, gehen Sie wie folgt vor:

posX += Math.cos(rotation) *  forwardSpeed + Math.sin(rotation) * strafeSpeed;
posY -= -Math.cos(rotation) * strafeSpeed + Math.sin(rotation) * forwardSpeed;

Ich würde jedoch empfehlen, eine Variable für cos / sin zu erstellen, die Sie nur aktualisieren, wenn sich die Drehung ändert, damit Sie sie nicht viermal pro Tick berechnen.

Die Geschwindigkeitsgeschwindigkeit würde sich von einer Seite zur anderen bewegen, die Vorwärtsgeschwindigkeit, um sich entlang Ihrer Rotation vorwärts zu bewegen.

edit: tesselode macht dasselbe, außer dass er keine seitliche Bewegung hat.

Die 8 Bits
quelle
2

Sie sagten, Update-Ticks, also gehe ich davon aus, dass Sie keine variable Bildrate haben. Wenn ja:

x + = Geschwindigkeit * math.cos (Winkel)

y + = Geschwindigkeit * math.sin (Winkel)

Wenn Sie eine variable Bildrate verwenden, müssen Sie auch mit der Deltazeit multiplizieren.

tesselode
quelle