/ / Atascado en hacer un motor de movimiento de juego 2D - 2d

Atascado en hacer un motor de movimiento de juego 2D - 2d

Estoy haciendo un motor de movimiento para mi juego 2D de arriba hacia abajo, pero me atasqué tratando de resolver el siguiente problema:

  • El jugador puede moverse usando las teclas de flecha, que te aceleran en las direcciones respectivas. Hay fricción por lo que dejas de moverte después de soltar las teclas, aunque no al instante.
  • Cuando sostienes dos teclas perpendiculares, aceleras en esta dirección de 45 ° a la misma velocidad que lo harías en un eje
  • Hay una velocidad máxima que encima de usted no puede acelerar caminando, esto también limita tu velocidad máxima de marcha, obviamente. Puede quedar eliminado, y por lo tanto, superar esta velocidad.
  • Si te mueves más rápido que max. velocidad de paso, puede disminuir la velocidad más rápido si mantiene las teclas en la dirección opuesta (s)

Pseudocódigo para el primer punto, sin fricción:

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;
}

Puedo resolver la fricción (obteniendo la longitud deel vector de movimiento, reduciéndolo por la fricción, proyectándolo hacia atrás con la misma relación x: y), sin embargo, no puedo ajustar mi cabeza para hacer que la velocidad máxima se complete.

Intenté una solución para no permitir que el jugadorcaminar por encima de maxSpeed, pero esto viola el punto 4. Además, tuvo el desagradable efecto secundario, que cuando te movías en MaxSpeed ​​hacia la izquierda y comenzaste a presionar hacia abajo, la dirección del movimiento no se modificó o apenas cambió.

Entonces comencé a pensar en numerosos productos, diferencias y otras cosas con los vectores, pero en su mayoría no pude seguirlo o tuve problemas iniciales.

Entonces, en conclusión, ¿podría alguien explicar un sistemaque cumple con todos los puntos anteriores, o apunta a un artículo que explica cómo un sistema como este podría implementarse? No te preocupes por sugerir algo complejo, puedo captar incluso los conceptos difíciles dados un tiempo.

¡Gracias por tu ayuda!

Respuestas

1 para la respuesta № 1

Perdón por no haber pensado en esto por más de un día, pero logré resolverlo, y no son dos líneas de código. (Aun así, gracias a todos por las ideas)

Como soy perezoso y cansado, no lo cambiaré a pseudocódigo, excepto los siguientes dos métodos:

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

Y el código (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;
}

Podría ser más corto, podría estar un poco más optimizado, pero funciona. Espero que esto ayude a cualquiera que tropiece con este problema en el futuro.


0 para la respuesta № 2

Añadir a la parte inferior:

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

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

Dónde int signo (x) { si x <0 return -1; }


0 para la respuesta № 3

Sugeriría asociar una velocidad específica con el jugador además de la posición, y solo verificar esa velocidad contra maxSpeed ​​cuando se presionen las teclas de flecha.

Si la velocidad EXCEDE la velocidad máxima, pero se presionan las teclas de flecha del lado opuesto, entonces mantendrá la velocidad actual por encima de la velocidad máxima y simplemente aplicará la aceleración negativa.