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

2015/1/30

Cannot get objects to remove from world correctly, HELP!

RagingAsian RagingAsian

2015/1/30

#
So whenever my Creeper and Bullet class objects interact, they remove from the world and cause an error: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. I cannot figure out how to fix this, as i am still a little new to Greenfoot. Here is the Code for all my classes so far. Thank you in advance and all help is greatly appreciated. Bullet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import greenfoot.*; 
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
{
     
    private Actor enemy;
    private int x=0;
     
    public Bullet(Actor enemy)
    {
        this.enemy = enemy;
         
    }
     
    public void act()
    {
        setLocation(getX(), getY());
        if(getX() >= getWorld().getWidth()-1)
        {
            getWorld().removeObject(this);
        }
         
        move(1);
        ifAHit();
    }
     
        //Track the enemy
//     public void move()
//     {
//         if ((getObjectsAtOffset(0,0,Creeper.class).isEmpty()))
//         {
//             int x=enemy.getX();           
//             int y=enemy.getY();
//             turnTowards(x,y);
//             move(1);
//         } else {
//             move (1);
//         }
//     }
     
    public void ifAHit()
    {
        Actor creeper = getOneIntersectingObject(Creeper.class);
        if(isTouching(Creeper.class))
        {
             
            getWorld().removeObject(creeper);
            getWorld().removeObject(this);
            if(atWorldEdge())
            {
               getWorld().removeObject(this);
            }
             
        }
      
    }
    public boolean atWorldEdge()
    {
        if(getX()<1||getX()>getWorld().getWidth()-10)
        {
            return true;
        }
        if(getY()<10||getY()>getWorld().getHeight()-10)
        {
            return true;
        }else return false;
          
    }
     
}
Creeper Class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import greenfoot.*;
import java.util.ArrayList;
 
public class Creeper extends Actor
{
    int[] waypointX = {120, 119, 91, 92, 42, 42, 120, 120, 175};
    int[] waypointY = {295857, 77, 77, 105,105, 153, 153};
    int index=0;
    int distance=150;
     
    private int counter=0;;
    private static final int max=20;
    private int spawn=0;
    public Creeper()
    {
         
    }
     
    public void act()
    {
        counter++;
        spawn++;
        if((counter>=20)&&(spawn<=max))
        {
            Creeper creeper = new Creeper();
            World world = getWorld();
            world.addObject(creeper, 0, 29);
            counter=0;
            
        }
        move();
    }
     
