Come mostrare l'animazione di apertura / chiusura della bocca di Pacman in Java con doppio buffering?
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);
}
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.
}