¿Cómo mostrar la animación de abrir / cerrar la boca de Pacman en Java con doble búfer?

StackOverflow https://stackoverflow.com/questions/622375

  •  05-07-2019
  •  | 
  •  

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);
}
¿Fue útil?

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.
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top