Come mostrare l'animazione di apertura / chiusura della bocca di Pacman in Java con doppio buffering?

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

  •  05-07-2019
  •  | 
  •  

Domanda

Sto cercando di mostrare la famosa animazione di apertura / chiusura della bocca del personaggio pacman in un gioco pacman usa e getta che sto facendo per insegnarmi la programmazione del gioco.

Quello che sto facendo è disegnare l'immagine della bocca aperta, quindi ridisegnare l'immagine della bocca chiusa nella stessa identica posizione (x / y). Ma questo non funziona e vedo sempre l'animazione a bocca chiusa.

Se lo inserisco in un ciclo, il sistema si blocca e vedi uno sfarfallio in cui l'immagine a bocca aperta è questa, ma non vedi che le immagini vengono sostituite.

Ho testato e verificato che entrambe le immagini siano state caricate correttamente e come previsto.

Ecco la mia funzione startAnim () , che viene chiamata quando si fa doppio clic sull'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);
}
È stato utile?

Soluzione

devi dormire tra le 2 immagini. altrimenti vedrai solo l'ultima immagine dipinta.

ad es.

while( running )
{
    image 1
    draw
    sleep
    image 2
    draw
    sleep
}

qualcosa del genere:

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) {}
            }
}

Altri suggerimenti

Come diceva sfossen, è necessario un ritardo tra il disegno delle immagini.

Un paio di altre cose da considerare.

  • Per un'animazione fluida, probabilmente hai bisogno di qualcosa di più della semplice "apertura bocca" e "bocca chiusa" immagini. Sono necessarie due o tre immagini intermedie.
  • Per semplificare la gestione delle risorse, potresti voler riunire tutti i tuoi fotogrammi di animazione in un'unica, ampia immagine, che sembrerà un "filmstrip". Quindi, per disegnare una cornice, usi l'offset (x, y) per la cornice che ti interessa.
  • Infine, se disegni tutti i fotogrammi ogni volta che attraversi il ciclo principale del tuo programma, Pac-Man eseguirà un chomp completo ogni volta che lo sposti. Dovresti pensare di disegnare solo un fotogramma ogni volta attraverso il ciclo principale e di utilizzare una variabile per tracciare il fotogramma in cui ti trovi.

Esempio (pseudocodice)

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.
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top