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

2015/2/16

Grabbing a reference to certain Objects.

Abomb1126 Abomb1126

2015/2/16

#
I've tried so hard to get this to work. I've been working on a way to grab objects out of the list that getIntersectingObjects() methods creates. I've created a reference for the list to store it in. I then made a condition to check if the list is empty. If it is not empty, I'm trying to check if a certain class is in the list with the .contains() method. The code works beautifully up to the printing of the collisionList. I get a great representation of what is colliding with the Crab. I just don't know how to grab a reference to what the crab is crossing. My code is as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
     * Detects if the worm is close to the crab, and if so, eats it.
     */
    public void detectCollision()
    {
        List collisionList = getIntersectingObjects(null);
        System.out.println(collisionList);
        if(!collisionList.isEmpty()){
            //Check for Worm
            if(collisionList.contains(new Worm())){
                System.out.println("IT WORKED!");
            }
             
        }
         
        //if(worm != null)
        //{
        //    world.removeObject(((Worm)worm));
        //    Greenfoot.playSound("eating.wav");
        //    wormsEaten++;
        //    ((CrabWorld) getWorld()).eatenWorm();
        //}
    }
I've tried using Worm.class for the argument for .contains() but it doesn't recognize that as an Object. I'm now wondering if it's even possible to reference the specific Objects that are inside the List. If anyone could help me out that would be great. Thanks! P.S. I've also imported the List from java.util, so that's not the issue.
danpost danpost

2015/2/16

#
First, the list will never contain the worm created by using 'new Worm()'. How can the new worm be in the list if you just created it?! Next, 'Worm.class' as an argument in 'contains' would mean you are trying to find the class in the list, not any object of that class. However, 'Worm.class' as an argument in 'getIntersectingObects' might serve your puposes. Then all objects in the list will be Worm type objects.
Abomb1126 Abomb1126

2015/2/16

#
That makes sense. And that 'new Worm()' arguement was just a last resort trying to find something to work. Now the "Worm.class' argument for 'getIntersectingObjects' would be nice, if I was only looking for instances where I cross over a worm. However, I am looking for all the possible collisions, and depending on what is in the list (could be Lobster, Worm, ect) I want to do different things. For example, If a worm object is in the list, I want to "eat" that worm, by destroying it from the world. Now, if the lobster was in list, I want to send the Crab back to the spawn position. I am looking for 1. Something to refence Worm to so I can destroy it properly, and 2. Detect difference objects within the same frame.
Abomb1126 Abomb1126

2015/2/16

#
Here's an update from what I've worked with. I've tried the approch you've suggested with the 'Worm.class'. And it works great. However, I cannot get a hold of the reference to be able to remove the worm that I need.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void detectCollision()
    {
        List wormCollision = getIntersectingObjects(Worm.class);
        System.out.println(wormCollision);
         
        if(!wormCollision.isEmpty()){
            //world.removeObject((Worm)wormCollision.get(0));
            System.out.println("Eating Worm!");
        }
         
        //if(worm != null)
        //{
        //    world.removeObject(((Worm)worm));
        //    Greenfoot.playSound("eating.wav");
        //    wormsEaten++;
        //    ((CrabWorld) getWorld()).eatenWorm();
        //}
    }
Now, under the 'isEmpty' condition, I've commented something out that I tried. My reference to the world is trying to remove an object. I'm using the wormCollision index of 0 (The first entry I assumed) and typecasted it to be a worm. Without the typecast, it does not compile saying the method cannot be applied to the given types. It's found an object when it needs an actor. Now I understood that and typecasted it to a worm, but now when I collide with a worm in-game (It compiles correctly), it throws a null pointer exception of the method argument. I don't know where to get this reference to complete the task that I want to. To answer my own previous question, I can just make a new list of all the "Lobster.class" that I am colliding with and do what I want accordingly, although, if ever in the future I want to do something with the Lobster Itself, I'm going to need the same referencing techniques.
danpost danpost

2015/2/16

#
You can loop through all intersecting object (of all types) with:
1
for (Object obj : getIntersectingObjects(null))
Then within the 'for' code block you can use lines similar to this:
1
if (obj instanceof Worm)
to determine which type of actor and do what you need to do depending on its type. If you are not calling any methods or trying to access any fields located within your subclasses of Actor, you can put the following as a first line in the 'for' code block:
1
2
3
Actor actor = (Actor) obj;
// and use lines like this instead of the one above
if (actor instanceof Worm)
Creating the Actor type variable is necessary because the World class method 'removeObject' requires an Actor type parameter (an Object type will not work).
danpost danpost

2015/2/16

#
Abomb1126 wrote...
I cannot get a hold of the reference to be able to remove the worm that I need.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void detectCollision()
{
    List wormCollision = getIntersectingObjects(Worm.class);
    System.out.println(wormCollision);
     
    if(!wormCollision.isEmpty()){
        //world.removeObject((Worm)wormCollision.get(0));
        System.out.println("Eating Worm!");
    }
     
    //if(worm != null)
    //{
    //    world.removeObject(((Worm)worm));
    //    Greenfoot.playSound("eating.wav");
    //    wormsEaten++;
    //    ((CrabWorld) getWorld()).eatenWorm();
    //}
}
In line 11, you use a variable called 'worm'. I do not see where that variable is declared. As an alternative, you could use something like this to remove all intersecting worms:
1
2
3
4
5
6
while (isTouching(Worm.class)){
    Greenfoot.playSound("eating.wav");
    removeTouching(Worm.class);
    wormsEaten++;
    ((CrabWorld)getWorld()).eatenWorm();
}
Followed by:
1
2
if (isTouching(Lobster.class)){
    // etc.
Abomb1126 Abomb1126

2015/2/16

#
The commented out section below is only reference to previous attempts, just disregard them.
Abomb1126 Abomb1126

2015/2/17

#
Okay, that helped. Now I have a nother problem. Once detected by the lobster, I call a looseLife() method.
1
2
3
4
5
6
7
8
9
10
11
public void looseLife()
    {
        lives--;
        if(lives>0){
            setLocation(280, 280);
            setRotation(0);
             
        }else{
            world.removeObject(this);
        }
    }
The world.removeObject(this); isn't seem to be working. 'this' aperently is not a Actor, and no matter what I do, typecast it and such, it doesn't work. P.S. This is in the Crab class, and if it touches the lobster it destroys itself.
danpost danpost

2015/2/17

#
It is not 'this' that is the problem. 'this', in itself, will never fail in a non-static method. It refers to the object the method is being executed for. The problem is 'world'. 'world' is not declared within the method and if not declared in the Crab class, the compiler will find the 'private World world' field in the Actor class. As a private field, you cannot access it directly; you need to use the Actor class 'getWorld()' method which returns what World object may be referenced in the field:
1
getWorld().removeObject(this);
davmac davmac

2015/2/17

#
Minor quibble but:
1
public void looseLife()
"Lose" is spelled as "lose". "loose" is how you describe a nut that needs tightening.
You need to login to post a reply.