Desarrollo de Juegos de Tablero (3):
Animación del personaje y/o fichas
(2º parte)
En esta 2º parte, vamos a ver un método mejor para animar los personajes o fichas en nuestro juego. Para ello vamos a trabajar con la misma imagen "jacinto" que teníamos anteriormente, pero nuestro código (esta vez usando clases), se va a encargar de hacernos el trabajo más fácil. Observar este esquema:
Cada Sprite (o cuadro) que es la pequeña imagen que forma la animación, lo tenemos en una regilla, donde podemos identificarla por el lugar de la fila y columna que ocupa en la imagen completa.
Crearemos las siguientes clases:
imagen: encargada de leer el archivo gráfico, y de dibujar solo el sprite actual (o cuadro indicado)
controlAnimacion: encargada de llevar el contador de la animación, ya que le pasaremos una lista de sprites (o cuadros) que forman la animación, y internamente llevará un contador para saber cual sprite es el actual.
animacion: esta clase contiene a dos objetos, uno tipo imagen y otro controlAnimacion, y funciona como una "fachada" para que el programador no tenga que usar directamente a las clases de más bajo nivel (imagen y controlAnimacion).
Clase: | Imagen | |||||
métodos | Parámetros | Descripción | ||||
_new() | ||||||
ruta | indica la ruta donde esta la imagen | |||||
filas | indica las filas de sprites que tiene la imagen | |||||
columnas | indica las columnas de sprites que tiene la imagen | |||||
dibujar() | ||||||
cuadro | numero que indica el sprite que se tendrá que dibujar | |||||
posx | coordenada X donde se dibujará sprite | |||||
posy | coordenada Y donde se dibujará el sprite | |||||
SpriteAltoAncho() | ||||||
devuelve el ancho y largo del Sprite (según el numero de filas y columnas) | ||||||
Usa una variable point, para devolver los valores: | ||||||
x es el ancho e y es el alto | ||||||
Clase: | ControlAnimacion | |||||
métodos | Parámetros | Descripción | ||||
_new() | ||||||
Frames | cadena de texto, que indica que sprite hace el movimiento: “1,2,3,2” | |||||
cuadro() | ||||||
Devuelve el numero de sprite actual | ||||||
es_primer_cuadro() | ||||||
Devuelve Verdadero o falso, si el contador de sprite paso es 0 o no | ||||||
avanzar() | ||||||
Avanza el contador interno paso, y si llega al último vuelve a 0 | ||||||
Clase: | Animacion | |||||
métodos | Parámetros | Descripción | ||||
_new() | ||||||
ruta | indica la ruta donde esta la imagen | |||||
filas | indica las filas de sprites que tiene la imagen | |||||
columnas | indica las columnas de sprites que tiene la imagen | |||||
Frames | cadena de texto, que indica que sprite hace el movimiento: “1,2,3,2” | |||||
Este constructor, crea internamente dos objetos (itmp y ControlAnimaciónTmp), con los datos de los parametros pasados. | ||||||
animar() | ||||||
llama al método avanzar, del objeto interno ControlAnimacionTmp | ||||||
pasoApaso | ||||||
x | coordenada X donde se dibujará sprite | |||||
y | coordenada Y donde se dibujará el sprite | |||||
Se encarga de dibujar la imagen y avanzar la animación. | ||||||
SpriteAltoAncho() | ||||||
devuelve el ancho y largo del Sprite (según el numero de filas y columnas) | ||||||
Usa una variable point, para devolver los valores: | ||||||
x es el ancho e y es el alto | ||||||
Esta clase esta compuesta por dos objetos: | ||||||
Private itmp As Imagen | ||||||
Private ControlAnimacionTmp As ControlAnimacion | ||||||
vease patrón de diseño Facade: | ||||||
http://jsbsan.blogspot.com.es/2013/11/patron-facade-fachada-ejemplo-de.html |
A la hora de dibujar, también he cambiado algunas cosas:
Uso un drawingArea, que tiene el evento _draw, donde coloco los objetos a dibujar (los personajes, explosiones, etc):
En el video se muestra varias animaciones ejecutandose a la vez:Public Sub DrawingArea1_Draw()figuraAnimada.dibuja() 'es una pieza en el tablero, que podemos mover.
ani1.pasoApaso(100, 100) 'es una animación simple
ani2.pasoApaso(200, 200)'es una animación simple
ani3.pasoApaso(200, 100)'es una animación simple
ani4.pasoApaso(100, 200)'es una animación simple
ani5.pasoApaso(300, 100)'es una animación simple
End
Esto permite animar a la vez varias figuras y animaciones que haya en dicho procedimiento. Además ese evento _Draw es llamado cada cierto tiempo por un temporizador (timer1), que se encarga de actualizar también la posición de los figuras :
En la clase PiezaAnimada, el método .actualizaPosicion() se va calculando la posición de la figura, mientras se mueve entre casilla y casilla.Public Sub Timer1_Timer()
figuraAnimada.actualizaPosicion() 'actualizamos la posicion de la ficha. Internamente si no hay cambios se dibujara en el mismo sitio
DrawingArea1.Refresh()
End
Public Sub actualizaPosicion()
If casillaFinal = casillaInicial Then Return 'a llegado a la casilla de destino
contadorA += 1pto.x = casillaInicialX + difx * contadorApto.y = casillaInicialY + dify * contadorA
If casillafinalX = pto.x And casillafinaly = pto.y ThencasillaInicial = casillaFinalEndif
End
Anteriormente el método .mueve() ha calculado cual es el incremento de X (difx) y el incremento de Y (dify), que se necesita para ir de la casilla actual a la casilla que se le haya indicado.
En el siguiente video vemos como se desplaza el personaje, a la vez que se hay otras animaciones reproduciendose:
Enlace de descarga del código fuente: alojado en drive google
El siguiente paso es implementar varios "estados" (osea varias animaciones a un mismo personaje/ficha), por ejemplo, cuando este parado, cuando vaya de izquierda a derecha o viceversa... para ello vamos a programar un autómata :)
Saludos