views:

999

answers:

2

I'm trying to show the famous mouth opening/closing animation of the pacman character in a throwaway pacman game I'm making to teach myself game programming.

What I'm doing is drawing the open mouth image, then redrawing the closed mouth image at the exact same (x/y) location. But this doesn't work, and I just see the closed mouth animation all the time.

If I put this in a loop, the system just freezes and you see flickering where the open mouth image this, but you don't see the images being replaced.

I've tested and made sure that both images are being loaded correctly and as expected.

Here's my startAnim() function, its called when you double click at the 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);
}
+3  A: 

you have to sleep between the 2 images. otherwise you will only see the last image painted.

eg.

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

something like this:

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) {}
         }
}
sfossen
I'm already doing that no? using thread.sleep?
Click Upvote
you need 2 thread sleeps, once between each change. right now you change the image, draw, change, draw, sleep.
sfossen
+1  A: 

As sfossen said, you need a delay between drawing the images.

A couple of other things to consider.

  • For smooth animation, you probably need more than just the "mouth open" and "mouth closed" images. You need two or three intermediate images.
  • To make resource management easier, you might want to put all of your animation frames together in a single, wide image, that will look like a "filmstrip". Then, to draw a frame, you use the (x, y) offset for the frame your interested in.
  • Finally, if you draw all the frames each time you go through the main loop of your program, Pac-Man will do a complete chomp every time you move him. You should think about drawing just one frame each time through the main loop and using a variable to track which frame you're on.

Example (pseudocode)

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.
}
mtnygard
I'm already sleeping, but the pacman doesn't update at all...
Click Upvote