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

2019/4/6

Illegal State Exception

1
2
AdiBak AdiBak

2019/4/6

#
Hello, I'm re-creating the Atari Centipede game. I'm working on making my actor classes be subclasses of more general superclasses (for example, the subclasses "Centipede" and "Mushroom" would be subclasses of "Hittable"). However, when I shoot the laser and it touches a mushroom, an illegal state exception is thrown for the laser class. Can anyone please help? Thank you. Here's the code for the laser class: public void act() { // Add your action code here. MyWorld k = (MyWorld)getWorld(); Score scTxt = k.getObjects(Score.class).get(0); move(); if (getWorld() != null){ Hittable c = (Centipede)getOneIntersectingObject(Centipede.class); if (c != null){ c.onHit(); onHitTarget(); } Hittable f = (Flea)getOneIntersectingObject(Flea.class); if (f != null){ f.onHit(); onHitTarget(); } Hittable m = (Mushroom)getOneIntersectingObject(Mushroom.class); if (m != null){ m.onHit(); onHitTarget(); } Hittable p = (Poison)getOneIntersectingObject(Poison.class); if (p != null){ p.onHit(); onHitTarget(); } Hittable sp = (Spurter)getOneIntersectingObject(Spurter.class); if (sp != null){ sp.onHit(); onHitTarget(); } Hittable sc = (Scorpion)getOneIntersectingObject(Scorpion.class); if (sc != null){ sc.onHit(); onHitTarget(); } if (getWorld() != null && shouldBeRemoved()){ remove(); } } } public void move(){ setLocation(getX(), getY() - speed); } public boolean inWorld(){ boolean isInWorld = true; if (getWorld() != null){ isInWorld = true; } return isInWorld; } public void onHitTarget(){ remove(); // return; } public void remove(){ getWorld().removeObject(this); return; } public boolean shouldBeRemoved(){ boolean shouldRemove = false; if (getY() - getImage().getHeight()/2 > getWorld().getHeight()){ shouldRemove = true; } return shouldRemove; } } And here's the exception: java.lang.IllegalStateException: Actor not in world. An attempt was made to use the actor's location while it is not in the world. Either it has not yet been inserted, or it has been removed. at greenfoot.Actor.failIfNotInWorld(Actor.java:714) at greenfoot.Actor.getOneIntersectingObject(Actor.java:965) at Laser.act(Laser.java:47) at greenfoot.core.Simulation.actActor(Simulation.java:567) at greenfoot.core.Simulation.runOneLoop(Simulation.java:530) at greenfoot.core.Simulation.runContent(Simulation.java:193) at greenfoot.core.Simulation.run(Simulation.java:183)
danpost danpost

2019/4/6

#
I would suggest that you have Hittable objects look for Laser objects, instead of what you have here. Only thing Laser act would need to do then is move and check for world edge (greatly simplified).
AdiBak AdiBak

2019/4/6

#
Thanks, it worked!
AdiBak AdiBak

2019/4/7

