Perché il mio oggetto si sposta più velocemente di 45 gradi rispetto a 90 gradi?


32

Ho oggetti nel mio gioco che si muovono più velocemente a 45 gradi e poi a 90 gradi.

Ogni oggetto ha

  • Posizione del punto (x, y)
  • Direzione Vector2D (x, y)
  • Int velocità

E quello che faccio durante un aggiornamento è che la nuova posizione viene calcolata come:

position.x += direction.x * speed
position.y += direction.y * speed

Come posso correggere questo? Voglio che si muova con la stessa velocità con qualsiasi angolazione.


8
Normalizza il tuo vettore di direzione prima dell'uso; problema risolto.
rallentato fino al


E se stai usando l'input dell'utente per controllare questo oggetto, fai attenzione a bloccare le direzioni 12,3,6,9 come spiegato qui per gli sviluppatori XNA: xona.com/2010/05/03.html . Potrebbe essere qualcosa che desideri (come in un gioco di ruolo) o meno (come in un gioco in stile Geometry Wars).
Xonatron,

nel vecchio gioco Descent , questa era una caratteristica .
J. Holmes,

@ 32bitkid Sì, vedi anche Doom straferunning
bobobobo,

Risposte:


55

Questo può essere spiegato con il Teorema di Pitagora , che è la seguente formula:

a² + b² = c²

Nel tuo caso, quando ti sposti a destra, stai usando (x: 1, y: 0) che ci dà

c² = 1 + 0 = 1
c = sqrt(1) = 1.00

Quando ci si sposta verso l'alto e verso destra, si sta utilizzando (x: 1, y: 1) che ci dà

c² = 1 + 1 = 2
c = sqrt(2) = 1.41

Come puoi vedere, la lunghezza in diagonale è più lunga della lunghezza sugli assi cardinali.

Come altri hanno già detto, dovresti semplicemente normalizzare il tuo vettore di direzione. Se usi XNA, è fatto così:

var normalizedDirection = direction;
normalizedDirection.Normalize();
position += normalizedDirection * speed

Ti sto dando +1 per il tuo aiuto nella mia domanda :)
Martin.

12

Normalizza il tuo vettore di direzione prima dell'uso.

Come spiegato da MindWorX, questo può essere semplicemente compreso, se sei preoccupato per i tuoi vettori di direzione che potrebbero darti dolore, assicurati che siano vettori di unità (magnitudine / lunghezza di 1).

Length(Vector2(1, 1)) == 1.4142135623730951 // first hint of grief
Length(Vector2(1, 0)) == 1

Vector2(1, 1) * 2 == Vector2(2, 2)
Vector2(1, 0) * 2 == Vector2(2, 0)

Length(Vector2(2, 2)) = 2.8284271247461903 // second hint
Length(Vector2(2, 0)) = 2

Se normalizzato:

normal(Vector2(1, 1)) == Vector2(0.707107, 0.707107)
Length(Vector2(0.707107, 0.707107)) == 1 // perfect

14
Non è una risposta utile. Se l'interrogante sapesse cosa significava "normalizzare il tuo vettore di direzione", non avrebbe posto la domanda.
Kristopher Johnson,

@KristopherJohnson non era chiaro che l'interrogante non sapeva come normalizzare un vettore. Anche se l'interrogante sembra abbastanza intraprendente da non importare comunque.
rallentato fino al

2
@KristopherJohnson: se l'interrogante non sapeva cosa significhi "normalizzare il tuo vettore di direzione", deve solo digitarlo su google, aggiungere il nome della sua lingua e ottenere un codice con spiegazioni.
Sdraiati Ryan il

6

Come stai calcolando la tua direzione? Se lo è 45 gradi (1,1), sarà sicuramente più veloce di 90 gradi (1,0).

Ti suggerisco di usare qualcosa del genere:

direction.x = Math.Cos(angleInRadians);
direction.y = Math.Sin(angleInRadians);

Per ottenere l'angolo in radianti, dovrai moltiplicare i tuoi gradi con, PI / 180o ancora meglio, usare MathHelper. Per esempio.

angleInRadians = 45.0 * Math.PI / 180.0; // first method
angleInRadians = MathHelper.ToRadians(45f); //second method

6

Jason,

Invece di avere tre attributi di oggetto,

  • Posizione del punto (x, y)
  • Direzione Vector2D (x, y)
  • Int velocità

spesso è molto più semplice combinare la direzione e la velocità in un vettore di velocità. Quindi hai solo due attributi,

  • Posizione del punto (x, y)
  • Velocità Vector2D (x, y)

Posizione di aggiornamento

Quando è necessario aggiornare la posizione dell'oggetto, è semplice come:

position.x += velocity.x * Δt;
position.y += velocity.y * Δt;

dov'è il Δttuo delta temporale - o differenza di tempo - o passo temporale.

Aggiornamento di posizione e velocità

È anche molto facile in questo modo gestire l'accelerazione (come per esempio dalla gravità). Se hai un vettore di accelerazione, puoi aggiornare la velocità e la posizione insieme in questo modo:

position.x += (velocity.x * Δt) + (0.5 * acceleration.x * Δt * Δt);
position.y += (velocity.y * Δt) + (0.5 * acceleration.y * Δt * Δt);

velocity.x += acceleration.x * Δt;
velocity.y += acceleration.y * Δt;

(Questa è fondamentalmente la formula s = vt + ½at² da Physics 101.)

Applicare una velocità

Se si desidera applicare una determinata velocità in una direzione normalizzata, è possibile impostare la velocità in questo modo:

velocity.x = normalizedDirection.x * speed;
velocity.y = normalizedDirection.y * speed;

Derivare una velocità

E se hai bisogno di fare il contrario - derivando la velocità e la direzione da un dato vettore di velocità - puoi semplicemente usare il teorema di Pitagora o il .Length()metodo:

speed = velocity.Length();

E una volta che la velocità è nota, la direzione normalizzata può essere calcolata dividendo la velocità per la velocità (facendo attenzione a evitare di dividere per zero):

if (speed != 0) {
    normalizedDirection.x = velocity.x / speed;
    normalizedDirection.y = velocity.y / speed;
} else {
    normalizedDirection.x = 0;
    normalizedDirection.y = 0;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.