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

2013/4/18

Getting dx, dy relative to x,y?

Monson Monson

2013/4/18

#
Hi! I've studied the List getObjectsAtOffset() and the Actor getObjectsAtOffset() methods, but is there some neat way to obtain a point dx, dy relative to an object's x,y position and rotation? Say we had a 2D scenario with two actors: Actor one is a person riding a scooter, and actor two is the passenger. Suppose the passenger 'sits' 10 pixels 'behind' actor one. How would I go about writing the code for this? Thanks in advance!
danpost danpost

2013/4/18

#
I will call the Scooter object 'scooter and the Person object 'person'. If you put a instance field in the Scooter class to hold the Person object that is in the scooter, call it 'rider'. Have it set to 'null' unless a person in riding; then, set it to the riding person. A simple 'trick' can be used to keep the person (if there is one riding) in his/her appropriate place. Still, in the Scooter class:
1
2
3
4
5
6
7
// immediately after moving the scooter
if (rider != null)
{
    rider.setLocation(getX(), getY())
    rider.setRotation(getRotation());
    rider.move(-10);
}
You could put this code in a method and call it after moving the scooter (call it 'moveRider').
davmac davmac

2013/4/18

#
You mean, you want to calculate the point that is 10 pixels 'behind' some other point (x,y) with a given rotation? First you start with a point that is 10 pixels 'behind' the origin (0,0) with no rotation, i.e. rotation = 0. So:
1
2
int nx = -10;
int ny = 0;
Then you rotate the point according to the desired rotation:
1
2
3
double r = Math.toRadians(getRotation());
nx = nx * Math.cos(r) - ny * Math.sin(r);
ny = ny * Math.cos(r) + nx * Math.sin(r);
Or, because you know the starting values, and because 0 times anything is 0, you can just shorten it to:
1
2
3
double r = Math.toRadians(getRotation());
int nx = -10 * Math.cos(r);
int ny = -10 * Math.sin(r);
Then you translate the point according to the location of (x,y):
1
2
nx += getX();
ny += getY();
Now you have (nx,ny) being the coordinates of the point that is 10 units 'behind' the current actor.
Monson Monson

2013/4/18

#
Thanks! @ danpost - I need two classes because it's a two-player scenario! :-) @ davmac - I'll re-write my code using your math and see if I can make it work! It's a lot of fun making these small games with Greenfoot, but unfortunately my math is a little rusty to say the least!
Monson Monson

2013/4/18

#
Right, I've been experimenting a bit with the math, but I'm still getting some weird results.. Here I'm testing davmac's math with a 'Wing'-object that I've made for the good old Rocket from the Asteroids tutorial:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
    * Stay attached!
    */
   public void stayAttached()
   {
       if (!getObjectsInRange(1000, Rocket.class).isEmpty())
       {
           Rocket rocket = (Rocket) getWorld().getObjects(Rocket.class).get(0);
            
           double nx = -25;
           double ny = 0;
            
           double r = Math.toRadians(getRotation());
            
           nx = -25 * Math.cos(r);
           ny = -25 * Math.sin(r);
 
           setLocation(nx += getX(), ny += getY());
           setRotation(rocket.getRotation()+90);   
       }
   }
As you can see, I'm trying to 'attach' the wing to the spacecraft and make the wing stay 25 pixels left relative from the (center of the) 'Rocket'. The rotation bit works but the wing shoots out towards the edge of the world! :-D I've swapped the ints with doubles because I got mismatch error reports.
davmac davmac

2013/4/18

#
You're using getX() and getY() from the wing itself, likewise for the rotation. So, you're effectively setting the wing to a position relative to itself. If you want it to be relative to the rocket, you should use rocket.getRotation(), rocket.getX() and rocket.getY().
Monson Monson

2013/4/19

#
Got it! Cheers! Here's the code for a 'left wing' object:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
     * Stay attached!
     */
    public void stayAttached()
    {
        if (!getObjectsInRange(1000, Rocket.class).isEmpty())
        {
            Rocket rocket = (Rocket) getWorld().getObjects(Rocket.class).get(0);
             
            double r = Math.toRadians(rocket.getRotation()+90);
             
            double nx = -25 * Math.cos(r);
            double ny = -25 * Math.sin(r);
 
            setLocation(nx += rocket.getX(), ny += rocket.getY());
             
            setRotation(rocket.getRotation()+90);   
        }
    }
Replace the "double r = Math.toRadians(rocket.getRotation()+90);" and the "setRotation(rocket.getRotation()+90);" for the right wing and it's where it should be! :-)
You need to login to post a reply.