    public void move()
    {
        move(1);       
        int theDistance = (int)(Math.hypot(waypointX[index] - getX(), waypointY[index] - getY()));  
        if (theDistance < 2  )
        {
             
             for (int i=0;i<theDistance;i++)
             {
                 distance=theDistance;
                 index++;
             }
              
                   
        }
        turnTowards(waypointX[index], waypointY[index]);
        if(counter>=425&&spawn>=445)
        {
            getWorld().removeObject(this);
        }
    }
    
}
Tower Class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
import java.util.ArrayList;
/**
 * Write a description of class Tower here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class Tower extends Actor
{
    private List<Creeper> enemies;
    private Actor closestEnemy;
    private int range;
    private int canShoot;
    private int count=0;
    public Tower()
    {
        GreenfootImage tower = new GreenfootImage(25, 25);
    }
     
    public void act()
    {  
        enemies = getObjectsInRange(100, Creeper.class);
         
        System.out.println(count+"    (//X2)");
        System.out.println(canShoot+"    (//canShoot value)");
        System.out.println("enemies " + enemies.size() + "    (//enemies)");
        turnClosest(enemies);
        shootAt();
    }
     
    public void turnClosest(List<Creeper> enemies)
    {
        Actor closest = null;
        int distance=100;
        if(enemies.size()>0)
        {
            for(int i=0;i<enemies.size();i++)
            {
                Actor turtle = enemies.get(i);
                range=(int)(Math.hypot(turtle.getX() - getX(), turtle.getY()-getY()));
                if((range<distance))
                {
                    closest=turtle;
                    distance=range;
                     
                }
            }
            System.out.println("x = " + closest.getX() + "    (//X axis)" );
            int targetX=closest.getX();
            int targetY=closest.getY();
            closestEnemy = closest;
            turnTowards(targetX,targetY);
             
        }
         
    }
     
    public void shootAt( )
    {
        canShoot=15;
        count++;
        if(count>=canShoot)
        {
            getWorld().addObject(new Bullet(closestEnemy), getX(), getY());
            if(count>=canShoot)
            {
                count=0;
            }
        }
    }
}
Super_Hippo Super_Hippo

2015/1/30

#
Ok, let's get through the act method of the bullet:
1
setLocation(getX(), getY());
This doesn't do anything.
1
2
3
4
if(getX() >= getWorld().getWidth()-1)
{
    getWorld().removeObject(this);
}
This removes the bullet if it reached the right edge of the world.
1
move(1);
This moves the bullet one step. I don't know if Greenfoot has an exception in the method itself, but usually this shouldn't be called when the bullet isn't in the world maybe.
1
2
3
4
5
6
ifAHit();
// -->
public void ifAHit()
{
    Actor creeper = getOneIntersectingObject(Creeper.class);
    if(isTouching(Creeper.class))
I am not 100% sure if getOneIntersectingObject and isTouching use the same algorithm to check for intersection, so it may not cause any error. Usually 'if (creeper!=null)' is used.
1
2
3
{
    getWorld().removeObject(creeper);
    getWorld().removeObject(this);
Removes the intersecting creeper and the bullet.
1
if(atWorldEdge())
Checks if the bullet is at the world edge. You just removed the bullet, so this causes the error.
1
2
3
4
5
        {
           getWorld().removeObject(this);
        }
    }
}
The last part tries to remove the object when it is at the world edge, but as I said, it was already removed before. This if-block shouldn't be here in this method.
RagingAsian RagingAsian

2015/2/3

#
Super_Hippo wrote...
Ok, let's get through the act method of the bullet:
1
setLocation(getX(), getY());
This doesn't do anything.
1
2
3
4
if(getX() >= getWorld().getWidth()-1)
{
    getWorld().removeObject(this);
}
This removes the bullet if it reached the right edge of the world.
1
move(1);
This moves the bullet one step. I don't know if Greenfoot has an exception in the method itself, but usually this shouldn't be called when the bullet isn't in the world maybe.
1
2
3
4
5
6
ifAHit();
// -->
public void ifAHit()
{
    Actor creeper = getOneIntersectingObject(Creeper.class);
    if(isTouching(Creeper.class))
I am not 100% sure if getOneIntersectingObject and isTouching use the same algorithm to check for intersection, so it may not cause any error. Usually 'if (creeper!=null)' is used.
1
2
3
{
    getWorld().removeObject(creeper);
    getWorld().removeObject(this);
Removes the intersecting creeper and the bullet.
1
if(atWorldEdge())
Checks if the bullet is at the world edge. You just removed the bullet, so this causes the error.
1
2
3
4
5
        {
           getWorld().removeObject(this);
        }
    }
}
The last part tries to remove the object when it is at the world edge, but as I said, it was already removed before. This if-block shouldn't be here in this method.
So I took out that code and causes and error when it hits the World's edge. This is the error message: 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:663) at greenfoot.Actor.getOneIntersectingObject(Actor.java:912) at Bullet.ifAHit(Bullet.java:53) at Bullet.act(Bullet.java:25) at greenfoot.core.Simulation.actActor(Simulation.java:568) at greenfoot.core.Simulation.runOneLoop(Simulation.java:526) at greenfoot.core.Simulation.runContent(Simulation.java:215) at greenfoot.core.Simulation.run(Simulation.java:205)
danpost danpost

2015/2/3

#
In your original code post, insert the following line after line 26 in the Bullet class:
1
return;
This will avoid the rest of the method being processed when the bullet is removed because it reached the right edge of the world.
RagingAsian RagingAsian

2015/2/3

#
Thank you Danpost. Also do you know how I can get the Bullet class to track the Creeper Class? I commented that method out, and it causes an error right as the Bullet spawns.
danpost danpost

2015/2/3

#
I do not know if you even need the condition for moving. You may be able to just remove the condition and run the block's internal code straight-away. If you do want a condition, maybe this will suffice:
1
if (enemy.getWorld() != null)
RagingAsian RagingAsian

2015/2/3

#
Thank you a lot, it is working perfectly.
You need to login to post a reply.