#
Hello, I've modified the code such that once every ten mushrooms are destroyed, a flea appears on the screen, and once every fifteen are destroyed, a scorpion emerges. However, once 10 mushrooms are destroyed, I get a null pointer exception in my GameState class, and I'm not sure why. Can someone please help? Thank you. Here's the exception: java.lang.NullPointerException at Flea.<init>(Flea.java:17) at GameState.addFlea(GameState.java:66) at GameState.checkFleas(GameState.java:103) at GameState.onAct(GameState.java:118) at MyWorld.act(MyWorld.java:44) at greenfoot.core.Simulation.actWorld(Simulation.java:573) at greenfoot.core.Simulation.runOneLoop(Simulation.java:506) at greenfoot.core.Simulation.runContent(Simulation.java:193) at greenfoot.core.Simulation.run(Simulation.java:183) Here's the code for GameState class: import greenfoot.*; import java.util.List; /** * Write a description of class GameState here. * * @author (your name) * @version (a version number or a date) */ public class GameState extends State { MyWorld w = ((MyWorld)getWorld()); public int yPosition = getWorld().getHeight() * 4/5; Score j = new Score(); private int numSegments = 10; private int numToDestroyForFlea = 10; private int numToDestroyForScorpion = 15; public GameState(MyWorld w){ super(w); } public void onSet(){ MyWorld q = ((MyWorld)getWorld()); if (!q.getObjects(Score.class).isEmpty()){ Score txt = q.getObjects(Score.class).get(0); q.setScore(q.getScore() - q.getScore()); txt.setText("Score: " + q.getScore()); } q.setLvl(1); w.setGameOver(false); Player player = new Player(); getWorld().addObject(player, getWorld().getWidth()/2, getWorld().getHeight() - player.getImage().getHeight()/2); Spider s = new Spider(); getWorld().addObject(s, s.getImage().getWidth()/2, getWorld().getHeight() - s.getImage().getHeight()/2); for (int i = 0; i < 10; i++){ Centipede centipede = new Centipede(); getWorld().addObject(centipede, getWorld().getWidth()/2 - centipede.getImage().getWidth() * i, centipede.getImage().getHeight()/2); } for (int i = 0; i < 42; i++){ int x = Greenfoot.getRandomNumber(getWorld().getWidth()); int y = Greenfoot.getRandomNumber(getWorld().getHeight()); Mushroom mushroom = new Mushroom(); if (getWorld().getObjectsAt(x, y, Mushroom.class).size() == 0 && (y >= 20 && y <= getWorld().getHeight() - player.getImage().getHeight())){ getWorld().addObject(mushroom, x, y); mushroom.goToGrid(); } } j.setText(w.getScore()); j.setSize(MyWorld.GRIDSIZE); j.setOutLColor(null); getWorld().addObject(j, j.getImage().getWidth(), j.getImage().getHeight()/2); } public void addFlea(){ for (int i = 0; i < 1; i++){ Flea f = new Flea(); getWorld().addObject(f, Greenfoot.getRandomNumber(getWorld().getWidth()), -f.getImage().getHeight()); } } public void addScorpion(){ for (int i = 0; i < 1; i++){ if (w.getLvl() >= 1 && w.getLvl() <= 3){ Scorpion sco = new Scorpion(); getWorld().addObject(sco, 0, Greenfoot.getRandomNumber(getWorld().getHeight()/3)); } if (w.getLvl() > 3 && w.getLvl() < 7){ Arachnoid a = new Arachnoid(); getWorld().addObject(a, 0, Greenfoot.getRandomNumber(getWorld().getHeight()/4)); } } } public void snapAllToGrid(){ List<Mushroom> plant = getWorld().getObjects(Mushroom.class); for (int i = 0; i < plant.size(); i++){ Mushroom fungi = plant.get(i); fungi.goToGrid(); } } public void onRemove(){ // Remove anything when state is changed List <Actor> all = getWorld().getObjects(Actor.class); getWorld().removeObjects(all); } public void checkFleas(){ if (w.getDestroyed() == numToDestroyForFlea){ numToDestroyForFlea += 10; addFlea(); } } public void checkScorpions(){ if (w.getDestroyed() == numToDestroyForScorpion){ numToDestroyForScorpion += 15; addScorpion(); } } public void onAct(){ // Do what happpens in the state. Check if needs to be changed if (getWorld() != null){ checkFleas(); checkScorpions(); } if (getWorld().getObjects(Centipede.class).isEmpty()){ Greenfoot.delay(15); w.setLvl(w.getLvl() + 1); for (int i = 0; i < 10; i++){ Centipede centipede = new Centipede(); //centipede.setDx(centipede.getDx() + 1); getWorld().addObject(centipede, getWorld().getWidth()/2 - centipede.getImage().getWidth() * i, centipede.getImage().getHeight()/2); } Centipede c = new Centipede(); getWorld().addObject(c, getWorld().getWidth() - c.getImage().getWidth() * 2, c.getImage().getHeight()/2); List<Mushroom> cacti = getWorld().getObjects(Mushroom.class); for (int i = 0; i < cacti.size(); i++){ Mushroom food = cacti.get(i); food.getImage().setTransparency(255); food.goToGrid(); } Spider s = new Spider(); getWorld().addObject(s, s.getImage().getWidth()/2, getWorld().getHeight() - s.getImage().getHeight()/2); if (getWorld() != null){ checkFleas(); checkScorpions(); } } if (getWorld().getGameOver() == true){ getWorld().setState(new GameOverState(getWorld())); } } }
danpost danpost

2019/4/7

#
The error is actually in your Flea class. Show code.
AdiBak AdiBak

2019/4/7

#
Here's the code for the Flea class: import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * Write a description of class Flea here. * * @author (your name) * @version (a version number or a date) */ public class Flea extends Hittable { boolean isRemoved = false; int dy = 3; public Flea(){ getImage().scale(MyWorld.GRIDSIZE, MyWorld.GRIDSIZE); } MyWorld b = (MyWorld) getWorld(); Score scTxt = b.getObjects(Score.class).get(0); /** * Act - do whatever the Flea wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { // Add your action code here. Score scTxt = b.getObjects(Score.class).get(0); if (b.getPaused() == false){ setLocation(getX(), getY() + dy); if (isTouching(Player.class)){ MyWorld w = ((MyWorld)getWorld()); w.setGameOver(true); } if (Greenfoot.getRandomNumber(100) == 20){ Mushroom m = new Mushroom(); getWorld().addObject(m, getX(), getY()); m.goToGrid(); } /*if (getY() > getWorld().getHeight()){ getWorld().removeObject(this); }*/ if (isTouching(Laser.class)){ removeTouching(Laser.class); onHit(); } } } public void onHit(){ Mushroom a = new Mushroom(); getWorld().addObject(a, getX(), getY()); a.goToGrid(); destroy(); b.setScore(b.getScore() + 100); scTxt.setText("Score: " + b.getScore()); } } Thanks!
danpost danpost

2019/4/7

#
You cannot get the Score object from the world in the constructor of the Flea class. The constructor is executed during the creation of the Flea object -- before it can be placed into any world. Override the Actor class addedToWorld(World) method to get the Score object. As an alternative, you could pass the Score object by way of a parameter argument to the Flea constructor.
AdiBak AdiBak

2019/4/7

#
I'm sorry, but I don't understand what you mean....
danpost danpost

2019/4/7

#
AdiBak wrote...
I'm sorry, but I don't understand what you mean....
Upon a second look, I see that the errant code is not actually in the constructor of the class; however, it is still processed during object creation. Only declare the b and scTxt fields where you have them. Do not assign them their values there. Those assignments cannot be performed before the actor is in a world. You have this:
public Flea(){
    getImage().scale(MyWorld.GRIDSIZE, MyWorld.GRIDSIZE);
}
MyWorld b = (MyWorld) getWorld();
Score scTxt = b.getObjects(Score.class).get(0);

public void act() 
{
    Score scTxt = b.getObjects(Score.class).get(0);
    if (b.getPaused() == false){
        setLocation(getX(), getY() + dy);
        if (isTouching(Player.class)){
            MyWorld w = ((MyWorld)getWorld());
            w.setGameOver(true);
        }
        if (Greenfoot.getRandomNumber(100) == 20){
            Mushroom m = new Mushroom();
            getWorld().addObject(m, getX(), getY());
            m.goToGrid();
        }

        /*if (getY() > getWorld().getHeight()){
        getWorld().removeObject(this);
        }*/
        if (isTouching(Laser.class)){
            removeTouching(Laser.class);
            onHit();
        }
    }
}
Change lines 4 and 5 to:
private MyWorld b;
private Score scTxt;
Then remove line 9. Finally, add the following method to the class:
protected void addedToWorld(World w)
{
    b = (MyWorld)w;
    scTxT = b.getObjects(Score.class).get(0);
}
You could also remove line 13 and change the 'w' to 'b' in line 14. All occurrences of 'getWorld()' or '(MyWorld)getWorld()' can also be replaced with 'b'.
AdiBak AdiBak

2019/4/7

#
Thanks, it worked again!
AdiBak AdiBak

2019/4/7

#
Hi, I'm trying to make the player move in conjunction with the mouse moving. The player shouldn't be able to cross the y-position of 4/5 of world height (he's restricted to the bottom-fifth). However, I'm having trouble doing this. I read the API, but I don't really understand how to use it in my code. Can someone please help? Thank you. Here's the code for my Player class: import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) //import java.lang.String; /** * Write a description of class Player here. * * @author (your name) * @version (a version number or a date) */ public class Player extends Actor { private int numPresses = 0; public Player(){ getImage().scale(MyWorld.GRIDSIZE * 3/2, MyWorld.GRIDSIZE * 3/2); } int dx = 2; int dy = -2; /** * Act - do whatever the Player wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { // Add your action code here. MyWorld v = (MyWorld)getWorld(); if (v.getPaused() == false){ move(); if (Greenfoot.mouseClicked(this)){ Laser l = new Laser(); if (getWorld().getObjects(Laser.class).size() == 0){ getWorld().addObject(l, getX(), getY() - l.getImage().getHeight()/2); Greenfoot.playSound("LaserBeam.wav"); } } } } public void move(){ int height = getWorld().getHeight(); int width = getWorld().getWidth(); int playerW = getImage().getWidth(); int playerH = getImage().getHeight(); MouseInfo mi = Greenfoot.getMouseInfo(); if (mi != null){ if (getY() - playerH/2 > height * 4/5){ setLocation(mi.getX(), mi.getY()); } } } public int getPresses(){ return numPresses; } }
Super_Hippo Super_Hippo

2019/4/7

#
Change 'getY()' in line ??? (in the if condition in the move method) to 'mi.getY()'. (Use code tags in the future, please.)
AdiBak AdiBak

2019/4/7

#
Sorry, I'll use code tags next time. Thank you!
AdiBak AdiBak

2019/4/7

#
Hi, I've added a new subclass, PointsLaser, that when used, increases the points obtained when destroying an enemy. However, I get an illiegal state exception upon shooting a centipede with a regular laser. Can someone please help? Thank you. Here's the code for my Centipede class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
/**
 * Write a description of class Centipede here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Centipede extends Hittable

{
    public int east = 0;
    public int west = 1;
    public int south = 2;
    public int direction = east;
    public static int dx;
    //  private int pointsPer = 100;
    private Score scTxt;
    
    public Centipede(){
        getImage().scale(MyWorld.GRIDSIZE, MyWorld.GRIDSIZE);
        dx = 2;
    }

    /**
     * Act - do whatever the Centipede wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        GreenfootImage img = getImage();
        int pedeH = img.getHeight();
        int pedeW = img.getWidth();
        MyWorld jon = (MyWorld)getWorld();
        // Add your action code here.
        if (jon.getPaused() == false){
            if (direction == east){
                dx = 2;
            }
            if (direction == west){
                dx = -2;
            }
            if (direction == south){
                setLocation(getX(), getY() + pedeH);
            }
            if (MyWorld.GRIDSIZE % dx == 0){
                setLocation(getX() + dx, getY());
            } else {
                System.out.println("dx has to be divisible by gridsize");
            }
            if (getX() + pedeW/2 > getWorld().getWidth()){
                setLocation(getX(), getY() + pedeH);
                direction = west;
            }
            if (getX() - pedeW/2 < 0){
                setLocation(getX(), getY() + pedeH);
                direction = east;
            }

            if (isTouching(Player.class)){

                jon.setGameOver(true);
            }

            if (getY() > getWorld().getHeight()){
                setLocation(getX(), getImage().getHeight()/2);
            }
            List <Mushroom> mushy = getIntersectingObjects(Mushroom.class);
            for (int i = 0; i < mushy.size(); i++){
                Mushroom collider = mushy.get(i); 
                if (getX() + pedeW > collider.getX() && dx > 0){
                    setLocation(getX(), getY() + pedeH);
                    if (getY() + pedeH > collider.getY()){                   
                        direction = west;
                    }              
                    direction = west;
                }

                if (getX() - pedeW < collider.getX() && dx < 0){
                    setLocation(getX(), getY() + pedeH);
                    if (getY() + pedeH > collider.getY()){                   
                        direction = east;
                    }
                    direction = east; 

                }
            } 
            if (getWorld() != null){
                Actor l = (Laser)getOneIntersectingObject(Laser.class);
                if (l != null){
                    getWorld().removeObject(l);

                    onLaserHit();
                }
                Actor p = (PointsLaser)getOneIntersectingObject(PointsLaser.class);
                if (p != null){
                    getWorld().removeObject(p);
                    onPointsLaserHit();
                }
            }

        }
    }    

    public void onLaserHit(){
        addMushroom();
        Greenfoot.playSound("Explo.wav");
        MyWorld g = (MyWorld)getWorld();
        g.setScore(g.getScore() + 100);
        scTxt = g.getObjects(Score.class).get(0);

        scTxt.setText("Score: " + g.getScore());

        destroy();
    }

    public void onPointsLaserHit(){
        addMushroom();
        Greenfoot.playSound("Explo.wav");
        MyWorld f = (MyWorld)getWorld();
        f.setScore(f.getScore() + 200);
        scTxt.setText("Score: " + f.getScore());
        destroy();
    }

    
}

And here's the error: java.lang.IllegalStateException: Actor not in world. An attempt was made to use the actor's location while it is not in the world. Either it has not yet been inserted, or it has been removed. at greenfoot.Actor.failIfNotInWorld(Actor.java:714) at greenfoot.Actor.getOneIntersectingObject(Actor.java:965) at Centipede.act(Centipede.java:95) at greenfoot.core.Simulation.actActor(Simulation.java:567) at greenfoot.core.Simulation.runOneLoop(Simulation.java:530) at greenfoot.core.Simulation.runContent(Simulation.java:193) at greenfoot.core.Simulation.run(Simulation.java:183)
Super_Hippo Super_Hippo

2019/4/8

#
Put lines 95-99 into an else-block or add "return;" after line 93.
There are more replies on the next page.
1
2