so i have two animation. one is when player is standing and one is when player get hit. 'standing' animation will keep looping for ever. and 'planehit' animation should loop though onces and stop.

in player class iam setting up animation by getting images. 'standing' animation has two images. 'planehit' has 4 images.

i need help modifing 'SpriteAnimation class' so that it will only loop though onces when player get hit. right now this code below keep looping both animation for ever.

player class

......
//get image for animation
private BufferedImage[] standing = {SpriteSheet.getSprite(0, 0), SpriteSheet.getSprite(1, 0)};
private BufferedImage[] planehit = {SpriteSheet.getSprite(0, 5), SpriteSheet.getSprite(1, 5), 
                                    SpriteSheet.getSprite(2, 5), SpriteSheet.getSprite(3, 5),};

// These are animation states
private SpriteAnimation aStand = new SpriteAnimation(standing, 10);
private SpriteAnimation aPlaneHit = new SpriteAnimation(planehit, 10);

//This is the actual animation
private SpriteAnimation animationStand = aStand;
private SpriteAnimation animationPlaneHit = aPlaneHit;

.........

public void animation()
{ 
  animationStand.start();     //keep looping
  if(isHit)                      //if player get hit
   animationPlaneHit.start();   //loop though onces but doesnt work

    animationStand.update();
        animationPlaneHit.update();
}
........
public void paint(...)
{
//make player standing a animation between two images.
 //if player get hit set flag to true. isHit is only true when player get hit. soon as he is not hit it   
 //turn to false. so if flag is true make animation.
g.drawImage(animationStand.getSprite(), (int)x,(int)y, width, height, null);
   if(isHit)
       flag = true;
   if(flag)
       g.drawImage(animationPlaneHit.getSprite(), (int)x,(int)y, width, height, null);
}

SpriteFrame

public class SpriteFrame {

    private BufferedImage frame;
    private int duration;

    public SpriteFrame(BufferedImage frame, int duration) {
        this.frame = frame;
        this.duration = duration;
    }

    public BufferedImage getFrame() {
        return frame;
    }

    public void setFrame(BufferedImage frame) {
        this.frame = frame;
    }

    public int getDuration() {
        return duration;
    }

    public void setDuration(int duration) {
        this.duration = duration;
    }
}

SpriteAnimation

public class SpriteAnimation {
    private int frameCount;                 // Counts ticks for change
    private int frameDelay;                 // frame delay 1-12 (You will have to play around with this)
    private int currentFrame;               // animations current frame
    private int animationDirection;         // animation direction (i.e counting forward or backward)
    private int totalFrames;                // total amount of frames for your animation

    private boolean stopped;                // has animations stopped

    private List<SpriteFrame> SpriteframeObject = new ArrayList<SpriteFrame>();    // Arraylist of frames 

    public SpriteAnimation(BufferedImage[] frames, int frameDelay) {
        this.frameDelay = frameDelay;
        this.stopped = true;

        for (int i = 0; i < frames.length; i++) {
            addFrame(frames[i], frameDelay);
        }

        this.frameCount = 0;
        this.frameDelay = frameDelay;
        this.currentFrame = 0;
        this.animationDirection = 1;
        this.totalFrames = this.SpriteframeObject.size();

    }

    public void start() {
        if (!stopped) {
            return;
        }

        if (SpriteframeObject.size() == 0) {
            return;
        }

        stopped = false;
    }

    public void stop() {
        if (SpriteframeObject.size() == 0) {
            return;
        }

        stopped = true;
    }

    public void restart() {
        if (SpriteframeObject.size() == 0) {
            return;
        }

        stopped = false;
        currentFrame = 0;
    }

    public void reset() {
        this.stopped = true;
        this.frameCount = 0;
        this.currentFrame = 0;
    }

