Galaga Paso 02: Velocidad constante

Creación de juegos desde cero: C# y SFML

Con la implementación realizada en el Paso01, ya tenemos un juego muy simple que permite mover a nuestro jugador (una bola azul) por la pantalla. Toda la magia de este movimiento reside en el bucle principal del juego, un bucle infinito (al menos hasta que la ventana se cierre) que se encarga de obtener las entradas, calcular las nuevas posiciones y redibujar la pelota en su nueva ubicación.

El problema surge con la velocidad de la pelota. Independientemente de que podamos hacer que avance más o menos pixeles en cada actualización, lo que está claro es que el número de veces que se ejecutará el bucle en un determinado tiempo va a ser muy variable.

Pensemos en dos casos básicos:

  • Por razones de jugabilidad quiero que la sensación de velocidad sea la misma independientemente de la máquina en la que estoy jugado. Tal y como está ahora mismo diseñado el bucle, en ordenadores más potentes la pelota se moverá más rápido que en ordenadores que no lo sean tanto.
  • Por otra parte, puede ser que ese mismo problema aparezca en un mismo ordenador en función de la carga de trabajo instantánea que tenga que realizar. Por ejemplo, los cálculos para renderizar sean muy costosos en cierto momento, lo que implica que cada ciclo del bucle tarde mucho más tiempo en ejecutarse.

La solución consiste en rediseñar el bucle para que tenga en cuenta la diferencia de tiempo que ha transcurrido entre cada iteración.

Vamos a cargar el código del segundo paso. Para ello, otra vez desde el terminal y desde la carpeta donde está el proyecto, hacemos git checkout Paso002:

C:\Users\alfredo\Documents\Visual Studio 2015\Projects\Galaga-SFML.Net [master]> git checkout Paso002

La solución consiste en hacer que el movimiento dependa del tiempo en el que se vuelve a pasar por el bucle. Es decir, actualizaremos la posición del jugador en función del tiempo que haya pasado desde la última vez que se calculo su posición.



¿Y cómo sabremos la nueva posición del jugador? Pues de una manera muy simple: teniendo en cuenta la velocidad (px/s) a la que queremos que se mueva. Así, para una velocidad constante,  aplicando la fórmula del movimiento lineal e=v*t (espacio es igual a velocidad por tiempo) y sabiendo cuanto tiempo ha pasado desde la última actualización, sabremos que distancia ha recorrido.

Para implementarlo modificamos la fución update para que tenga en cuenta el tiempo transcurrido desde la ultima actualización y que calcule la nueva posición en función de él

// actualiza el estado del mundo en función del tiempo transcurrido 
// desde la última actualización
private void update(SFML.System.Time time)
{
      SFML.System.Vector2f speed = new Vector2f(0f, 0f);

      if (_IsMovingUp)
	speed.Y -= _playerSpeed;
      if (_IsMovingDown)
        speed.Y += _playerSpeed;
      if (_IsMovingLeft)
        speed.X -= _playerSpeed;
      if (_IsMovingRight)
        speed.X += _playerSpeed;

      // espacio = velocidad * tiempo. El nuevo espacio se añade a 
      // la posición previa
      // del tiempo se obtienen los segundos ya que la velocidad se
      // da en px/s
      _player.Position += speed * time.AsSeconds(); 
}

Por otra parte en el bucle tendremos que calcular el tiempo transcurrido entre cada iteración y pasarlo a la función update.

public void run() {
            
     Clock clock = new Clock();
     SFML.System.Time deltaTime;
            
     // Game Loop
     while (_window.IsOpen)
     {
        // para cada uno de los ciclos reinicio el reloj a cero 
        // y devuelvo el tiempo que ha pasado desde el inicio
        deltaTime = clock.Restart();

        // Procesamos eventos
        _window.DispatchEvents();

        update(deltaTime);
        render();
     }
  }    

Por último de asignamos en el constructor una velocidad en px/s al jugador.

   _playerSpeed = 25;           // 25 px/s

De esta manera conseguimos que, independientemente del equipo o de su carga de trabajo, la velocidad aparente de nuestro jugador sea constante.

Bibliografía

[R1] SFML. Game Development

Tags: , , , , ,

Compartir en Facebook Compartir en Twitter

Un comentario a “Galaga Paso 02: Velocidad constante”

  1. jamaro dice:

    Ya arranca esto, y ya estamos esperando a aprender más.
    ¡Suerte con LOS PROYECTOS!

Dejar un comentario

XHTML: Puedes usar estos tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>