Hi Everyone!
I am struggling with trigonometry.
In my top down shooter game, I am trying to set the position of the bullet when the player shoots, but I cannot find the working solution and it drives me crazy. I am really bad in trigonometry (that’s my Sin…bad joke, I know :D), so if anyone could help me fixing my code that would be very good.
Here is my problem with a screenshot:
As you can see the bullet is always a bit above the gun (it is always on the top of the Origin of the texture).
The full source code is here:
Dropbox link
I was following different tutorials, and the best what I found calculates the angle and the position like this:
MouseState mouse = Mouse.GetState();
Vector2 mousePosition = new Vector2(mouse.Position.X, mouse.Position.Y);
//This is the player on the picture.
Vector2 survivorPosition = new Vector2(RectangleSurvivorDestination.X, RectangleSurvivorDestination.Y);
Vector2 vector = (mousePosition - survivorPosition);
if(vector != Vector2.Zero)
Vector2.Normalize(vector);
AngleSurvivor = (float)Math.Atan2(vector.Y, vector.X);
AngleBullet = AngleSurvivor;
//So far so good, the player and even the bullet is rotating properly.
/*THIS IS THE INCORRECT SECTION I GUESS*/
//The player texture width is 77px, height is 33px. I used hard-coded values
//for better readability.
//(77.0f / 2.0f) - this is because the Origin is the center of the image and I
//wanted the bullet to come from out of the barrel of the gun.
//(33.0f / 1.0f) - the gun is not at the center of the image, so I wanted to
//shift the bullet down to the barrel. Maybe this is wrong.
Vector2 bulletPosition = new Vector2(
(float)(survivorPosition.X + (77.0f / 2.0f) * Math.Cos(AngleSurvivor)),
(float)(survivorPosition.Y + (33.0f / 1.0f) * Math.Sin(AngleSurvivor)));
RectangleBulletDestination = new Rectangle(
(int)bulletPosition.X, (int)bulletPosition.Y,
RectangleBulletDestination.Width, RectangleBulletDestination.Height);
Any ideas?
Thank you in advance!
Looks like a simple alignment problem, from your pictures…
The bullet looks like its off by the same amount in all the pics, so you could probably value-tweak your way out… Would be my guess…
But I think you should have this:
First find by how much the muzzle is different from the player. I store this in a vector2… differenceVector = new Vector2( gunLength, body width/2)…
This “difference” vector can now be used to determine the position of the muzzle, using the rotation of the player…
I always use some variance of this:
public static Vector2 RotateVector2(Vector2 point, float radians, Vector2 pivot)
{
float cosRadians = (float)Math.Cos(radians);
float sinRadians = (float)Math.Sin(radians);
Vector2 translatedPoint = new Vector2();
translatedPoint.X = point.X - pivot.X;
translatedPoint.Y = point.Y - pivot.Y;
Vector2 rotatedPoint = new Vector2();
rotatedPoint.X = translatedPoint.X * cosRadians - translatedPoint.Y * sinRadians + pivot.X;
rotatedPoint.Y = translatedPoint.X * sinRadians + translatedPoint.Y * cosRadians + pivot.Y;
return rotatedPoint;
}
Its a method that takes the point you want spun, the amount you want it spun, and the position you want it spun around, and returns a new position…
In your case that would be something like:
MuzzlePos = playerPos + diffenceVector;
muzzlePos = RotateVector2(muzzlePos, playerRotation, playerPos)
you can even change the differenceVector to allow for recoil very easily…
Having a muzzle pos is also usefull for smoke and flash effects…
Then of course you spawn your bullet on the muzzle pos…
You are a god, no less!
Thank you very much! One day I will re-learn all these trigonometry things…
lol, I’m gonna tell my mom, she’ll be pleased…
I use that method and a few other ones in a “common methods/functions” static class in my games…
I also have one for “is the point above or below the line”…
-They return values from overloads only, so I have no trouble with them being global…
1 Like
Yes, obviously I also put this into a static class and it serves me well since then!
The solution I attached was just a pure test app, without my so-called “engine” and without any proper project/code architecture.