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

2013/4/5

Making Asteroids, gameplay stops midplay when bullet hits asteroid

Griffon305 Griffon305

2013/4/5

#
I didn't really know how title this, and I have a rough idea of what is going on but I am not sure how to fix it. Basically I have a rotating turret that fires bullets at incoming asteroids. All of the coding for the bullet looks like this:
public class bullet extends movers
 
{ 
  //This establishes the speed of the bullet. 
  private int speed = 5;
  //Class bullet constructor.
  public bullet()  
    {  
        GreenfootImage image = getImage();  
        image.scale(image.getWidth() - 70, image.getHeight() - 70);  
        setImage(image);  
    }  
 
  //This tells the bullet what to do in what order.
   public void act()  
   {  
       move(speed);
       endAtEdge();
       hitAsteroid();
   }  
   /**This will check to see if the bullet is within 5 pixels of the worlds edge.  If so it will
    * return true. If not, it will return false.
    */ 
   
   public boolean atWorldEdge()
    {
        if(getX() < 5|| getX() > getWorld().getWidth() - 5)
            return true;
        if(getY() < 5 || getY() > getWorld().getHeight() - 5)
            return true;
            
        else
            return false;
            
    }
   /** This method will let the bullet know when it actually touches an asteroid.
    * 
    */
   public boolean canSee(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;        
    }
   /** This method will tell that bullet that if the atWorldEdge command returns true to remove itself
    * from the game.
    */
   public void endAtEdge()
   {
      
       if (atWorldEdge()) 
       
        {
            getWorld().removeObject(this);
        }
   }
   /** This method will be activated if the bullet touches the asteroid. If the bullet touches the
    * asteroid, the asteroid will be removed from the game.
    */
   public void destroy(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        if(actor != null) 
        {
            getWorld().removeObject(actor);
        }
    }
   /** This will tell the bullet that if it hits the asteroid to call the destroy the method and then 
    * remove itself from the game.
    */
   public void hitAsteroid()
    {
       if (canSee(asteroid.class))
       {
       destroy(asteroid.class);
       getWorld().removeObject(this);
       }
    }
}
    
So basically, I am telling the bullet to move, then to destroy an asteroid (if it sees one) or to end at the edge of the world (when it reaches it). The problem that I am having is that depending on how I order the endAtEdge() method and the destroyAsteroid() method, I keep getting an error. If I put endAtEdge() before destroyAsteroid(), my game will have an error when you fire a bullet and it reaches the world edge (but continues to play fine if you hit an asteroid) and vice versa if you put destroyAsteroid() before endAtEdge(). The error says: "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." So I think what is happening is that once the bullet reaches the edge (or hits an asteroid), it is removed but the program continues to run the act() method, and once it finds there is no longer any bullet, it has an error. So my question is, how do I get around this? What code do I put in so that once the bullet is removed (whether because it reaches the edge of the world or blows up an asteroid) I can still continue to play the game? Sorry for all the coding! Thanks! Jason
danpost danpost

2013/4/5

#
There is an Actor class method that you can use to get the world the actor is in, if it is in one. If the actor is not in any world the method will return 'null'; if it is in a world, then that world will be returned. The method is 'getWorld'. Change your last line in your act method to:
if (getWorld() != null) hitAsteroid();
or, change your act method to the following:
public void act()
{
    move(speed);
    endAtEdge();
    if (getWorld() == null) return;
    hitAsteroid();
}
You need to login to post a reply.