如何用双缓冲在Java中显示Pacman的张嘴/闭嘴动画?
题
我试图在我正在制作的一次性吃豆人游戏中展示吃豆人角色著名的张嘴/闭合动画,以自学游戏编程。
我正在做的是绘制张开嘴的图像,然后在完全相同的 (x/y) 位置重新绘制闭合的嘴图像。但这不起作用,我只看到一直闭着嘴的动画。
如果我将其放入循环中,系统就会冻结,您会看到张开嘴的图像闪烁,但您看不到图像被替换。
我已经测试并确保两个图像都按预期正确加载。
这是我的 startAnim()
函数,当您双击小程序时调用它:
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);
}
解决方案
你必须睡在2张图片之间。否则你只会看到最后一幅画。
例如
while( running )
{
image 1
draw
sleep
image 2
draw
sleep
}
类似的东西:
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 所说,绘制图像之间需要一段延迟。
还有其他一些需要考虑的事情。
- 为了获得流畅的动画效果,您可能需要的不仅仅是“张嘴”和“闭嘴”图像。您需要两个或三个中间图像。
- 为了使资源管理更容易,您可能希望将所有动画帧放在一个宽图像中,该图像看起来像“幻灯片”。然后,要绘制框架,请使用您感兴趣的框架的 (x, y) 偏移量。
- 最后,如果您每次执行程序主循环时都绘制所有帧,则每次您移动吃豆人时,吃豆人都会进行一次完整的咀嚼。您应该考虑每次通过主循环仅绘制一帧,并使用变量来跟踪您所在的帧。
示例(伪代码)
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.
}
不隶属于 StackOverflow