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
K_wow K_wow

2013/9/3

#
For my roleplaying game, I want to detect if an astronaut is on a floor panel in the world. Since the floor panel image is 50x50 pixels and the world cell size is 1 pixel, I am using a heap of complicated code to detect the astronaut. This is what I'm using:
    public Actor checkSquareInFront(Class cls)
    {
        int xPos = getX();
        int yPos = getY();
        Actor actorToCheck = null;
        if (direction == 0) // rotation 0
        {
            for (int currentPixel = ((yPos + 25) / 50 * 50) - 50; currentPixel < ((yPos + 25) / 50 * 50); currentPixel++)
            {
                actorToCheck = checkRow(cls, currentPixel, ((xPos + 25) / 50 * 50), 50);
                if (actorToCheck != null)
                {
                    break;
                }
                setLocation(xPos, yPos);
            }
        }
        else if (direction == 1) // rotation 90
        {
            for (int currentPixel = ((yPos + 25) / 50 * 50) + 50; currentPixel < ((yPos + 25) / 50 * 50) + 100; currentPixel++)
            {
                actorToCheck =  checkRow(cls, currentPixel, ((xPos + 25) / 50 * 50) - 50, 50);
                if (actorToCheck != null)
                {
                    break;
                }
                setLocation(xPos, yPos);
            }
        }
        else if (direction == 2) // rotation 180
        {
            for (int currentPixel = ((yPos + 25) / 50 * 50) - 50; currentPixel < ((yPos + 25) / 50 * 50); currentPixel++)
            { 
                actorToCheck = checkRow(cls, currentPixel, ((xPos + 25) / 50 * 50) - 100, 50);
                if (actorToCheck != null)
                {
                    break;
                }
                setLocation(xPos, yPos);
            }
        }
        else if (direction == 3) // rotation 270
        {
            for (int currentPixel = ((yPos + 25) / 50 * 50) - 100; currentPixel < ((yPos + 25) / 50 * 50) - 50; currentPixel++)
            {
                actorToCheck = checkRow(cls, currentPixel, ((xPos + 25) / 50 * 50) - 50, 50);
                if (actorToCheck != null)
                {
                    break;
                }
                setLocation(xPos, yPos);
            }
        }
        setLocation(xPos, yPos);
        return actorToCheck;
    }

    public Actor checkRow(Class cls, int y, int x, int range)
    {
        Actor actorToCheck = null;
        for (int currentPixel = x; currentPixel < x + range; currentPixel++)
        {
            if (currentPixel < getWorld().getWidth() && y < getWorld().getHeight())
            {
                setLocation(currentPixel, y);
                actorToCheck = getOneObjectAtOffset(0, 0, cls);
                if (actorToCheck != null)
                {
                    break;
                }
            }
        }
        return actorToCheck;
    }
It's probably not the best way to do it, but it's the only way I know how. However, with this code, the astronaut is sensed at places where he shouldn't be able to be sensed. I only want to check the floor panel in front of the player, but the player can be up to 100 pixels away. The sensing offset appears to be wrong, as does the amount of pixels to check. Does anyone know how to fix this?
danpost danpost

2013/9/4

#
Please explain exactly when you want 'true' to be the result of the state of intersection of the two images (of the astronaut and the square). Am I correct in presuming this is a top-down view scenario?
K_wow K_wow

2013/9/4

#
This is a top-down view scenario. The code I am using is nothing to do with the intersection of the astronaut and square images. The player teleports to each pixel in the square, checks if the astronaut is there, and once it has teleported to all the pixels it needs to, it teleports back to the individual position. If the astronaut is found within the square, that's when I want to return true.
danpost danpost

2013/9/4

#
Could you not use a different method, like 'getOneIntersectingObject(cls)'?
K_wow K_wow

2013/9/4

#
If I used that, then the astronaut might not be in the square itself. I want to make sure that the center point (or the exact coordinates) is inside the square.
danpost danpost

2013/9/4

#
Then change the image of the astronaut to a single point, use the getOneIntersectingObject(cls) method, then reset the original image of the astronaut.
K_wow K_wow

2013/9/4

#
Do you mean use getOneIntersectingObject(cls) with the player, or the background?
danpost danpost

2013/9/4

#
You could also just compare the x and y of the astronaut to the limits of the image of the square:
public boolean isAstronautHere()
{
    if (!getOneIntersectingObject(Astronaut.class).isEmpty())
    {
        Actor astro = (Actor) getOneIntersectingObject(Astronaut.class);
        return astro.getX() >= getX()-getImage().getWidth()/2 &&
               astro.getX() <= getX()+getImage().getWidth()/2 &&
               astro.getY() >= getY()-getImage().getHeight()/2 &&
               astro.getY() <= getY()+getImage().getHeight()/2;
    }
    return false;
}
K_wow K_wow

2013/9/4

#
Firstly, I'm still not sure whether you are checking the intersection of the player or world image, could you tell me which image you're checking? Secondly, it looks like it will return false anyway, at the end of the method. Thirdly, I need to return the astronaut actor so I can access it's variables, although I think I can fix that myself. Finally, I'm not sure how to code that so that it searches only in the square the player is facing. Sorry if I'm being a bother.
danpost danpost

2013/9/4

#
Obviously 'astro' is an Actor object; and because I use 'getX()' without a prefix, it must be coded in an subclass of Actor (the class that represents the floor panel). (You used 'setLocation' in your code; so, I assumed that the code you have shown was in an Actor subclass -- probably the floor panel one search for an astronaut on it. Maybe you are confused because I did not mention that 'Astronaut' may not be the name of the class of the astronaut object you are trying to detect. In short (if you replaced the name of the class of your astronaut with Astronaut and the code is placed in the class of the floor panel object), this will check to see if the center of the astronaut is anywhere on the floor panel.
K_wow K_wow

2013/9/4

#
My world does not have floor panel objects in it, though. The floor panels are just the world image. I had my code in the player class, and where the player checks to find the astronaut depends on the direction the player is facing. If I were to have the floor panels as individual objects, the player would still have to find the one they were facing, and then call a method from that. I would probably have just as much trouble locating the floor panel object the player is facing as I would finding the astronaut.
danpost danpost

2013/9/4

#
Ok, I think I understand now. You are putting in the player's class code that will detect if the astronaut (an Actor object) in on the floor panel (not an Actor object) in front of him. Do you have a matrix of floor panels in the world? does the matrix cover the entire world background? Does your background scroll? If a full-world matrix of panels, does the first one cover the range (0, 0)-(50, 50)?
K_wow K_wow

2013/9/4

#
Yes, that's it. the floor panels ARE the world background. The background does not scroll. The first one does cover the range (0, 0)-(50, 50), all of the panels are 50x50 pixels. Would it help if I provided a download to the source code?
danpost danpost

2013/9/4

#
Is there only one astronaut at a time? and what is the class name for the astronaut object?
K_wow K_wow

2013/9/4

#
The method will only detect one astronaut, and I don't plan to ever have 2 astronauts on the same floor panel. The class name for the astronaut is "Astronaut.class".
There are more replies on the next page.
1
2