1

I am writing a simple 2D game where any enemy walks toward you and you have to shoot him. Right now I am animating the walking by creating an array of all 8 different images, and then cycling through them every 5 ticks. Is there a better or simpler way to do this? Here is the code:

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;
    }
}

The function Images.loadImage is just a custom method for loading images

user1150769
  • 395
  • 1
  • 4
  • 17

2 Answers2

4

Had you ever heard about something called Frame independent movement you should consider make the movement based on time so you will have a consistent movement on all cases

suggest you some help : create a class the wrap you animation movement

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];
}

}

and you soldier should act as a model

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 ;
}

}

then in you Game main world class define an Animation object that represent the animation you want to made for the soldiers and make as much as you want instances of soldiers objects this way you will define the animation once i.e you dont have to create 8 images each time you want to create a soldier and another benifet that you will have a loosly coupled application

example

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);


}

}
confucius
  • 13,127
  • 10
  • 47
  • 66
3

One problem I see: Your "curImg" is not dependent on time, but on images drawn so far. So if you raise or lower FPS (e.g. for smoother background scrolling) the images will flip faster or slower. Probably the animation images are drawn for a specific time, e.g. a 5 images walk cycle for 1 second. You should have a (global or scene relative) time value and select the image dependent on the time value.

Hauke Ingmar Schmidt
  • 11,559
  • 1
  • 42
  • 50