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

2014/12/8

Actor not in World Error. I don't know anymore.

Cookiezero Cookiezero

2014/12/8

#
Hello everyone. I'm new here and I've been wracking my brain over how I could make this work in Greenfoot. It's a simple concept. All I want to do in my game are these things. Have the player avatar shoot a bullet at an enemy and have 1)The bullet disappear 2) the enemy disappear and 3) subtract from my enemy counter/score. However, each time I do this/each time there are no enemies onscreen but there are still bullets, Greenfoot gives me "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. "error @ at bullet.destroy(bullet.java:47) AND at bullet.act(bullet.java:16). I would like there to be "missed bullets" still onscreen without crashing. Thank you for your time. ---------bullet------------------------------------------------------------------------ import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) import java.util.List; /** * Write a description of class bullet here. * * @author (your name) * @version (a version number or a date) */ public class bullet extends Actor { boolean touchedEnemy = false; public void act() { move(5); disappear(); destroy(); return; } public void disappear() { if(atWorldEdge()) { World world; world = getWorld(); world.removeObject(this); } } public boolean atWorldEdge() { if(getX() < 10 || getX() > getWorld().getWidth() - 10) return true; if(getY() < 10 || getY() > getWorld().getHeight() - 10) return true; else return false; } public void destroy() { Actor touchingEnemies = getOneIntersectingObject(touchEnemy.class); if(touchingEnemies != null) { if(touchedEnemy = true) { World myWorld = getWorld(); SandBG sandbg = (SandBG)myWorld; myWorld.removeObject(touchingEnemies); Counter counter = sandbg.getCounter(); counter.subtractScore(); } } else { touchedEnemy = false; } } } ----------touchEnemy------------------------------------------------------------------------- public class touchEnemy extends Actor { private int horizontalSpeed = Greenfoot.getRandomNumber(5)-3; private int verticalSpeed = Greenfoot.getRandomNumber(5)-3; /** * Act - do whatever the touchEnemy wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { move(horizontalSpeed, verticalSpeed); wrapAtEdge(); } public void move(int changeX, int changeY) { int x = getX(); int y = getY(); int newX = x + changeX; int newY = y + changeY; setLocation(newX, newY); } public String hitTheEdge() { int x = getX(); int y = getY(); World myWorld = getWorld(); int rightSide = myWorld.getWidth() - 1; int bottomSide = myWorld.getHeight() - 1; if(y == 0) { return "top"; } else if (x == 0) { return "left"; } else if (x == rightSide) { return "right"; } else if (y == bottomSide) { return "bottom"; } else { return null; } } public void wrapAtEdge() { String edge = hitTheEdge(); int x = getX(); int y = getY(); World myWorld = getWorld(); int rightSide = myWorld.getWidth() - 1; int bottomSide = myWorld.getHeight() - 1; if(edge == "bottom") { setLocation(x, 0); } else if(edge == "top") { setLocation(x, bottomSide); } else if(edge == "left") { setLocation(rightSide, y); } else if(edge == "right") { setLocation(0, y); } } }
danpost danpost

2014/12/8

#
This is the classic 'two methods that remove the actor' problem. If you have two methods that each can remove the actor (the bullet,, in your case) from the world (methods are 'disappear' and 'destroy'), then if one remove the object, the other one will throw either the IllegalStateException or a NullPointerException. This can be solved by testing if the actor is still in the world after the first method is called (checking the return of 'getWorld' for 'null').
You need to login to post a reply.