44. Un personaje que salta en vertical.

Hacer que el personaje puede "saltar" supone varios cambios:

  • Por una parte, cuando haya comenzado a saltar deberá moverse solo, al igual que ocurría cuando caía, lo que implica que necesitaremos un método "Saltar", que comience la secuencia del salto, pero también usaremos el método "Mover", que se encargará de continuar esa secuencia (cuando corresponda).
  • Además, la secuencia de salto será más complicada que (por ejemplo) el movimiento "normal" del personaje o que su caída: el salto (hacia los lados)suele ser un movimiento parabólico. Además, en muchos juegos, el personaje salta en vertical si sólo se pulsa la tecla de saltar, y lo hace de forma parabólica a derecha o izquierda si se pulsa la tecla de salto junto con una de las teclas de dirección.

Una primera forma de conseguirlo sería usar realmente la ecuación de la parábola, pero suele ser más eficiente y más versátil "precalcular" la secuencia de movimientos y guardarlos en un array. Realmente, ni siquiera es necesario hacer "con cálculos reales", sino que podemos imitar la aceleración de la gravedad, preparando movimientos más rápidos (más "largos") al principio y al final de la parábola, y movimientos más lentos en el punto medio, algo como:

int[] pasosSaltoArriba = {
    -8, -8, -8, -6, -6, -5, -5, -4, -4, -4, -3, -3, -2, -1, -1, 0, 0, 0,
    0, 0, 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 8, 8, 8 };

Esa es la secuencia de salto casi completa: falta tener en cuenta que cuando el personaje deja de avanzar en forma parabólica, ya sea porque realmente llegue a su destino o porque choque un obstáculo, deberíamos comprobar si tiene suelo por debajo, para que caiga en caso contrario.

En este primer acercamiento, nos centraremos en que el personaje salte (y caiga, claro) en vertical, y en el próximo apartado lo ampliaremos para que también salte hacia los lados.


Vamos con ello...

En primer lugar, necesitaremos un método "Saltar" dentro del personaje, que pondrá en marcha la secuencia de salto:

// Hace que el personaje comience a saltar
public void Saltar()
{
    saltando = true;
}

(Obviamente, ese "saltando" será un atributo privado del Personaje)

Por otra parte, dentro de la "Partida", habrá que comprobar si se pulsa una cierta tecla (por ejemplo, Espacio) para llamar a ese método:

public void ComprobarTeclas()
{
    ...
 
    if (Hardware.TeclaPulsada(Hardware.TECLA_ESP) || Hardware.JoystickPulsado(0) )
        miPersonaje.Saltar();
 
}

Además, el método "Mover" del personaje, tendrá que comprobar si está saltando, y hacer algo en ese caso. Una primera aproximación podría ser disminuir en una unidad la posición "y" del personaje, de modo que cuando pulsemos Espacio, empezaría a moverse lentamente hacia arriba hasta que saliera de la pantalla para nunca más volver...

public void Mover()
{
    if (saltando)
        y--;
 
    else
        if (miPartida.EsPosibleMover(x,y+incrY,
                x+ancho,y+alto+incrY))
            Caer();
}

Por supuesto, lo anterior no es cierto del todo: en cuanto pulsemos ESC, termina la partida y podemos volver a empezar... o incluso salir del juego para hacer que el salto sea un poco más real.

En cuanto hayamos comprobado que todo funciona hasta aquí, podemos utilizar un array con lo que se tiene que desplazar en cada "fotograma" de la secuencia de salto, como ya habíamos comentado más arriba. Nos vendrá bien tener también un contador que nos permitar saber en cual de todos esos "pasos" nos encontramos actualmente:

// Atributos
bool saltando;
int[] pasosSalto =
    { -10, -10, -8, -8, -6, -6, -4, -2, -1, -1, 0,
      0, 1, 1, 2, 4, 6, 6, 8, 8, 10, 10  };
int pasoSaltoActual;

De modo que un "Mover" más real debería tomar el siguiente de esos "saltos" para aplicárselo al personaje, reiniciar toda la secuencia cuando ha terminado, y, a partir de entonces (pero no antes) comprobar si debe caer:

public void Mover()
{
    if (saltando)
    {
        // Siguiente incremento del salto
        y += pasosSalto[pasoSaltoActual];
        // Si no ha terminado la secuencia
        if (pasoSaltoActual < pasosSalto.Length-1)
            pasoSaltoActual++; // preparo el siguiente
        // Y si ha terminado, reinicio
        else
        {
            pasoSaltoActual = 0;
            saltando = false;
        }
    }
    else
        if (miPartida.EsPosibleMover(x, y + incrY,
                x + ancho, y + alto + incrY))
            Caer();
}

Ejercicio propuesto: Aplica todos estos cambios. Comprueba qué ocurre si se pulsa la tecla hacia arriba mientras el personaje está saltando... y soluciónalo.