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

2021/7/13

Animation with Image Arrays overriding each other

BaseEvoli BaseEvoli

2021/7/13

#
I am trying to aniamate the character in my game using image arrays. The idle animation is supposed to play all the time when no button is pressed. If left or right is pressed, the run animation is supposed to play. And when space is pressed, the shoot animation is supposed to play. When the idle animation plays, nothing else plays for some reason, even if a button is pressed, and when the idle animation should in theory not even play because the if should prevent it. The shoot animation shouldn't loop. When I press space, it depends on how long I press it on what frame it ends, and it never plays through. How can I make the animations work simultaniously without overriding each other and creating a mess? Here is the code of my character class:
import greenfoot.*;

public class Character extends Mover
{
    private int shotTimer = 15;
    private int SpaceTimer = 15;
    private int AnyPressed = 0;

    private int idleFrames = 35;
    private int idleTime;

    private int ShootFrames = 6;
    private int ShootTime;
    private int ShootAnimate;

    private int LeftFrames = 16;
    private int LeftTime;

    private int RightFrames = 16;
    private int RightTime;

    Character()
    {
        
    }

    public void act() 
    {
        shotTimer ++;
        AnyPressed --;
        SpaceTimer --;
        ShootAnimate --;
        checkKeys();

    }

    private void checkKeys()
    {
        if(Greenfoot.isKeyDown("left") )
        {
            animateLeft();
            moveLeft();
            AnyPressed = 50;
        }else{
            AnyPressed = 0;
        }

        if(Greenfoot.isKeyDown("right") )
        {
            animateRight();
            moveRight();
            AnyPressed = 50;
        }else{
            AnyPressed = 0;
        }

        if(Greenfoot.isKeyDown("space") && SpaceTimer <= 0)
        {

            ShootAnimate=5;

            if(shotTimer > 25){

                ShootTime = 0;
                this.shoot();
                shotTimer = 0;
                AnyPressed = 50;

            }
            SpaceTimer = 25;
        }else{
            AnyPressed = 0;
        }

        if(ShootAnimate >= 1){
            animateShoot();
        }

        /*if(AnyPressed < 1 /*&& ShootAnimate >= 1){

            setImage(animateIdle()[idleTime]);
            idleTime++;
            if(idleTime == idleFrames){
                idleTime = 0;
            }

        }else{
            AnyPressed = 1;
        }
        */

    }   
    public void animateShoot(){
        setImage(animateShootx()[ShootTime]);
        if(ShootFrames < 6){
            ShootTime ++;
        }
        /*if(ShootTime == ShootFrames){
        ShootTime = 0;
        }*/

    }

    public void animateLeft(){
        setImage(animateLeftx()[LeftTime]);
        LeftTime ++;
        if(LeftTime == LeftFrames){
            LeftTime = 0;
        }
    }

    public void animateRight(){
        setImage(animateRightx()[RightTime]);
        RightTime ++;
        if(RightTime == RightFrames){
            RightTime = 0;
        }
    }

    public void shoot()
    {
        this.getWorld().addObject(new Bullet(), this.getX()+30, this.getY()-45);
    }

    public GreenfootImage[] animateIdle(){

        GreenfootImage[] images = new GreenfootImage[idleFrames];

        for(int i = 0; i < 35; i++){

            if(AnyPressed < 1){

                images[i] = new GreenfootImage("Idle" + i + ".png");

            }

        }

        return images;

    }

    public GreenfootImage[] animateShootx(){

        GreenfootImage[] images = new GreenfootImage[ShootFrames];

        for(int i = 0; i < 6; i++){

            if(ShootAnimate >= 1){

                images[i] = new GreenfootImage("Shoot" + i + ".png");

            }

        }

        return images;

    }

    public GreenfootImage[] animateLeftx(){

        GreenfootImage[] images = new GreenfootImage[LeftFrames];

        for(int i = 0; i < 16; i++){

            images[i] = new GreenfootImage("Left" + i + ".png");

        }

        return images;

    }

    public GreenfootImage[] animateRightx(){

        GreenfootImage[] images = new GreenfootImage[RightFrames];

        for(int i = 0; i < 16; i++){

            images[i] = new GreenfootImage("Right" + i + ".png");

        }

        return images;

    }

}
And here is the mover class:
import greenfoot.*;

public class Mover extends Actor
{
    private static final int speed = 6;             // running speed (sideways)
    
    private int vSpeed = 0;                         // current vertical speed
    
    public void moveUp()
    {
       setLocation(getX(), getY()+5);
    }
    
    public void moveRight()
    {
        setLocation ( getX() + speed, getY() );
    }
    
    public void moveLeft()
    {
        setLocation ( getX() - speed, getY() );
    }
    
    public void setVSpeed(int speed)
    {
        vSpeed = speed;
    }
}
RcCookie RcCookie

2021/7/14

#
How do you want to have multiple animations playing at the same time? You can only show one image at a time
danpost danpost

2021/7/15

#
It is not easy to give advice here. On one hand, there is lag due to reading in multiple images during game time. On the other hand, there is a lot of memory used up if the images are loaded up front. However, that is what I think you should do -- load all the images into arrays when you create the character. With these field arrays, you can add one more field array for the one that is currently being used (by setting it equal to one of the others). Use only one timer for the current animation (along with the shot delay timer). You will also not need fields for frame counts (size of arrays will suffice). Using modulus function will help in "wrapping" animations (going from last image in array back to first). So, you might have the following fields (and only those fields);
GreenfootImage[] imgIdle;
GreenfootImage[] imgLeft;
GreenfootImage[] imgRight;
GreenfootImage[] imgShoot;
GreenfootImage[] imgCurrent;
int imgIndex;
int spaceTimer;
with the first four arrays being loaded at line 24, after which imgCurrent is set to imgIdle. By knowing the current image set --
if (imgCurrent == imgShoot)
-- you gain better control of your animations.
You need to login to post a reply.