/ / Bloccato nel creare un motore di movimento di gioco 2D - 2d

Bloccato nel creare un motore di movimento di gioco 2D - 2d

Sto facendo un motore di movimento per il mio gioco 2D top-down, ma mi sono bloccato cercando di risolvere il seguente problema:

  • Il giocatore può muoversi usando i tasti freccia, che ti accelerano nelle rispettive direzioni. C'è attrito quindi smetti di muoverti dopo aver rilasciato i tasti, anche se non istantaneamente.
  • Quando si tengono due tasti perpendicolari, si accelera in questa direzione di 45 ° alla stessa velocità che si avrebbe su un asse
  • C'è una velocità massima che sopra non puoi accelerare camminando, questo limita anche la tua massima velocità di camminata, ovviamente. Puoi essere buttato via, e quindi superare questa velocità comunque.
  • Se ti muovi più velocemente del massimo. velocità della camminata, puoi rallentare più velocemente se tieni premuto i tasti nella direzione opposta

Pseudocodice per il primo punto, senza attrito:

gameTick(){

tempX += LeftKeyHeld ? -1 : 0;
tempX += RightKeyHeld ? 1 : 0;
tempY += UpKeyHeld ? -1 : 0;
tempY += DownKeyHeld ? 1 : 0;
ratio = 0.71;

if( |tempX| == |tempY| ) {
tempX =tempX* ratio;
tempY =tempY* ratio;
}
player.x += tempX;
player.y += tempY;
}

Posso risolvere l'attrito (ottenendo la lunghezza diil vettore di movimento, riducendolo per l'attrito, proiettandolo indietro con lo stesso rapporto x: y), tuttavia, non riesco a capire come ottenere il maxSpeed.

Ho provato una soluzione di non permettere al giocatore dicammina a tutto quando sopra maxSpeed, ma questo viola il punto 4. Inoltre, ha avuto il brutto effetto collaterale, che quando ti sei spostato a MaxSpeed ​​a sinistra, e hai iniziato a premere verso il basso, la direzione del movimento non è cambiata.

Poi ho iniziato a pensare a numerosi prodotti, differenze e altre cose con i vettori, ma per lo più non potevo seguirlo più o incappare in problemi precoci.

Quindi, in conclusione, qualcuno potrebbe spiegare un sistemache soddisfa tutti i punti sopra, o indica un articolo che spiega come un sistema come questo potrebbe essere implementato? Non preoccuparti di suggerire qualcosa di complesso, riesco a cogliere concetti anche difficili, dato un po 'di tempo.

Grazie per l'aiuto!

risposte:

1 per risposta № 1

Scusa se non ti ho lasciato pensare a questo per più di un giorno, ma sono riuscito a risolverlo, e non in due righe di codice. (Anche se grazie ancora a tutti per le idee)

Perché sono pigro e stanco, non lo cambio in pseudocodice, tranne i seguenti due metodi:

updateGame(){
player.walk();
player.move();
}
player.move(){
player.x += player.speedX
player.y += player.speedY
}

E il codice (java):

public void walk() {
float tempX = 0;
float tempY = 0;
float accelX;
float accelY;
float nextSpeedX;
float nextSpeedY;
float nextSpeed;
float speed;
tempX += walkLeft ? -1 : 0;
tempX += walkRight ? 1 : 0;
tempY += walkUp ? -1 : 0;
tempY += walkDown ? 1 : 0;

if (Math.abs(tempX) == Math.abs(tempY)) {
tempX = (float) tempX * rat;
tempY = (float) tempY * rat;
}

accelX = tempX * (float) runSpeed;
accelY = tempY * (float) runSpeed;
speed = (float) Math.sqrt(speedX * speedX + speedY * speedY);
nextSpeedX = speedX + accelX;
nextSpeedY = speedY + accelY;
nextSpeed = (float) Math.sqrt(nextSpeedX * nextSpeedX + nextSpeedY * nextSpeedY);

if (nextSpeed > maxSpeed) { //can"t accelerate by running
if (nextSpeed > speed) {  //wants to accelerate
if (speed > maxSpeed) {  //the current speed is larger than maximum.
float diff = (float)(speed / nextSpeed);
float greenX = nextSpeedX*diff;
float greenY = nextSpeedY*diff;
accelX = greenX-speedX;
accelY = greenY-speedY;
} else { //speed <= maxspeed
float diff = (float)(maxSpeed / nextSpeed);
float greenX = nextSpeedX*diff;
float greenY = nextSpeedY*diff;
accelX = greenX-speedX;
accelY = greenY-speedY;
}
} else { //wants to slow! allow it!
//acceleration doesn"t need to be changed
}
} else { //no problem, allow it!
//acceleration doesn"t need to be changed
}
speedX += accelX;
speedY += accelY;
}

Potrebbe essere più breve, potrebbe essere un po 'più ottimizzato, ma funziona. Spero che questo possa aiutare chiunque si imbatta in questo problema in futuro.


0 per risposta № 2

Aggiungi alla fine:

 If (|tempX|>maxSpeed)
tempX=maxSpeed*sign(tempX);

If (|tempY|>maxSpeed)
tempY=maxSpeed*sign(tempX);

Dove segno int (x) { se x <0 ritorno -1; }


0 per risposta № 3

Ti suggerisco di associare una velocità specifica con il giocatore oltre alla posizione, e di controllare solo la velocità rispetto a maxSpeed ​​quando vengono premuti i tasti freccia.

Se la velocità supera la velocità massima, ma vengono premuti i tasti freccia dal lato opposto, si mantiene la velocità attuale al di sopra di maxSpeed ​​e si applica semplicemente l'accelerazione negativa.