    private void addFrame(BufferedImage frame, int duration) {
        if (duration <= 0) {
            System.err.println("Invalid duration: " + duration);
            throw new RuntimeException("Invalid duration: " + duration);
        }

        SpriteframeObject.add(new SpriteFrame(frame, duration));
        currentFrame = 0;
    }

    public BufferedImage getSprite() {
        return SpriteframeObject.get(currentFrame).getFrame();
    }

    public void update() {
        if (!stopped) {
            frameCount++;

            if (frameCount > frameDelay) {
                frameCount = 0;
                currentFrame += animationDirection;

                if (currentFrame > totalFrames - 1) {
                    currentFrame = 0;
                }
                else if (currentFrame < 0) {
                    currentFrame = totalFrames - 1;
                }
            }
        }
    }
}

Recommended Answers

All 9 Replies

**[EDIT:

I only just realized your post is Java, and my recommendation is C++. However, the basic logic is still of use to you. I dunno if there are enums in Java, but you could just easily use integer values or, a bool.

]**

In your SpriteAnimation class add this:

enum PlayBackMode{Loop, PlayOnce};
PlayBackMode playMode;

Then you'll have to set the PlaneHit animation's playMode = PlayOnce. And the update function should be:

public void update() {
    if (!stopped) {
        frameCount++;
        if (frameCount > frameDelay) {
            frameCount = 0;
                currentFrame += animationDirection;
            if (currentFrame > totalFrames - 1) {
                currentFrame = 0;
                if(playMode == PlayOnce){
                    stopped = true;
                }
            }
            else if (currentFrame < 0) {
                currentFrame = totalFrames - 1;
            }
        }
    }
}

You need to tell the code that the animation stops when it reaches the max amount of frames. You don't do that in your original code, as far as I know. I'm also confused by currentFrame += animationDirection and the else if that checks if currentFrame is less than 0. When would that ever happen?

quick question what is playBackMode. is that 'animationPlaneHit' value in player class.

int loop;
int PlayOnce;
...

if( == playOnce)
{
    stopped = true;
}
...

i was thinking:
Add a boolean loop somewhere in the Animation class, then check if it's false.

but not sure how to do this

DId you try Liuqahs15's suggestion? It looked perfectly sensible to me...

ps: Liuqahs15: Nice post. And yes, Java has enums just like that.

yes, here is what i have:

//animation construtor

    public SpriteAnimation(BufferedImage[] frames, int frameDelay, boolean shouldLoop) {
        this.loop = shouldLoop; 
        ....
    }

//i put this line in update method update method

 if(!loop) {
     stopped = true;
 }

in player class i am sending boolean

private SpriteAnimation aStand = new SpriteAnimation(standing, 10, true);    //loop
private SpriteAnimation aPlaneHit = new SpriteAnimation(planehit, 10, false); //dont loop

but it didnt worked for me. not sure what iam doing wrong. i think my animation class is right but the problem might be in player class? bc iam runing two animation at same time.

You don't say where you put it in the update method. The suggested code used it like this to stop the animation ofter the last frame was displayed if in "play once" mode...

 if (currentFrame > totalFrames - 1) {
   currentFrame = 0;
   if(playMode == PlayOnce){
      stopped = true;
   }
 }
commented: ty +2

o i c. just last question, i am not sure what to set these value to.

//constructor
playMode = ;
playOnce = ;

Liuqahs suggested an enum, which is generally a good idea, but if you haven't learned those yet you could use a simple boolean, eg
boolean playOnce = (true or false depending on the type of Sprite)
then if it's true you stop the animation after the last frame, but if its false you go back to the first frame

i c. i tried this. but didnt worked.

//playOnce could be true or false. depends in player class. 
//animation construtor
    public SpriteAnimation(BufferedImage[] frames, int frameDelay, boolean shouldLoop) {
            this.playOnce = shouldLoop; 
            ....
        }






 if (currentFrame > totalFrames - 1) {
   currentFrame = 0;
   if(PlayOnce){
      stopped = true;
   }
 }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.