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

2013/10/11

A Bullet That Moves To Center Of Screen

cruelrabbit cruelrabbit

2013/10/11

#
Hi! I have a turret that moves in a circle around the edge of the screen, and fires towards the center of the screen. The problem is that the bullets move in an "L" shaped path instead of a nice, smooth triangular path. Here is the relevant function for the bullet -
public void moveToCenter()
    {
        if (getX() > 280)
        {
            setLocation(getX()-1, getY());
        }
        if (getX() < 280)
        {
            setLocation(getX()+1, getY());
        }
        if (getY() > 280)
        {
            setLocation(getX(), getY()-1);
        }
        if (getY() < 280)
        {
            setLocation(getX(), getY()+1);
        }
    }    
What am I missing? How do I get the bullet to move in a diagonal?
danpost danpost

2013/10/11

#
Have the bullet save its original starting point coordinates in int fields and add a third int field to track the distance from that point. Then, just move the actor back to the starting point and move the extra distance each act cycle. What your code above is doing: by moving one pixel up or down and/or one pixel left or right, you are restricting all but eight possible angles to move in. Pixels are the smallest unit of movement for an actor and from the center location as shown below only the eight surrounding locations can be arrived at by moving (getX() +/- 1, getY() +/- 1). X X X X 0 X X X X Keep in mind however, that even with exact angular movement (in int degrees), arriving at the exact center of the world would happen less often then ending up there. So, my method above will pass close to the center and keep on going unless you remove the bullet when in comes in an area located around the center of the window. As you did not give any information as to what happens after the center is reached, I am not able to help there.
cruelrabbit cruelrabbit

2013/10/11

#
Sorry, I'm a bit of a noob and I'm not entirely sure what you mean. How would I track the distance?
JetLennit JetLennit

2013/10/11

#
I think this is what you want... Try something like this maybe
public void moveToCenter()  
    {  
        int centX = (getWorld().getWidth())/2;
        int centY = (getWorld().getHeight())/2;
        if(getX() == centX() && getY() == centY)
        {
               //whatever happens when it is in the middle
         }
         else
         {
                turnTowards(centY, centX);
                move(5);
         }
    }    
danpost danpost

2013/10/11

#
Add these instance fields:
private int origX;
private int origY;
private int distance;
set the 'origX' and 'origY' fields in an 'addedToWorld' method (called automatically by the system when the actor is added into a world):
public void addedToWorld(World world)
{
    origX = getX();
    origY = getY();
    turnTowards(world.getWidth()/2, world.getHeight()/2); // or (280, 280)
}
with this act method
public void act()
{
    distance++;
    setLocation(origX, origY);
    move(distance);
}
Like I said before, the bullet will travel along an angle that is exactly at a degree mark as the rotation can only be set to int degrees; so, hitting the exact center is somewhat unlikely percentage-wise. What you could do is after the distance gets to some number, maybe around 140 (one-half the way to the middle from the edge), is to split the movement in half, readjusting the angle by applying another turnTowards(280, 280); before moving the second half, like so:
public void act()
{
    setLocation(origX, origY); // move back to origin
    distance++; // increase the distance from origin
    turnTowards(280, 280); // turn toward middle
    int moveDistance = distance; // set up field to hold partial move distances
    if (distance > 140) // distance is large -- split move into two parts
    {
        moveDistance = distance/2; // get half the distance (do not worry about remainder here)
        move(moveDistance); // move half the distance
        turnTowards(280, 280); // readjust angle to move
        moveDistance = distance - moveDistance; // get rest of move distance (this gets remainder)
    }
    move(moveDistance); // move remaining distance (which could be the whole distance)
}
This should make the bullet approach real close to the center, but could still by-pass it without landing on it.
cruelrabbit cruelrabbit

2013/10/12

#
Wow, thanks guys! I will try this out later today and let you know how it goes. Thanks again!
You need to login to post a reply.