Movimiento suave en un juego basado en fichas

8

¿Cómo podemos hacer que nuestro personaje se mueva suavemente a través de las fichas? Se mueve azulejo por azulejo, pero eso no parece profesional. Además, cuando mantiene presionadas las teclas de flecha, se desliza por la pantalla. ¿Cómo podemos evitar que eso suceda?

leo882
fuente
Estás usando enteros para el movimiento del jugador. Intenta usar flotadores en su lugar.
Mokosha el
1
Es mejor si reduce su código al mínimo requerido para demostrar / comunicar su problema / pregunta. Además, puede interesarle esta pregunta .
kevintodisco el
1
Eliminé las partes innecesarias de tu pregunta. Es mejor llegar al punto y no agregar código adicional u otra pelusa.
MichaelHouse

Respuestas:

6

El movimiento suave se puede lograr de varias maneras. Y realmente depende de qué tipo de movimiento quieras permitir.

  • Movimiento todavía restringido a azulejos. Este tipo es el más fácil para hacer cosas como la detección de colisiones y otras comprobaciones de movimiento. Para este tipo de movimiento, simplemente interpolará la posición con el tiempo a medida que haga la transición entre las fichas. Puede ser tan simple como agregar algo como lo siguiente al ciclo de actualización.

Pseudocódigo:

 if(GetDistance(position, targetposition) > minDistance) {
     position = MoveTowards(position, targetposition, deltatime);
 }

Donde MoveTowardssolo toma la posición actual y agrega una parte de la distancia entre esta y la posición objetivo.

  • El movimiento no está restringido a los azulejos. Esto se vuelve mucho más difícil de implementar. Esencialmente, con este método, simplemente almacena la posición y la actualiza a través de la velocidad. Es decir, cambio de posición con el tiempo.

Mantener presionadas las teclas de flecha para mover personajes también se puede implementar de diferentes maneras. Probablemente lo que estás haciendo es algo como:

if(keydown(left))
   tilePosition.X--;

De hecho, esto haría que el personaje se deslice por la pantalla. Ya que estarías actualizando la posición muchas veces por segundo. Una forma un poco mejor de implementar esto sería agregar un retraso. Algo como

if(keydown(left)) {
    if(leftKeyHeldTimer > movementDelay) {
        tilePosition.X--;
        leftKeyHeldTimer = 0;
    } else {
        leftKeyHeldTimer+= deltaTime;
    }
}

Esto agregará un temporizador de retraso y solo actualizará la posición del mosaico cuando movementDelayse haya alcanzado el valor.

MichaelHouse
fuente
0

Puedo identificar dos problemas. El primero se relaciona con el movimiento suave y el segundo se relaciona con la aparición de caracteres en la pantalla.

Para crear un movimiento suave, puede usar una técnica llamada Interpolación lineal o (LERP) para suavizar el movimiento. Básicamente, cómo funciona es entre su punto de partida y su punto final, usted calcula un conjunto de distancias cada vez más pequeñas para emular un movimiento suave y reducir la velocidad a medida que se acerca el punto final.

El ejemplo más simple de esta función sería:

//point1 is the current position, will be starting position on first call
//point2 is the target position
//epsilon is the % of the distance between current and target you want
//to cover per game physics loop (a fixed realworld time based loop).
//The smaller the % the "smoother" the motion.

float lerp(float point1, float point2, float epsilon)
{
    return point1 + epsilon * (point2 - point1);
}

A medida que el personaje se acerca al punto 2, irá disminuyendo gradualmente. Tenga en cuenta que en realidad nunca tocarán el punto 2, sino que se acercarán infinitamente. Debería corregir esto y si el jugador está a menos de una distancia infinitamente pequeña del punto 2, podemos considerar que el jugador está en el punto 2.

El segundo problema que mencionaste está relacionado con tu personaje volando fuera de la pantalla. Este es el resultado de la entrada que se lee cada actualización del bucle del juego combinada con el movimiento instantáneo entre los mosaicos.

Idealmente para resolver esto, en su código debe decidir

  1. Cuánto tiempo real le tomaría al personaje moverse del punto 1 al punto 2.
  2. Configure su Lerp para que se ejecute entre los puntos 1 y dos durante esta duración
  3. Lea la entrada nuevamente una vez que se haya alcanzado el punto 2 para decidir a dónde ir
Ang Li
fuente