¿Cómo mostrar la animación de abrir / cerrar la boca de Pacman en Java con doble búfer?
Pregunta
Estoy tratando de mostrar la famosa animación de apertura / cierre de boca del personaje pacman en un juego de pacman desechable que estoy haciendo para enseñarme a mí mismo a programar juegos.
Lo que estoy haciendo es dibujar la imagen de boca abierta, luego volver a dibujar la imagen de boca cerrada exactamente en la misma ubicación (x / y). Pero esto no funciona, y solo veo la animación de boca cerrada todo el tiempo.
Si pongo esto en un bucle, el sistema simplemente se congela y ves un parpadeo en el lugar donde se muestra la boca abierta, pero no ves las imágenes que se están reemplazando.
He probado y me he asegurado de que ambas imágenes se estén cargando correctamente y como se esperaba.
Aquí está mi función startAnim ()
, se llama cuando haces doble clic en el applet:
public void beginGame() //Called from engine.java
{
isRunning=true;
repaint();
pacman.startAnim();
}
public void startAnim() //In different class, pacman.java
{
Image orig;
while (engine.isRunning)
{
orig=this.getCurrentImg();
draw(engine.getGraphics());
this.setCurrImg(currImg2);
this.draw(engine.getGraphics());
this.setCurrImg(orig);
this.draw(engine.getGraphics());
try
{
Thread.sleep(100);
}
catch (InterruptedException e) {}
}
}
public void draw(Graphics g) //Called from engine.paint()
{
g.drawImage(getCurrentImg(), getX(),
getY(), engine);
}
Solución
tienes que dormir entre las 2 imágenes. de lo contrario, solo verás la última imagen pintada.
ej.
while( running )
{
image 1
draw
sleep
image 2
draw
sleep
}
algo como esto:
public void startAnim() //In different class, pacman.java
{
final int cnt = 2;
Image[] imgs = new Image[ cnt ];
int step = 0;
imgs[ 0 ] = closedMouthImage;
imgs[ 1 ] = openMouthImage;
while ( engine.isRunning )
{
this.setCurrImg( imgs[ step ] );
draw(engine.getGraphics());
step = ( step + 1 ) % cnt;
try
{
Thread.sleep(100);
}
catch (InterruptedException e) {}
}
}
Otros consejos
Como dijo sfossen, necesita un retraso entre el dibujo de las imágenes.
Un par de otras cosas a tener en cuenta.
- Para una animación fluida, probablemente necesite más que solo la boca abierta y " boca cerrada " imagenes Necesita dos o tres imágenes intermedias.
- Para facilitar la administración de recursos, es posible que desee unir todos sus cuadros de animación en una sola imagen ancha, que se verá como una " tira de película " ;. Luego, para dibujar un marco, use el desplazamiento (x, y) para el marco que le interesa.
- Finalmente, si dibuja todos los cuadros cada vez que pasa por el bucle principal de su programa, Pac-Man hará un chomp cada vez que lo mueva. Debería pensar en dibujar solo un cuadro cada vez a través del bucle principal y usar una variable para rastrear en qué cuadro se encuentra.
Ejemplo (pseudocódigo)
frameWidth = 32
frameIndex = 0
while(running) {
// Draw just the frame of your animation that you want
drawImage(pacmanX, pacmanY, filmStrip, frameIndex * frameWidth, 0, frameWidth, frameHeight)
frameIndex = (frameIndex + 1) % frameCount
// Update position of pacman & ghosts
// Update sound effects, score indicators, etc.
}