28 diciembre 2008

Remake (parcial) de Fruity Frank... 23 - Un movimiento del personaje más suave

Para hacer que el movimiento del personaje sea más suave, la solución puede ser no sumar 40 a su coordenada X cada ver que se pulse la tecla "derecha" (por ejemplo), sino aumentar poco a poco hasta llegar a esos 40. Aun así, cuando pulsemos la tecla "derecha", su posición deberá seguir aumentando durante varios "fotogramas" del juego, por lo que podemos usar una variable booleana para comprobar si estamos en medio de un movimiento:

Algunos de los atributos, que antes eran
    // El personaje se moverá de 1 en 1 casilla,
// cuando se pulse cada tecla
incrX = 41;
incrY = 34;

ahora podrían ser
    // El personaje se moverá de varios en varios pixeles
// cuando se pulse cada tecla
anchoCasilla = 41;
altoCasilla = 34;
incrX = 4;
incrY = 4;
enMovimiento = false;

Y la rutina de mover a la derecha, que antes era
    public  void MoverDerecha()
{
if (miJuego.GetNivelActual().EsPosibleMover( (short) (x+incrX), y) )
{
CambiarDireccion(DERECHA);
SiguienteFotograma();
x += incrX;
miJuego.GetMarcador().IncrPuntuacion(
miJuego.GetNivelActual().PuntosMover( x, y ));
}
}

ahora podría modificarse así
    public  void MoverDerecha()
{
if (enMovimiento) // Si ya está en movimiento, salgo
return;
if (miJuego.GetNivelActual().EsPosibleMover( (short) (x+anchoCasilla), y) )
{
CambiarDireccion(DERECHA);
enMovimiento = true;
incrXActual = incrX; incrYActual = 0;
xFinal = (short)(x+anchoCasilla); yFinal = y;
miJuego.GetMarcador().IncrPuntuacion(
miJuego.GetNivelActual().PuntosMover( (short) (x+anchoCasilla), y ));
}
}

Es decir, pone en marcha el movimiento (enMovimiento = true), calcula los incrementos que se van a usar para desplazarse y la posición final, suma puntos... pero deja los movimientos intermedios a otra función, que podría llamarse "Mover", que se llamaría desde "SiguienteFotograma" (en el juego), y que podría ser así:
    public new void Mover()
{
if (!enMovimiento) // Si no está en movimiento, no hay que hacer nada
return;
SiguienteFotograma();
x += incrXActual; // Aumento otro poco la posición
y += incrYActual;
// Compruebo si me paso (ancho y salto pueden no ser proporcionales)
if ((incrXActual > 0 ) && (x >= xFinal))
x = xFinal;
if ((incrXActual < 0 ) && (x <= xFinal))
x = xFinal;
if ((incrYActual > 0 ) && (y >= yFinal))
y = yFinal;
if ((incrYActual < 0 ) && (y <= yFinal))
y = yFinal;
// Compruebo si ya he avanzado toda la casilla, para dejar de mover
if ((x == xFinal) && (y == yFinal))
enMovimiento = false;
}

Esta función aumenta la posición según los incrementos previstos, comprueba que no nos hayamos pasado (porque el incremento puede no ser un divisor exacto del ancho de la casilla), y marca el movimiento como terminado cuando corresponda.


De paso, en esta versión he mejorado un poco los gráficos, conservando la estética inicial y los 16 colores originales, pero con puntos algo más pequeños para que las imágenes sean más nítidas. Las imágenes originales siguen estando disponibles en una subcarpeta, de forma que en la versión definitiva del juego se podría permitir incluso al usuario escoger si quiere usar los gráficos originales del juego o una estética ligeramente revisada.

Como es habitual, todo el fuente del proyecto está en: code.google.com/p/fruityfrank