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

2021/2/12

Switch case FSM access instance variables from act() method

gfask gfask

2021/2/12

#
Hello, I want to make a simple FSM in greenfoot with switch case. This code doesn't work. I don't know why.
public void act() {
        switch (state) {
            case "attack" : 
            if (this.energie<30) {
                this.state = "attack2";
            }
            setRotation(getRotation()+1);
            setLocation(getX()+1,getY());
            if(isAtEdge()==true){
                getWorld().addObject(new Figur(this.energie, this.state),300,300);
                getWorld().removeObject(this);
            }
            break;
            case "attack2":
            System.out.println("state: "+ state);
            break;
            default:
            System.out.println("default");
        }
With this code, I never reach state attack2. Dont't matter how low energie is. But: If I remove the lines
 if(isAtEdge()==true){
                getWorld().addObject(new Figur(this.energie, this.state),300,300);
                getWorld().removeObject(this);
            }
the state is changed, if the energie is lower 30. What could be the problem? Annotation: getWorld().addObject(new Figur(this.energie, this.state),300,300); does work, the new Object has the energie (also lower than 30), but the state is not changed.
danpost danpost

2021/2/12

#
Instead of removing this and adding a new Figur actor, just relocate this:
if (isAtEdge()) setLocation(300, 300);
gfask gfask

2021/2/12

#
This does work:
        if(isAtEdge()==true){
            setLocation(getX()-600,getY());
}
So the question is: Why does this not work, if I create a new Object?
danpost danpost

2021/2/12

#
gfask wrote...
Why does this not work, if I create a new Object?
I would have to see the entire class.
gfask gfask

2021/2/12

#
Thank you danpost, you are right, but the question still is: Why doesn't it work, when I create a new actor, althoug the actor has a energy<30.
danpost danpost

2021/2/12

#
gfask wrote...
Thank you danpost, you are right, but the question still is: Why doesn't it work, when I create a new actor, althoug the actor has a energy<30.
danpost wrote...
I would have to see the entire class.
gfask gfask

2021/2/12

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)


public class Figur extends Actor{
    private String state; 
    private int energie;
    
    public Figur(int energie, String state){
        this.state=state;
        this.energie = energie;
    }
    public void act() {
        switch (state) {
            case "attack" : 
            if (this.energie<30) {
                this.state = "attack2";
            }
            setRotation(getRotation()+1);
            setLocation(getX()+1,getY());
            if(isAtEdge()==true){
                getWorld().addObject(new Figur(this.energie, this.state),300,300);
                getWorld().removeObject(this);
            }
            break;
            case "attack2":
            System.out.println("state: "+ state);
            break;
            default:
            System.out.println("default");
        }
    }
    public void decreaseEnergie (int i){
        System.out.println("Energie: "+ energie);
        energie = energie-i;
        System.out.println("After: "+ energie);
    }
}
    
danpost danpost

2021/2/12

#
gfask wrote...
<< Code Omitted >>
I honestly do not see any reason why it would not work. And, from what I can tell from testing is that it does work.
gfask gfask

2021/2/12

