GIving a precise vector2 to LinearVelocity

Topics: Developer Forum, User Forum
Feb 22, 2008 at 11:21 PM
I'm trying to make a object with mass 1 travel from a specific point to another point under a gravity of (0,20) 20 downwards. I have the radians angle from my starting point to my ending point, and have measured the horizontal and vertical distances between the two as well. To accomplish this task I'm thinking there has got to be a conversion ratio that I could use to send my object x amount of pixels. To illustrate, I believe I need to find the magic ratio:

float Ax = (float)(horizontalDistanceFromCenter * magicRatio) * (float)Math.Cos(radians);
float Ay = ((float)(verticalDistanceFromCenter * magicRatio) * (float)Math.Sin(radians)) + 20;
ball.BodyObject.LinearVelocity = new Vector2(Ax, Ay);

Any ideas? Am I doing this correctly? TIA.
Feb 23, 2008 at 1:53 AM
I derived equations for the initial velocity:

float Vx = (desiredX - currentX) / travelTime;
float Vy = (desiredY - currentY) / travelTime + 10*travelTime;
ball.BodyObject.LinearVelocity = new Vector2(Vx, Vy);

This will (assuming the physical accuracy of the engine) transport the ball, over a given time interval, to a different position. As long as you have a 1:1 ratio between simulation units and pixels (as long as you draw the objects at the actual location of the objects), this should work. One thing you didn't take into account is that you must specify how long you want the object to take to get where it's going. Let me know how it goes.
Feb 23, 2008 at 3:07 AM
Hmmm, I suppose I could just put in .5 to 1 second for travel time and adjust as needed. Let me try this out and see what happens. Thanks for the reply.
Feb 23, 2008 at 3:10 AM

michael_brooks11 wrote:
I derived equations for the initial velocity:

float Vx = (desiredX - currentX) / travelTime;
float Vy = (desiredY - currentY) / travelTime + 10*travelTime;
ball.BodyObject.LinearVelocity = new Vector2(Vx, Vy);

This will (assuming the physical accuracy of the engine) transport the ball, over a given time interval, to a different position. As long as you have a 1:1 ratio between simulation units and pixels (as long as you draw the objects at the actual location of the objects), this should work. One thing you didn't take into account is that you must specify how long you want the object to take to get where it's going. Let me know how it goes.


I'll play with it, but is travelTime in seconds, ms, or ?
Feb 23, 2008 at 3:30 AM
Here's what I got, thanks for the help:

float horizontalDistance = (float)(mousePosition.X - 502);
float verticalDistance = (float)(mousePosition.Y - 10);
float travelTime = 0.5f;

float Ax = horizontalDistance / travelTime;
float Ay = (verticalDistance / travelTime) + (10 * travelTime);

ball.BodyObject.LinearVelocity = new Vector2(Ax, Ay);

Now at travelTime values lower than 0.5 the ball does seem to go to the intended place, but zips there at an incredible speed usually tunneling through collisions and being not very visible, so it's not ideal. At lower speeds I think the constant affect of gravity is just throwing things out of wack. What I'm thinking I could do is eliminate gravity until the first object is hit and then put it back into place. Would this make it easier to accomplish?
Feb 23, 2008 at 4:10 AM
Eliminating gravity works better, but really detracts from the game. ie: It's realistic when planning a shot. Not sure what to do now...

It almost seems that I need to measure the distance, see how long it takes to travel that distance, and then in my initial vector put the counter to the gravity in that. I only took Physics I so I'm guessing there's some learning involved in doing this. The sucker doesn't need to be NASA precise, but just really close to where the player eventually clicks. I suppose if this is too complex I can come up with another way to shoot the ball out, but this seemed the easiest on the player.
Feb 23, 2008 at 6:15 AM
You probably have to tweak the travelTime to make it work. I suspect that a travel time in milliseconds would be most appropriate (since you typically would call Update on the physics engine with millisecond time intervals). That should reduce the speed of your object as well.

The object should follow a parabolic path from the start location to the specified finish location. There's no way to make it follow a straight path without turning off gravity or manually calculating velocity at every step. The shape of the path depends on how fast you want it to get there.
Coordinator
Feb 23, 2008 at 8:04 PM
I don't think it's a good idea to be always manually adjusting the velocity. The engine was desigend to have things moved around by forces. What you need to do is calculate the vectory force that will "steer" your object toward the destination you want.

You can update this force every loop.

See here for some info on this: http://www.red3d.com/cwr/papers/1999/gdc99steer.html

Can you describe in more detail what you are trying to accomplish. Steering behaviors might not be a good fit, but the engine was not meant to have it's velocity changed from the outside every loop.
Feb 24, 2008 at 1:15 AM
Let me actually get my initial game up to a website to actually show you what I'm trying to do instead of describing it. Right now I'm only setting the initial velocity once when a ball is shot out. I'm trying to get the ball to shoot to where the mouse button was clicked.
Feb 24, 2008 at 1:26 AM
http://blechie.com/Games/MadPegs/testpage.html

The shooter will shoot the ball out and it's supposed to go to where the mouse is clicked. This is supposed to make it easier to make more precise shots so that you can have some control over the bounce of the ball. I've gotten pretty close with just some hacked together math, but figured I'd go for more precise aiming. Does this help make it clearer?
Feb 24, 2008 at 4:42 AM
I got it, big thanks to Michael's head start. The Y component was a bit tricky and the one causing the problems. Here's what I finally came up with, just had the wife play through and she says it's accurate :). Bingo!

float distance = (float)Math.Sqrt(Math.Pow(horizontalDistance,2) + Math.Pow(verticalDistance, 2));
const float pixelDistancePerSecond = 215;
float travelTime = distance / pixelDistancePerSecond;

float Ax = horizontalDistance / travelTime;
float Ay = (verticalDistance - 10 * (float)Math.Pow(travelTime, 2)) / travelTime;
Coordinator
Feb 25, 2008 at 11:06 AM
Glad you got it figured out.

Pretty cool game! Love the sound effects.