所以我一直在看Notch的Metagun源代码,我似乎无法弄清楚他是如何让精灵动画的。现在,我想要做的就是循环一些角色行走动画的图像。这是代码,我的输出,到目前为止,只显示行走的第一个图像,这是静止的角色: 包动画;
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
public class SpriteAnimation extends JComponent{
/**
*
*/
private static final long serialVersionUID = 1L;
int frame=0;
public void paint(Graphics g){
try{
BufferedImage still = ImageIO.read(SpriteAnimation.class.getResource("still.png"));
BufferedImage walkRight = ImageIO.read(SpriteAnimation.class.getResource("right.png"));
BufferedImage midWalk = ImageIO.read(SpriteAnimation.class.getResource("mid.png"));
BufferedImage walkLeft = ImageIO.read(SpriteAnimation.class.getResource("left.png"));
BufferedImage[] states={still,walkRight,midWalk};
int frame=0;
do{
frame++;
if(frame>=3){
frame=0;
g.drawImage(states[frame],0,0,null);
}
}
while(true);
}catch(Exception e){
}
}
}
答案 0 :(得分:3)
我不知道为什么其他人继续前进,只是试图重构你的代码,甚至没有提到真正的问题:如果你使用Swing
制作你的动画,那么这个循环很大不否。你基本上是在占用EDT
并拖延整个GUI。
您应该重写代码,以便SpriteAnimation
每次调用paint
方法时只绘制一帧,而动画循环由某种计时器外部管理
快速举例:
public class SpriteAnimation extends JComponent{
private int currentFrame = 0;
private BufferedImage[] frames;
public SpriteAnimation(){
/**
* Load your frames
*/
}
public void paintComponent(Graphics g){
currentFrame++;
if(frame >= 3)
frame = 0;
// we pass this as the ImageObserver in case the images are
// loaded asynchronously
g.drawImage(frames[currentFrame], 0, 0, this);
}
}
在你的主要方法中:
// Timer is a swing timer
Timer timer = new Timer(
100,
new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// main frame is your main animation canvas (eg a JFrame)
mainFrame.repaint();
}
});
timer.start();
答案 1 :(得分:1)
问题在于:
if(frame>=3){
frame=0;
g.drawImage(states[frame],0,0,null);
}
需要:
if(frame>=3){
frame=0;
}
g.drawImage(states[frame],0,0,null);
此外,您的states
数组缺少walkLeft
:
BufferedImage[] states={still,walkRight,midWalk};
这也意味着您可能希望上述代码段中的条件为frame > states.length
。
注意:您应该按照@ asermax的评论建议使用计时器,但这应该至少修复您的错误。