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

2019/11/20

Remove bullet after killing

SemDeBakkero SemDeBakkero

2019/11/20

#
Hi I want to let my bullet dissapear after I kill an enemy. But I get the following termnal window: 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:713) at greenfoot.Actor.isAtEdge(Actor.java:262) at bullet.ifAtWorldEdge(bullet.java:37) at bullet.act(bullet.java:21) 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) 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:713) at greenfoot.Actor.isAtEdge(Actor.java:262) at bullet.ifAtWorldEdge(bullet.java:37) at bullet.act(bullet.java:21) 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) 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:713) at greenfoot.Actor.isAtEdge(Actor.java:262) at bullet.ifAtWorldEdge(bullet.java:38) at bullet.act(bullet.java:21) 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) This is my code:
public class bullet extends Actor
{
   public bullet()
   {
       setImage("bullet.png"); //invoegen foto
        getImage().scale(35,35); //grootte foto
              
   }
   public void act() 
    {
        move(20);   //bewegen met snelheid 10
        kill(); //de public "kill" uitvoeren
        ifAtWorldEdge(); //de public "ifAtWorldEdgde" uitvoeren
   }
   public void kill()
    {
        Actor Enemy; //het gaat over de actor Enemy
        Enemy = getOneObjectAtOffset(0, 0, Enemy.class); 
        if (Enemy !=null)
        {
            World world;
            world = getWorld();
            world.removeObject(Enemy); //de enemy laten verdwijnen
            world.removeObject(this); //de bullet laten verdwijnen
        }
        
    }
   public void ifAtWorldEdge()
    {
        if (isAtEdge()) //als dit object aan de buitekant is
        {
            getWorld().removeObject(this);  //verwijder dan de bullet
            
        } 

    }
    
}
What should I change??
danpost danpost

2019/11/21

#
You are calling two methods, each which could remove the actor from the world (lines 12 and 13). Neither of these methods can execute properly if the actor is not in the world (one uses getOneObjectAtOffset and the other isAtEdge,, both requiring the actor be in a world). Regardless of the order these methods are called, if the first one removes the actor, the second one will fail. There are two main ways to avoid this dilemma. One is to not remove the actor is those called method, but have them return a boolean value indicating the "to-remove" state and then use those returned values ... like:
if (kill() || isAtEdge()) getWorld().removeObject(this);
This actually, eliminates the need for the ifAtWorldEdge method. The other main way is just to check if the actor is still in the world or not:
kill();
if (getWorld() == null) return;
ifAtWorldEdge();
// no code requiring actor be in world can follow

// or
kill();
if (getWorld() != null) ifAtWorldEdge();
// pre-checking must be performed anytime following code requires actor be in the world
SemDeBakkero SemDeBakkero

2019/11/21

#
danpost wrote...
You are calling two methods, each which could remove the actor from the world (lines 12 and 13). Neither of these methods can execute properly if the actor is not in the world (one uses getOneObjectAtOffset and the other isAtEdge,, both requiring the actor be in a world). Regardless of the order these methods are called, if the first one removes the actor, the second one will fail. There are two main ways to avoid this dilemma. One is to not remove the actor is those called method, but have them return a boolean value indicating the "to-remove" state and then use those returned values ... like:
if (kill() || isAtEdge()) getWorld().removeObject(this);
This actually, eliminates the need for the ifAtWorldEdge method. The other main way is just to check if the actor is still in the world or not:
kill();
if (getWorld() == null) return;
ifAtWorldEdge();
// no code requiring actor be in world can follow

// or
kill();
if (getWorld() != null) ifAtWorldEdge();
// pre-checking must be performed anytime following code requires actor be in the world
Wow thanks man, this worked!!
You need to login to post a reply.