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

2021/4/1

Flip the animation after the actor hit the border

Leon137 Leon137

2021/4/1

#
So my problem is that i don't know how to mirror the animation of my actor, after the actor hits the border. The actor should travel between the two x-borders, but the animation works only in one direction. The animation cycles with 13 images and is everytime resized to the random generated size of the actor.
public void animate()
    {
        if (count % 6 == 0)
        {
            if(animateImage > 12){
                animateImage = 0;
            }
            setImage("Vogel-mirror_" + animateImage + ".png");
            animateImage++;
            size();
           
        }
    }
danpost danpost

2021/4/1

#
Please provide the full class.
Leon137 Leon137

2021/4/1

#
public class Vogel1 extends Actor
{
    int speed = Greenfoot.getRandomNumber(8) +2;
    int health = 250;
    int count1;
    int count2;
    int animateImage1 = 1;
    int animateImage2 = 1;
    static int scaleTiny = Greenfoot.getRandomNumber(40) +80;
    static int scaleBig = Greenfoot.getRandomNumber(50) +135;

    public Vogel1(String startbild)
    {

    }

    public void act()
    { 
        move();
        click();
        health();
        count1++;
        count2++;
        animate();
    }

    public void move()
    {
        move(speed);
        //if (isAtEdge()){ //test
        //turn (180);
        //getImage().mirrorVertically();
        //move(speed);
        //}
    }

    public void animate()
    {
        if (count1 % 6 == 0)
        {
            if(animateImage1 > 12){
                animateImage1 = 0;
            }
            setImage("Vogel-mirror_" + animateImage1 + ".png");
            animateImage1++;
            size();
        }
    }

    public void health()
    {
        if (health == 0){
            getWorld().removeObject(this);
        }
        health = health - 1;
    }

    public void size()
    {
        GreenfootImage bild = getImage();
        if(speed >= 6){
            bild.scale(scaleTiny, scaleTiny);
            setImage(bild);
        }else{
            bild.scale(scaleBig, scaleBig);
            setImage(bild);
        }
    }

    public void explosion()
    {
        if (count2 % 6 == 0)
        {
            if(animateImage2 > 7){
                animateImage2 = 0;
            }
            setImage("ex_gif-" + animateImage2 + ".png");
            animateImage2++;
        }
    }

    public void click()
    {
        if (Greenfoot.mouseClicked(this)){
            Counter counter = ((Welt)getWorld()).getCounter();
            if (speed >= 8){
                counter.heraufzaehlen(+2);
            }else{
                counter.heraufzaehlen(+1);
            }
            switch(Greenfoot.getRandomNumber(3)){
                case 0: Greenfoot.playSound("chick_hit1.mp3"); break;
                case 1: Greenfoot.playSound("chick_hit2.mp3"); break;
                case 2: Greenfoot.playSound("chick_hit3.mp3"); break;
            }
            explosion();
            getWorld().removeObject(this);
        }
    }
}
danpost danpost

2021/4/1

#
Image creation and manipulation operations are taxing on CPU time. Best would be to create all images when the first Vogel1 object is created. If they are all mirrored and sized at the start, all you would need to do is set the appropriate image when needed. Using a double array of images will make it easy to work with. Also, it does no good to animate an explosion that will never happen if the actor is not in the world. Here a new class would suffice for the explosion -- it can still be coded in this class as an inner class. My suggestions would end up something like this (untested):
import greenfoot.*;

public class Vogel1 extends Actor
{
    static int scaleTiny = Greenfoot.getRandomNumber(40)+80;
    static int scaleBig = Greenfoot.getRandomNumber(50)+135;
    static GreenfootImage[][] imgs;
    
    int speed = Greenfoot.getRandomNumber(8)+2;
    int health = 250;
    int count;
    int imgNum;
 
    public Vogel1(String startbild)
    {
        if (imgs == null)
        {
            imgs = new GreenfootImage[2][13];
            int size = speed > 5 ? scaleTiny : scaleBig;
            for (int i=0; i<13; i++)
            {
                imgs[0][i] = new GreenfootImage("Vogel-mirror_"+(i)+".png");
                imgs[0][i].scale(size, size);
                imgs[1][i] = new GreenfootImage(imgs[0][i]);
                imgs[1][i].mirrorVertically();
            }
        }
        updateImage();
    }
 
    public void act()
    { 
        move();
        click();
        health();
        animate();
    }
 
    private void move()
    {
        move(speed);
        if (isAtEdge())
        {
            turn (180);
            count = -1; // to ensure image change
        }
    }
 
    private void animate()
    {
        count = (++count) % 6;
        if (count == 0)
        {
            imgNum = (++imgNum) % 13;
            updateImage();
        }
    }
    
    private void updateImage()
    {
        setImage(imgs[getRotation()/180][imgNum]);
    }
 
    private void health()
    {
        if (health == 0) getWorld().removeObject(this);
        else health--;
    }
    
    private void click()
    {
        if (Greenfoot.mouseClicked(this)){
            Counter counter = ((Welt)getWorld()).getCounter();
            if (speed >= 8){
                counter.heraufzaehlen(+2);
            }else{
                counter.heraufzaehlen(+1);
            }
            switch(Greenfoot.getRandomNumber(3)){
                case 0: Greenfoot.playSound("chick_hit1.mp3"); break;
                case 1: Greenfoot.playSound("chick_hit2.mp3"); break;
                case 2: Greenfoot.playSound("chick_hit3.mp3"); break;
            }
            getWorld.addObject(new Vogel_Explosion(), getX(), getY());
            getWorld().removeObject(this);
        }
    }
    
    private class Vogel_Explosion extends Actor
    {
        public Vogel_Explosion()
        {
            count = 0;
            imgNum = 0;
            updateImage();
        }
        
        public void act()
        {
            count = (++count) % 6;
            if (count == 0)
            {
                imgNum++;
                if (imgNum == 8) getWorld.removeObject(this);
                else updateImage();
        }
        
        private void updateImage()
        {
            setImage(new GreenfootImage("ex_gif-" + imgNum + ".png"));
        }
    }
}
I changed the name of the field animateImage to imgNum to make it clear what it is for.
Leon137 Leon137

2021/4/1

#
Thank you so much, the animation works perfect and the explosion animation too.
danpost danpost

2021/4/1

#
Leon137 wrote...
Thank you so much, the animation works perfect and the explosion animation too.
I see I forgot to close my if block after line 105. I am sure you got that closing bracket put in.
Leon137 Leon137

2021/4/1

#
The only thing what is different now, is that my actor always spawns with the same size. In my initially class i had the size method, which generated an individual size for each spawning actor. Is there any way to implement this again?
danpost danpost

2021/4/1

#
Leon137 wrote...
The only thing what is different now, is that my actor always spawns with the same size. In my initially class i had the size method, which generated an individual size for each spawning actor. Is there any way to implement this again?
Remove "static" from lines 5, 6 and 7. I may be wrong, but with the code you initially provided. all Vogel1 objects would have been the same random size also (had the scaling been working properly).
Leon137 Leon137

2021/4/1

#
danpost wrote...
Leon137 wrote...
The only thing what is different now, is that my actor always spawns with the same size. In my initially class i had the size method, which generated an individual size for each spawning actor. Is there any way to implement this again?
Remove "static" from lines 5, 6 and 7.
Now its working perfect, thank you very much for your help.
danpost danpost

2021/4/1

#
Leon137 wrote...
Now its working perfect, thank you very much for your help.
You can now also remove lines 16, 17 and 27.
You need to login to post a reply.