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

2016/11/23

Need help with stopping an actor from still trying to execute methods after removal from game

miahg17 miahg17

2016/11/23

#
Hello. I am making a game that has multiple hostile actors that move toward a player actor. The goal is to maneuver the player in a way that will make the hostiles run into a hole, which will remove the hostile and add to a score. If the hostiles reach the player, the player will die. The problem is that i'm receiving errors after a hostile or player gets removed. The error occurs with the opposite method. So, when player dies, the chasePlayer method throws an error. If a hostile is removed, the killPlayer method throws an error. I'm not sure what functionality to add that will stop these methods from continuing once I reach one of these points. Here is my Hostile code, which is the Super class of my 3 hostiles:
/**
 * Write a description of class Hostile here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Hostile extends Actor
{
   private Player player;
    
    public Hostile(Player player){
        this.player = player;
    }
    
    /**
     * Act - do whatever the Red wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
    
    }
    
    public void chasePlayer()
    {
        int deltaX = player.getX() - getX();
        int deltaY = player.getY() - getY();
        setRotation((int) (180 * Math.atan2(deltaY, deltaX) / Math.PI));
    }
    
    public void isAtHole(){
        Hole hole = (Hole) getOneIntersectingObject(Hole.class);
        if(hole!=null){
            Board board = (Board) getWorld();
            board.removeObject(this);
          
        }
    }
    
    public void killPlayer(){
        Player player = (Player) getOneIntersectingObject(Player.class);
        if(player!=null){
            Board board = (Board) getWorld();
            board.removeObject(player);
        } 
        
    }
    
}
Here is one of my hostile actors, which are subclasses of Hostile:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Red here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Red extends Hostile 

{
   private Player player;
    
    public Red(Player player){
       super(player);
    }
    
    /**
     * Act - do whatever the Red wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        super.chasePlayer();
        move(3);
        super.isAtHole();
       killPlayer();
    }
    
    
    
    
    
    
}
Here is my Player code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Player here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Player extends Actor
{
    public Player(){
    }
     
    /**
     * 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() 
    {
      moveKeys();
    } 
    
    /**
     * Check whether a keyboard key has been pressed and react if it has.
     */
    private void moveKeys()
    {
        if (Greenfoot.isKeyDown("up")||Greenfoot.isKeyDown("W")) 
        {
            setLocation(getX(), getY()-8);
        }
        
        if (Greenfoot.isKeyDown("down")||Greenfoot.isKeyDown("S")) 
        {
            setLocation(getX(), getY()+8);
        }
        
        if (Greenfoot.isKeyDown("right")||Greenfoot.isKeyDown("D")) 
        {
            setLocation(getX()+6, getY());
        }
        
        if (Greenfoot.isKeyDown("left")||Greenfoot.isKeyDown("A")) 
        {
            setLocation(getX()-6, getY());
        }
    }
}
Here is my World code: import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * Write a description of class MyWorld here. * * @author (your name) * @version (a version number or a date) */ public class Board extends World { /** * Constructor for objects of class MyWorld. * */ public Board() { // Create a new world with 600x400 cells with a cell size of 1x1 pixels. super(1000, 800, 1); Player tim = new Player(); addObject(tim,400,400); Red red = new Red(tim); addObject(red,700,700); Blue blue = new Blue(tim); addObject(blue,150,700); Yellow yellow = new Yellow(tim); addObject(yellow,150,150); Hole hole = new Hole(); addObject(hole, 475,400); } } There are two more subclasses of Hostile, which are Yellow and Blue. They have matching code except for the int inside move(). Thanks for any help you can give.
miahg17 miahg17

2016/11/23

#
Code for Red has one typo. killPlayer() should be super.killPlayer().
danpost danpost

2016/11/23

#
miahg17 wrote...
Code for Red has one typo. killPlayer() should be super.killPlayer().
That is not a typo -- either way is fine. The only time you would need to prefix a superclass method call with 'super.' is when you override the method in the class (have a method with the same name and same parameter types in both the class and the superclass). In the 'killPlayer' method of the Hostile class, add the following line at the beginning (first line in the method):
if (getWorld() == null) return;
You could do the same in the 'chasePlayer' and 'isAtHole' methods as well (so if you decide to change the call order, it will not cause the problem again.
miahg17 miahg17

2016/11/23

#
I tried the line you provided inside all three methods as first line and still get this when my player is removed: 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:711) at greenfoot.Actor.getX(Actor.java:164) at Hostile.chasePlayer(Hostile.java:29) at Red.act(Red.java:24) at greenfoot.core.Simulation.actActor(Simulation.java:604) at greenfoot.core.Simulation.runOneLoop(Simulation.java:562) at greenfoot.core.Simulation.runContent(Simulation.java:221) at greenfoot.core.Simulation.run(Simulation.java:211) The similar error that occured when a hostile was removed has cleared up.
danpost danpost

2016/11/23

#
For the 'chasePlayer' method, both need to be in the world. Make the following the first line:
if (player == null || player.getWorld() == null || getWorld() == null) return;
miahg17 miahg17

2016/11/29

#
Thanks for the help danpost.
You need to login to post a reply.