Okay, here's my problem. The game I'm making is a 2D platformer, where you use the keyboard to move the guy around. When you click somewhere on the screen, your shot is supposed to make a beeline for the coordinate you just clicked. Somehow, I need to calculate the projectile's "slope".
Assume that (0,0) is the top-left coordinate of the screen, and (3,3) is the bottom-right. If my player is at (0,3), and I click at (1,1), then my shot should move at a rate of 1 unit horinzontally, and -2 units vertically, right That's easy to calculate, because you just subtract the player's coordinates from the click coordinates. If I click at (2,-1), however the movement rate should still be the same... simply subtracting (0,3) from (2,-1) won't work anymore, because that would come out to (2,-4), which is double the movement rate that I want.
I guess the basic problem is that subtracting the origin from the destination only gives the the units travelled, not the relative slope. I'm guessing I'd have to do some division somewhere to get the slope, but I'm not sure where.
I should add, the end goal here is to calculate some relative x/y movement rate.
ie, 0.5 unit left for every 1 unit up, or 1 unit left for every .25 units down, or whatever.
I'm trying to get an x/y movement ratio here, so that either x or y is 1, and the other number is zero-point-something. Can anyone help

Calculate "slope"
KumarB
I'm kind of confused now, from all these different variables flying around. This is the code so far:
// x + y are mouse click coordinates
public void Shoot( int x, int y )
{
if (_painState == HeroPainState.Dying || _painState == HeroPainState.Dead
|| _painState == HeroPainState.Exiting || _painState == HeroPainState.Exited)
return;
float xStart = CentreX; // horizontal/vertical centre of hero
float yStart = CentreY;
float xDif = (x - xStart); // difference between starting point and click coordinates
float yDif = (y - yStart);
float slope = yDif / xDif; // Rise over run, right
float xMove = 0;
float yMove = 0;
if (xDif > yDif) // Here I attempt to calculate the relative x/y movement rate
{
xMove = 1;
yMove = slope;
}
else if(yDif > xDif)
{
xMove = slope;
yMove = 1;
}
_heroShot.Shoot( xStart, yStart, xMove, yMove );
}
...but it's not working. The speed of the shot varies, and sometimes goes in a different direction than the one that was clicked. In other cases, it's so blindingly fast you can't even see it.
MikeWarriner
One other tip. Rather than have variables called xSomething and ySomething you might want to start using a Vector2 to store these things since thats what they are. YOu can get at the components easily if you need them and you can add and subtract them in one step. The formula I gave you is called normalizing - Vector2.Normalize() would do the same thing. The code looks much neater
public void Shoot( Vector2 location )
{
if (_painState == HeroPainState.Dying || _painState == HeroPainState.Dead
|| _painState == HeroPainState.Exiting || _painState == HeroPainState.Exited)
return;
Vector2 shotDirection = location - Center;
shotDirection.Normalize();
_heroShot.Shoot( Center, shotDirection );
}
Rich Wilson
Jedig33k
Dvorak Pavel
You are half way there. Do some google searches for normalizing vectors.
You don't actually need one of the components to be 1, you need the length of the vector to be 1. You get this by dividing each component byt sqrt(x*x, y* y) - basic trig. There is a normalize function on vector2 in directx to do this for you.
whyme
xmove = xdif /math.sqrt(xdif*xdif + ydif * ydif);
ymove = ydif/math.sqrt(xdif*xdif + ydif * ydif);
This will give you a vector that is one unit long.... you can multiply both components by a constant to give you the speed you want.
This is pretty basic game math you won't get far without picking up a good book - I recommend this one