This site requires JavaScript, please enable it in your browser!
Greenfoot back
Tenn0
Tenn0 wrote ...

2023/12/14

slow down the walking animation

Tenn0 Tenn0

2023/12/14

#
i dont know how to slow down the walking animation of my "Player" character
public void act() 
    {
        if (Greenfoot.isKeyDown("d"))
            this.setLocation(this.getX()+7, this.getY());
        if (Greenfoot.isKeyDown("d"))
            this.animateRunRight();

        if  (Greenfoot.isKeyDown("a"))
            this.setLocation(this.getX()-7, this.getY());
        if  (Greenfoot.isKeyDown("a"))
            this.animateRunLeft();

        if  (Greenfoot.isKeyDown("w"))
            this.setLocation(this.getX(), this.getY()-4);
        if  (Greenfoot.isKeyDown("w"))
            this.animateRunUp();

        if  (Greenfoot.isKeyDown("s"))
            this.setLocation(this.getX(), this.getY()+4);
        if  (Greenfoot.isKeyDown("s"))
            this.animateRunDown();

        if (Greenfoot.isKeyDown("right"))
            this.setLocation(this.getX()+7, this.getY());
        if (Greenfoot.isKeyDown("right"))
            this.animateRunRight();

        if  (Greenfoot.isKeyDown("left"))
            this.setLocation(this.getX()-7, this.getY());
        if  (Greenfoot.isKeyDown("left"))
            this.animateRunLeft();

        if  (Greenfoot.isKeyDown("up"))
            this.setLocation(this.getX(), this.getY()-4);
        if  (Greenfoot.isKeyDown("up"))
            this.animateRunUp();

        if  (Greenfoot.isKeyDown("down"))
            this.setLocation(this.getX(), this.getY()+4);
        if  (Greenfoot.isKeyDown("down"))
            this.animateRunDown();
        eatPokeball();
    }   

    public void initAnimationSprites()
    {
        for (int i = 0; i < 4; i++)
        {
            String filename = "Run" + i + "_90.png";
            RunRight[i] = new GreenfootImage(filename);
            Greenfoot.delay(2);
        }

        for (int i = 0; i < 4; i++)
        {
            String filename = "Run" + i + "_-90.png";
            RunLeft[i] = new GreenfootImage(filename);
            Greenfoot.delay(2);
        }

        for (int i = 0; i < 4; i++)
        {
            String filename = "Run" + i + "_0.png";
            RunUp[i] = new GreenfootImage(filename);
            Greenfoot.delay(2);
        }

        for (int i = 0; i < 4; i++)
        {
            String filename = "Run" + i + "_180.png";
            RunDown[i] = new GreenfootImage(filename);
            Greenfoot.delay(2);
        }
    }

    public void animateRunRight()
    {
        setImage(RunRight[animCounter++ % 4]);
        
    }

    public void animateRunLeft()
    {
        setImage(RunLeft[animCounter++ % 4]); 
        
    }

    public void animateRunUp()
    {
        setImage(RunUp[animCounter++ % 4]); 
        
    }

    public void animateRunDown()
    {
        setImage(RunDown[animCounter++ % 4]); 
        
    }
danpost danpost

2023/12/20

#
Tenn0 wrote...
i dont know how to slow down the walking animation of my "Player" character << Code Omitted >>
You cannot slow the animation by delaying the initializing of the animation images. You will need an extra counter to count act steps between image changes. You will also need to keep track of the last direction moved so this new counter can be set properly to change the image immediately when the direction does change. First, however, you should note that with your current code, some unwanted behavior will occur. Imagine, if both "a" and "left" are down, the speed doubles and the animation runs twice as quick. Or, if "a" and "w" are down, the player will move along some diagonal, but its image is facing up (since the "w" part is executed after the "a" part). The animation again will be double speed. I guess, to put it bluntly, it is not just the slowing down of the animation you should be concerned with, as there is very little control over its speed at all. The way to avoid these issues is to collected all the required information before acting on any of it. For example:
int dx = 0, dy = 0; // to retain key info for horizontal and vertical controls
if (Greenfoot.isKeyDown("a") || Greenfoot.isKeyDown("left")) dx--; // left control
if (Greenfoot.isKeyDown("d") || Greenfoot.isKeyDown("right")) dx++; // right control
if (Greenfoot.isKeyDown("w") || Greenfoot.isKeyDown("up")) dy--; // up control
if (Greenfoot.isKeyDown("s") || Greenfoot.isKeyDown("down")) dy++; // down control
The two variables, dx and dy, can each have only one of three values -- 0, 1, or -1. You want that one, and only one, of these to be a non-zero value (meaning one, and only one is zero, as well). If the product of the two is zero, then one of them must be zero. Then, after that, if the sum of the two is not zero, then the other is non-zero. Perfect. We can start with the following conditions:
if (dx*dy == 0 && dx+dy != 0) {
Now you have a valid direction in one of the two variables. The player can now be moved:
setLocation(getX()+7*dx, getY()+4*dy);
But, it is not very useful being two variables for the animation. We can, however, now convert these values into a single rotational value in a way which, as you will soon see, will be very useful:
int dir = (1-dx)*dx*dx + (2-dy)*dy*dy;
The term on the right with the zero-valued variable will drop out and the other remains (by the double multiplication of the variable -- multiplying the parenthesized part by 1). This new variable has 4 possible values -- 0, 1, 2, and 3, representing right, down, left and up, consecutively. Your code currently has 4 arrays for the animation. Let us combine them into a double array and use the value of this new variable as an index. Here is the full code:
static final int SPRITE_TIME = 10; // adjust as needed

GreenfootImage[][] run = new GreenfootImage[4][4];
int animCounter;
int animSet;

public Player() {
    String[] str = new String[] { "_90", "_180", "_-90", "_0" };
    for (int j = 0; j < 4; j++) {
        for (int i=0; i< 4; i++) {
            run[j][i] = new GreenfootImage("Run"+i+str[j]+".png");
        }
    }
    setImage(run[0][0]);
}

public void act() {
    move();
    eatPokeball();
}

private void move() {
    int dx = 0, dy = 0;
    if (Greenfoot.isKeyDown("a") || Greenfoot.isKeyDown("left")) dx--;
    if (Greenfoot.isKeyDown("d") || Greenfoot.isKeyDown("right")) dx++;
    if (Greenfoot.isKeyDown("w") || Greenfoot.isKeyDown("up")) dy--;
    if (Greenfoot.isKeyDown("s") || Greenfoot.isKeyDown("down")) dy++;
    if (dx*dy == 0 && dx+dy != 0) {
        setLocation(getX()+7*dx, getY()+4*dy);
        int dir = (1-dx)*dx*dx + (2-dy)*dy*dy;
        if (dir != animSet) animCounter = -1;
        animSet = dir;
        animCounter = (animCounter+1)%(4*SPRITE_TIME);
        if (animCounter%SPRITE_TIME == 0) {
            setImage(run[animSet][animCounter/SPRITE_TIME]);
        }
    }
}

private void eatPokeball() {
    // etc.
You need to login to post a reply.