Difesa della torre 2D - Un proiettile per un nemico


14

Sto cercando di trovare una buona soluzione per un proiettile per colpire il nemico. Il gioco è la difesa della torre 2D, la torre dovrebbe sparare un proiettile e colpire il nemico garantito.

Ho provato questa soluzione - http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

Il link menzionato per sottrarre l'origine del proiettile e anche il nemico (sottrazione vettoriale). Ci ho provato ma un proiettile segue solo il nemico.

float diffX = enemy.position.x - position.x;
float diffY = enemy.position.y - position.y;

velocity.x = diffX;
velocity.y = diffY;

position.add(velocity.x * deltaTime, velocity.y * deltaTime);

Ho familiarità con i vettori ma non sono sicuro di quali passaggi (operazioni matematiche vettoriali) devono essere fatti per far funzionare questa soluzione.


Risposte:


11

Il tuo ragionamento è stato perfetto: usa un vettore per spostarti dalla mia posizione al mio obiettivo. Questo è lo scopo di un vettore ; hai semplicemente dimenticato la velocità !

La velocità è un vettore: una velocità e una direzione. Tuttavia, se si dimentica di normalizzare il vettore differenza e moltiplicarlo per la velocità del proiettile (uno scalare), in pratica si sta dicendo che se si è vicini al bersaglio (il vettore differenza è piccolo) il proiettile rallenta ; mentre se sei lontano la velocità del proiettile è maggiore.

Questo è il problema di fondo: è necessario calcolare sia la direzione che la grandezza del vettore.


Grazie dell'aiuto. Ho provato a usare lo scalare dopo aver calcolato il vettore delle differenze, sembra che abbia funzionato ma non sembra buono. Ho provato a vedere se calcolo la differenza vettore, normalizzo, quindi scalare la velocità. Sembra meglio adesso. Sì, penso di aver bisogno dei missili homing in questo gioco qualche tempo dopo. Grazie ancora.
Tashu,

1
Questa risposta non ha senso per nessun altro?
BlueRaja - Danny Pflughoeft il

@Fxlll: Ok, penso di vedere cosa stai cercando di dire. C'è molta lanugine non correlata alla risposta all'inizio / alla fine, e sono stato anche confuso dal tuo inglese (che mi rendo conto che probabilmente non è colpa tua) . Ho inviato un suggerimento di modifica per ripulire questa risposta.
BlueRaja - Danny Pflughoeft il

@BlueRaja - Danny Pflughoeft grazie per il tuo sforzo!
FxIII

7

Se il bersaglio si sta muovendo in una direzione costante a un ritmo costante e il percorso del proiettile è in linea retta a un ritmo costante, è possibile utilizzare un'equazione quadratica per prevedere il punto esatto che si intersecheranno e puntare la pistola della torre in quel punto .

Poiché è una certezza che il proiettile colpirà il suo segno e puoi calcolare il tempo esatto che ci vorrà dal fuoco all'impatto, non sarà richiesto alcun rilevamento delle collisioni, semplicemente sparare con la pistola, attendere l'intervallo di tempo calcolato, registrare un colpo.

Ecco il pseudo codice per l'equazione quadratica:

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
{
    t = t2;
}
else
{
    t = t1;
}

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second

Grazie per lo pseudo codice, lo controllerò per vedere come funziona l'equazione quadratica con questa situazione. Grazie ancora.
Tashu,

Il problema è che l'utente può spostarsi verso il proiettile e, appena prima di essere colpito, può allontanarsi dalla traccia del proiettile. In questo caso, questa soluzione sarebbe abbastanza buona?
Martin.

No, come qualificato nella prima frase. Questo non è per tutti i giochi ma per un gioco in cui i bersagli si muovono solo a una velocità costante. Velocità costante significa sia direzione che velocità. Ad esempio, il gioco in stile Defense Grid può utilizzare questo approccio.
Steve H,

3

Devi "prevedere" la posizione degli oggetti quando il proiettile lo raggiungerà. Puoi farlo usando gli oggetti speed / velocity (speriamo che sia costante;)) ed è il vettore direzionale.

Non sono sicuro di quale sia la formula esatta dalla parte superiore della mia testa, ma penso che sia qualcosa del genere:

NewPosition = OldPosition + (Speed ​​* DirectionVector);

Se hai un percorso impostato dovrai ricalcolare quando l'oggetto cambia direzione. Usa questa NewPosition come vettore nemico.posizione e il proiettile dovrebbe colpire l'oggetto senza "effetto homing". L'homing si verifica a causa del fatto che l'oggetto nemico si è mosso da quando è stato calcolato il vettore originale, può raggiungerlo solo quando un oggetto sta viaggiando in una direzione abbastanza a lungo.

Spero che sia di aiuto :)


3
Oppure puoi imbrogliare e colpire automaticamente, quindi utilizzare lo sprite in movimento come feedback visivo. O semplicemente sparare i proiettili a 50000 ² mph.
Jonathan Connell,

1

Puoi evitare di usare la radice quadrata e la potenza di 2.

var distX:Float = target.x - x;
var distY:Float = target.y - y;
_velX = distX / timeTravel;
_velY = distY / timeTravel;

// Take out if you want a nice slow down as approaches effect.  
timeTravel -= 1.0; // make sure u have a positive timeTravel.
x += _velX;
y += _velY;

if (distX < 0)
    distX = -distX;

if (distY < 0)
    distY = -distY;

if (_velX < 0)
    _velX = -_velX;

if (_velY < 0)
    _velY = -_velY;

// Should both snap @ the same time.
if (distX < _velX)
x = target.x; // snap & see what happens.

if (distY < _velY)
y = target.y; // snap & see what happens.

// TODO: call your onHitTarget here ...
// Hopefully this shall provide 10x the performance 
// of using Math.sqrt and all the extra multiplications.

È tutto scritto dalla memoria. A proposito, usa gli elementi che funzionano: testalo riga per riga se sei nuovo in questo. Float è il numero in AS3.

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.