Java 做简单行走动画的好方法?

Java 做简单行走动画的好方法?,java,swing,animation,jpanel,Java,Swing,Animation,Jpanel,我正在写一个简单的2D游戏,任何敌人向你走来,你都必须射杀他。现在,我正在通过创建一个包含所有8个不同图像的数组来设置行走的动画,然后每5次循环一次。有更好或更简单的方法吗?代码如下: public class Soldier { private int xpos, ypos, curImg; private Image[] soldier; private Image currentImg; public Soldier(){ xpos = 500;

我正在写一个简单的2D游戏,任何敌人向你走来,你都必须射杀他。现在,我正在通过创建一个包含所有8个不同图像的数组来设置行走的动画,然后每5次循环一次。有更好或更简单的方法吗?代码如下:

public class Soldier {

private int xpos, ypos, curImg;
private Image[] soldier;
private Image currentImg;

    public Soldier(){
        xpos = 500;
        ypos = 250;
        curImg = 0;
        soldier = new Image[8];
        for(int i=0; i<soldier.length; i++){
            soldier[i] = Images.loadImage("res/soldier/s"+(i+1)+".png");
        }
    }

    public void draw(Graphics2D g2){
        currentImg = soldier[curImg/5];
        g2.drawImage(currentImg, xpos, ypos, null);
        if(curImg == 35){
            curImg = 0;
        }
        else{
            curImg++;
        }
    }

    public void move(){
        xpos-=1;
    }
}
公共级士兵{
私人int XPO、YPO、curImg;
私人形象[]士兵;
私有镜像;
公兵(){
xpos=500;
ypos=250;
curImg=0;
士兵=新形象[8];

对于(int i=0;i我看到的一个问题:你的“curImg”不取决于时间,而是取决于迄今为止绘制的图像。因此,如果你提高或降低FPS(例如,为了更平滑的背景滚动),图像将翻转得更快或更慢。动画图像可能是在特定时间绘制的,例如,5个图像的行走周期为1秒。你应该有一个(全局或场景相关)时间值,并根据时间值选择图像。

我发现一个问题:您的“curImg”不取决于时间,而是取决于迄今为止绘制的图像。因此,如果您提高或降低FPS(例如,为了更平滑的背景滚动)图像将翻转得更快或更慢。动画图像可能是在特定的时间内绘制的,例如,5幅图像的行走周期为1秒。您应该有一个(全局或场景相关)时间值,并根据时间值选择图像。

您听说过称为帧独立运动的东西吗 你应该考虑以时间为基础进行运动,这样你将在所有情况下都有一个一致的运动:

建议你一些帮助: 创建一个类,用于包裹动画移动

public class Animation {

  public static final int ANIMATION_LOOPING = 0;
    public static final int ANIMATION_NONLOOPING = 1;

private Image [] sprites;
private float frameDuration ; 

public Animation (Image ... sprites, float frameDuration){

this.sprites =sprites;
this.frameDuration = frameDuration;
}  

//this function takes a the walking time of the soldier 
public Image getKeyFrame(float stateTime , int mode){


int frameNumber = (int) stateTime/ frameDuration;

if(mode == ANIMATION_NONLOOPING){
frameNumber = Math.min( sprites.length , frameNumber);
}
else{
frameNumber = frameNumber % sprites.length;
}

return sprites[frameNumber];
}

}
你应该做个模范

public class Solider {

float walkingTime = 0;

  int xpos ;
 int ypos ;
 int xspeed;

public Solider(int xpos,int ypos,int xspeed){

this.xpos = xpos;
this.ypos = ypos;
this.xspeed = xspeed;//movementPerSecond in the x axis for example -3
}

//deltaTime is the time elapsed in milliseconds
public void update(float deltaTime){


xpos += xspeed * (deltaTime / 1000.0);
walkingTime += deltaTime ;
}
}

然后在游戏主世界级中定义一个动画对象,该对象表示要为士兵制作的动画,并尽可能多地制作士兵对象的实例。通过这种方式,您将定义一次动画,即每次创建一个士兵和另一个要创建的benifet时,您不必创建8个图像ave是一个松散耦合的应用程序

范例

public class MyGameWorld {

Animation soldierAnimation ; 

Soldier [] soliders ;

public MyGameWorld(int numbers_of_soliders){

soliders = new Soldier[numbers_of_soliders];

//loop over the array to instantiate them 
for( int i =0; i < numbers_of_soliders;++i){
soliders[i] = new Soldier(randomx ,randomy ,-5); // randomx , randomy is random values you can supply 
}

//then instantiate the animation object
//first get the images 
Image [] sprites = new sprites [8]; 
sprites [0] = new Image ......


soldierAnimation = new Animation(0.2, sprites);// this will make it flip each 0.2 seconds you can put any value that fits your need 
}


//in the game loop update you soldiers 

for(int i =0 ; i <numbers_of_soliders ; ++i){
soliders[i].update(deltaTime);
}

then render them using the animation 
for(int i =0 ; i< number_of_soliders ; ++i){

drawOnScreenThisImageWithThisPosition( soliders[i].xpos, soliders[i].ypos,soldierAnimation.getKeyFrame(soliders[i].walkingTime, Animation.ANIMATION_LOOPING);


}

}
公共类MyGameWorld{
动画士兵化;
士兵[]士兵;
公共MyGameWorld(士兵的整数){
士兵=新士兵[士兵人数];
//在数组上循环以实例化它们
对于(int i=0;i<士兵人数;++i){
士兵[i]=新士兵(randomx,randomy,-5);//randomx,randomy是您可以提供的随机值
}
//然后实例化动画对象
//首先获取图像
Image[]精灵=新精灵[8];
精灵[0]=新图像。。。。。。
soldierAnimation=新动画(0.2,精灵);//这将使它每0.2秒翻转一次,您可以根据需要设置任何值
}
//在游戏循环中更新你的士兵

对于(inti=0;i你听说过称为帧独立运动的东西吗 你应该考虑以时间为基础进行运动,这样你将在所有情况下都有一个一致的运动:

建议你一些帮助: 创建一个类,用于包裹动画移动

public class Animation {

  public static final int ANIMATION_LOOPING = 0;
    public static final int ANIMATION_NONLOOPING = 1;

private Image [] sprites;
private float frameDuration ; 

public Animation (Image ... sprites, float frameDuration){

this.sprites =sprites;
this.frameDuration = frameDuration;
}  

//this function takes a the walking time of the soldier 
public Image getKeyFrame(float stateTime , int mode){


int frameNumber = (int) stateTime/ frameDuration;

if(mode == ANIMATION_NONLOOPING){
frameNumber = Math.min( sprites.length , frameNumber);
}
else{
frameNumber = frameNumber % sprites.length;
}

return sprites[frameNumber];
}

}
你应该做个模范

public class Solider {

float walkingTime = 0;

  int xpos ;
 int ypos ;
 int xspeed;

public Solider(int xpos,int ypos,int xspeed){

this.xpos = xpos;
this.ypos = ypos;
this.xspeed = xspeed;//movementPerSecond in the x axis for example -3
}

//deltaTime is the time elapsed in milliseconds
public void update(float deltaTime){


xpos += xspeed * (deltaTime / 1000.0);
walkingTime += deltaTime ;
}
}

然后在游戏主世界级中定义一个动画对象,该对象表示要为士兵制作的动画,并尽可能多地制作士兵对象的实例。通过这种方式,您将定义一次动画,即每次创建一个士兵和另一个要创建的benifet时,您不必创建8个图像ave是一个松散耦合的应用程序

范例

public class MyGameWorld {

Animation soldierAnimation ; 

Soldier [] soliders ;

public MyGameWorld(int numbers_of_soliders){

soliders = new Soldier[numbers_of_soliders];

//loop over the array to instantiate them 
for( int i =0; i < numbers_of_soliders;++i){
soliders[i] = new Soldier(randomx ,randomy ,-5); // randomx , randomy is random values you can supply 
}

//then instantiate the animation object
//first get the images 
Image [] sprites = new sprites [8]; 
sprites [0] = new Image ......


soldierAnimation = new Animation(0.2, sprites);// this will make it flip each 0.2 seconds you can put any value that fits your need 
}


//in the game loop update you soldiers 

for(int i =0 ; i <numbers_of_soliders ; ++i){
soliders[i].update(deltaTime);
}

then render them using the animation 
for(int i =0 ; i< number_of_soliders ; ++i){

drawOnScreenThisImageWithThisPosition( soliders[i].xpos, soliders[i].ypos,soldierAnimation.getKeyFrame(soliders[i].walkingTime, Animation.ANIMATION_LOOPING);


}

}
公共类MyGameWorld{
动画士兵化;
士兵[]士兵;
公共MyGameWorld(士兵的整数){
士兵=新士兵[士兵人数];
//在数组上循环以实例化它们
对于(int i=0;i<士兵人数;++i){
士兵[i]=新士兵(randomx,randomy,-5);//randomx,randomy是您可以提供的随机值
}
//然后实例化动画对象
//首先获取图像
Image[]精灵=新精灵[8];
精灵[0]=新图像。。。。。。
soldierAnimation=新动画(0.2,精灵);//这将使它每0.2秒翻转一次,您可以根据需要设置任何值
}
//在游戏循环中更新你的士兵

对于(int i=0;i可能更好地分离draw方法的帧处理。将其放在某个更新方法中。为什么需要另一个为什么?仅简单?????可能更好地分离draw方法的帧处理。将其放在某个更新方法中。为什么需要另一个为什么?仅简单?????谢谢!我会尝试实现这个。谢谢!我会尝试实现这个。