#
Hi, ok I wrote a very small example. It never changes in state "attack2", although energy becomes < 30 , if I hit the Figur often.
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
public class MyWorld extends World{
Figur f;
Rocket r;
    public MyWorld(){    

        super(600, 400, 1); 
        //Energie and state
        f=new Figur(100,"attack");
        addObject(f,500,100);
        
        //With reference to Figur
        r = new Rocket(f);
        r.setRotation(270);
        addObject(r,400,500);
        
    }
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class Bullet extends Actor{
    int timer;
    Figur f;
    Rocket r;

    public Bullet(Rocket r, Figur f){
        setRotation(270);
        timer = 0;
        this.r=r;
        this.f=f;
    }

    public void act() {
        timer=timer+1;
        move(2);
        if(isTouching(Figur.class)==true){
            f.decreaseEnergie(40);
            //f=null;
            getWorld().showText("Hit Figure! ",350,50);
            getWorld().removeObject(this);
            return;
        }
        if(isAtEdge()==true){
            getWorld().removeObject(this);
            return;
        }
    }    
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class Figur extends Actor{
    private String state; 
    private int energy;

    public Figur(int energy, String state){
        this.state=state;
        this.energy = energy;
    }

    public void act() {
        switch (state) {
            case "attack" : 
            //System.out.println("state: "+ state);
            if (this.energy<30) {
                this.state = "attack2";
            }
            setRotation(getRotation()+1);
            setLocation(getX()+1,getY());
            if(isAtEdge()==true){
                getWorld().addObject(new Figur(energy,state),50,300);
                getWorld().removeObject(this);
            }
            break;
            case "attack2":
            System.out.println("state: "+ state);
            break;
            default:
            System.out.println("default");
        }
    }
    public void decreaseEnergie (int i){
        System.out.println("Energy before decreasing: "+ energy);
        energy = energy-i;
        System.out.println("Energy after decreasing: "+ energy);
        System.out.println("state: "+ state);
    }
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class Rocket extends Actor{
    private Figur f;
    private int timer;
    public Rocket(Figur f){
        this.f=f;
    }

    public void act() {
        timer = timer + 1;
        if(Greenfoot.isKeyDown("space") && timer > 60){
            timer = 0; 
            //System.out.println("space");
            getWorld().addObject(new Bullet(this,f), getX(), getY()-50);
        }  


    }    
}


gfask gfask

2021/2/12

#
Why the figure never changes in state "attack2" ?
danpost danpost

2021/2/12

#
gfask wrote...
Why the figure never changes in state "attack2" ?
When you create a new one, it is then not the same as the one referenced by Figur f . The one in world, once recreated will maintain an energy value of 100 while the one referenced by f (which no longer acts nor is in the world) will have its energy go down.
danpost danpost

2021/2/12

#
Actually, you need not have any references passed to new objects. The following is sufficient:
import greenfoot.*;

public class MyWorld extends World
{
    public MyWorld()
    {    
        super(600, 400, 1);
        addObject(new Figur(), 500, 100);
        addObject(new Rocket(), 400, 500);
    }
}
import greenfoot.*;

public class Bullet extends Actor
{
    public Bullet()
    {
        setRotation(270);
    }
    
    public void act()
    {
        move(2);
        Figur f = (Figur)getOneIntersectingObject(Figur.class);
        if (f != null)
        {
            f.decreaseEnergie(40);
            getWorld().showText("Hit Figure!", 350, 50);
            getWorld().removeObject(this);
        }
        else if (isAtEdge())
        {
            getWorld().removeObject(this);
        }
    }    
}
import greenfoot.*;

public class Figur extends Actor
{
    private String state; 
    private int energy;
    
    public Figur()
    {
        this(100, "attack");
    } // vv              vv
    
    public Figur(int energy, String state)
    {
        this.state = state;
        this.energy = energy;
    }
 
    public void act()
    {
        switch (state)
        {
            case "attack": 
            if (energy < 30) state = "attack2";
            setRotation(getRotation()+1);
            setLocation(getX()+1,getY());
            if (isAtEdge())
            {
                getWorld().addObject(new Figur(energy, state), 50, 300);
                getWorld().removeObject(this);
            }
            break;
            case "attack2":
            // System.out.println("state: "+state);
            break;
            default:
            System.out.println("default");
        }
    }
    
    public void decreaseEnergie (int i)
    {
        System.out.println("Energy before decreasing: "+energy);
        energy = energy-i;
        System.out.println("Energy after decreasing: "+energy);
        System.out.println("state: "+state);
    }
}
import greenfoot.*;

public class Rocket extends Actor
{
    private int timer;
    
    public Rocket()
    {
        setRotation(270);
    }
    
    public void act()
    {
        timer = timer+1;
        if (Greenfoot.isKeyDown("space") && timer>60)
        {
            timer = 0; 
            getWorld().addObject(new Bullet(), getX(), getY()-50);
        }  
    }    
}
gfask gfask

2021/2/13

#
First: Thank you for your answer an the code, that does work.
danpost wrote...
gfask wrote...
Why the figure never changes in state "attack2" ?
When you create a new one, it is then not the same as the one referenced by Figur f . The one in world, once recreated will maintain an energy value of 100 while the one referenced by f (which no longer acts nor is in the world) will have its energy go down.
Why is it so, it doesn't make sense. If I cut the reference code line 38, my example still doesn't work. I tried also, to update the reference to f in the world, calling a setter-methode in myworld in line 69/70. It also doesn't work. Why?
danpost danpost

2021/2/13

#
gfask wrote...
Why is it so, it doesn't make sense.
You would need to update Figur f in Rocket class when you create a new Figur actor.
gfask gfask

2021/2/13

#
Thanks a lot, you are right. Updating Figur f in Rocket class does work.
You need to login to post a reply.