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

2013/9/3

Detecting an object within a square

1
2
danpost danpost

2013/9/4

#
You do not plan to ever have 2 on the same panel; but, you could have more than one in the world :\ What about the astronaut being on the same panel as the player; is that something that could happen?
K_wow K_wow

2013/9/4

#
It shouldn't matter if there is more than one in the world, the player only searches through a specific area. I have code to prevent the player from going on to a panel occupied by an astronaut, but as I said in the original post, the sensing is off, so it doesn't work properly.
danpost danpost

2013/9/4

#
Well, it would make it a little easier to check for if there was only one in the world. Will be working on something for you.
K_wow K_wow

2013/9/4

#
Are you saying it would be easier to have the astronaut in the world class file, and access it from there?
danpost danpost

2013/9/4

#
I am not exactly sure if this is what you were looking for . . . but it should, given a class, return 'true' if any instances of that class are located in the 50x50 panel ahead of the player, provided the player is not facing the edge of the world.
public boolean  actorAhead(Class cls)
{
    int x = getX(), y = getY(); // save current location
    move(50); // move forward
    if (Math.abs(x-getX())+Math.abs(y-getY()) != 50)
    { // on edge panel facing edge
        setLocation(x, y); // return to original location
        return false; // indicate no instances found
    }
    // get root coordinates of panel
    x = (getX()/50)*50; 
    y = (getY()/50)*50;
    move(-50); // move back to original location
    for (Object obj : getWorld().getObjects(Astronaut.class))
    { // for all astronauts in world
        Actor actor = (Actor)obj; // reference an astronaut as Actor
        // if not within limits, process next astronaut
        if (actor.getX() < x) continue;
        if (actor.getX() >= x+50) continue;
        if (actor.getY() < y) continue;
        if (actor.getY() >= y+50) continue;
        // astronaut within limits if here
        return true; //  indicate one was found
    }
    return false; // no astronauts found ahead
}
K_wow wrote...
Are you saying it would be easier to have the astronaut in the world class file, and access it from there?
No. The code provided here should be in the player class code.
K_wow K_wow

2013/9/4

#
So the continue is like the opposite of break, and once the method returns something, it exits, right? Also, could you please make it return an Actor instead? I'm not sure how to do it with that method, considering the unfamiliar code, and I need the method to return an Actor. Thanks for the code though!
K_wow K_wow

2013/9/4

#
I've figured out how to make it return an actor, you don't need to worry about that, but I've run into another problem. Your code uses the "move()" method, which moves the actor, taking into account their rotation. I am not using the rotation variable to define which direction they move, so the rotation of the player is always 0. I am instead using a "direction" method, which is like the rotation divided by four.
danpost danpost

2013/9/4

#
The 'continue;' statement immediately starts the next iteration of the loop. The 'break;' statement exits the loop (or 'switch'). The 'return;' statement immediately exits the method; and to return the actor found (or 'null' if none found):
public Actor actorAhead(Class cls)
{
    int x = getX(), y = getY(); // save current location
    setRotation(90*direction);
    move(50); // move forward
    if (Math.abs(x-getX())+Math.abs(y-getY()) != 50)
    { // on edge panel facing edge
        setLocation(x, y); // return to original location
        setRotation(0);
        return null; // indicate not found
    }
    // get root coordinates of panel
    x = (getX()/50)*50; 
    y = (getY()/50)*50;
    move(-50); // move back to original location
    setRotation(0);
    for (Object obj : getWorld().getObjects(Astronaut.class))
    { // for all instances of given class in world
        Actor actor = (Actor)obj; // reference an instance as Actor
        // if not within limits, process next actor
        if (actor.getX() < x) continue;
        if (actor.getX() >= x+50) continue;
        if (actor.getY() < y) continue;
        if (actor.getY() >= y+50) continue;
        // astronaut within limits if here
        return actor; //  indicate which one found
    }
    return null; // no actors of given class found ahead
}
I accounted for no rotation of the actor, but the field being the angle divided by 90.
K_wow K_wow

2013/9/4

#
Thanks, but now I have the rotation problem. Did you see my last post?
danpost danpost

2013/9/4

#
I updated my last post. It is accounted for there.
K_wow K_wow

2013/9/4

#
IT WORKS! Thank you so much for your help! Now for the much smaller nullPointerException problem:
    public void interact()
    {
        Actor astronaut = actorAhead(Astronaut.class);
        String key = Greenfoot.getKey();
        if(astronaut != null)
        {
            Astronaut astro = (Astronaut)astronaut;
            if (key.equals("enter"))
            {
                getWorld().addObject(new DialogueWindow(astro.headImage, astro.line0), getWorld().getWidth() / 2, getWorld().getHeight() / 2);
            }
        }
    }
the exception points at the line with "if (key.equals("enter")).
danpost danpost

2013/9/4

#
oK! WOW.
K_wow K_wow

2013/9/4

#
Uh oh, looks like another problem! I don't think it's a big one though. I updated my last post.
danpost danpost

2013/9/4

#
That is a common mistake. 'getKey' will only return a String value when a valid key is 'pressed and released'. Otherwise, it will return 'null'. You cannot compare Strings to 'null'; but, you can compare 'null' to Strings. In other worlds: 'key.equals("enter")' could error if 'key' was 'null' '"enter".equals(key)' will never error, even if 'key' was 'null'
K_wow K_wow

2013/9/4

#
That's fixed it, thanks!
You need to login to post a reply.
1
2