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

2013/4/15

Program crashes when i do a shot

JesusJesus JesusJesus

2013/4/15

#
Hey, I creating a game, where you can shoot on enemys (Spider) and i want to remove the Spider if i hit it. I used this code in the Laser class (The shots which hit the Spiders):
public void remove()
    {
      if (canSee(Spider.class) )
        {
            remove(Spider.class);
        }
    }
and this code in the Overclass of the Laser class:
public boolean canSee(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;     
    }
    public void remove(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        if(actor != null) 
        {
            getWorld().removeObject(actor);
            return;
        }
    }
When I start the game, it crashes if the Laser hit the edge of the map, why??? Im sure that it is because of one of These codes, because without them it works. Thank you very much
danpost danpost

2013/4/15

#
Actually, the problem is not in any of these methods. It is probably in your 'act' method that calls these methods. Among those method calls in your 'act' method, you probably have more than one that can remove the Laser object that is being acted on from the world. When the first one remove the object, the second one produces an error. In the 'act' method, after any method call (except the last one) that has a chance of removing the Laser object ('this') from the world, place the following statement:
if (getWorld() == null) return;
This will prevent any further executing of code within the 'act' method after the object has been removed from the world.
JesusJesus JesusJesus

2013/4/15

#
Thank you for your request, but sry i dont really know what you mean... should i do this in the act method? But in my act method is nearly nothing, here I will upload the hole Laser class so you can tell me there how i should do it okay? And again thank you ;)
public void act() 
    {
        move(15);
        move();
        remove();
    } 
    public void move()
    {
        setLocation(getX(), getY());
        if(getY()>550)  
        {
            getWorld().removeObject(this);
            return;
        }
        setLocation(getX(), getY());
        if(getY()<10)  
        {
            getWorld().removeObject(this);
            return;
        }
        setLocation(getX(), getY());
        if(getX()<10)  
        {
            getWorld().removeObject(this);
            return;
        }
        setLocation(getX(), getY());
        if(getX()>550)  
        {
            getWorld().removeObject(this);
            return;
        }
    } 
    public void remove()
    {
      if (canSee(Spider.class) )
        {
            remove(Spider.class);
            return;
        }
    }
danpost danpost

2013/4/15

#
Yes. Change line 5 from
remove();
to
if (getWorld() != null) remove();
Here is what was happening. Line 4 executes the 'move' method which will remove the Laser object from the world if it is at one of the edges of the world. Whether the object was removed or not, after returning from that method, the 'remove' method is called to execute. If the object was removed from the world, the 'canSee' method will cause an error because it tries to use the location of the object in a world to determine if an object of the given class is intersecting it and you cannot get a location of an object that is not in a world.
JesusJesus JesusJesus

2013/4/15

#
WOOOOW you are the best!! It works. Thanks a lot. I will follow you now... ;)
danpost danpost

2013/4/15

#
Another way to fix it is by changing line 36 to
if (getWorld() != null && canSee(Spider.class))
The 'return;' statement on line 39 is un-necessary and your 'move' method can be simplified to
public void move()
{
    if (getY()>550 ||
        getY()<10 ||
        getX()<10 ||
        getX()>550)  
            getWorld().removeObject(this);
}
This method really does not move the object; it only checks for the edges of the world and removes the object if it is at one. You might consider renaming the method to more reflect what it does (maybe 'checkWorldEdges'). The 'remove' method could be better named also (maybe something like 'checkSpider').
You need to login to post a reply.