# Bullet animation

This topic is 1865 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Im just wondering if anyone could help me out a bit...
First of all im making topdown 2d shooter with C++ and SDL and iwe got a problem with the bullet animation...
Anyone knows what math code should I use that the ''bullet'' would follow the mouse coordinates and then acctually go in a straight line from char coordinates to mouse coordinates? Tnx for any ideas...

##### Share on other sites
You would probably have to use a little bit of linear algebra for this, a rough idea is to subtract your mouse position from your player position to get the direction vector, then you can normalize it, and every frame that you want to animate the bullet, you just add this direction vector to your velocity and multiply it by the bullets speed (and deltaTime if you have one)

something like,
[source lang="cpp"]///in class h
Vector2 direction;
Vector2 velocity;
vector2 position;
float bulletSpeed;

///when you fire gun
direction = playerPos - mousePos;
direction.normalize();

///dt is frame delta time

velocity = direction * bulletSpeed * dt;

position += velocity;[/source]

Other people will probably have some better ways to go about it, but that should get you started

##### Share on other sites

Other people will probably have some better ways to go about it, but that should get you started
I don't think there are other ways that make any sense, actually.

##### Share on other sites
Actually, depending on his needs, it may be better to use a discrete pixel by pixel method.

You can calculate the angle of the click and the mouse by using:
[source lang="cpp"]angle = atan2f(clickedPosition.y - currentPos.y, clickedPosition.x - currentPos.x);[/source]

Then use the angle to calculate a "final" position, given a maximum distance that a bullet shall move:
[source lang="cpp"]finalX = currentPos.fX + (cos(angle) * maximumMovement);
nextY = currentPos.fY + (sin(angle) * maximumMovement);

[/source]
And finally use the bresenham algorithm to find all the pixels the buttlet would move by:

[source lang="cpp"]void bresenham(unsigned x0, unsigned y0, unsigned x1, unsigned y1){

int dx = absolute(x1-x0);
int dy = absolute(y1-y0);

int sx, sy;
if (x0 < x1){
sx = 1;
}
else{
sx = -1;
}

if (y0 < y1){
sy = 1;
}
else{
sy = -1;
}

int err = dx-dy;
while (!(x0 == x1 && y0 == y1)){

int errTimesTwo = 2 * err;
if (errTimesTwo > -dy){
err -= dy;
x0 = x0 + sx;
}

if (errTimesTwo < dx){
err += dx;
y0 += sy;
}

}

}
[/source]
Of course you would need some adjusts if you want the bullets to be dodgeable/renderable projectiles.
The advantages of this method is that it is really easy to find the bullet path and check for collisions if you need it.

Hope this helps Edited by KnolanCross

##### Share on other sites
The first section there calculates the same location as Xaer0's simple approach, but does it in a more complicated and less efficient manner, thus does not make sense.

Bresenham's algo is almost completely unrelated to the question, and likely does not make sense for him to use in collision detection.

##### Share on other sites
Thanks guys im going to try em all to see what I get...
First just one question from Xaer0 what is that direction.normalize() and how do I use it?

##### Share on other sites
normalizing a vector makes the sum of all the components (x and y in this case) = 1,

http://www.fundza.com/vectors/normalize/index.html

that can explain it MUCH better than I can, very helpful and good to know for future use

##### Share on other sites

The first section there calculates the same location as Xaer0's simple approach, but does it in a more complicated and less efficient manner, thus does not make sense.

Bresenham's algo is almost completely unrelated to the question, and likely does not make sense for him to use in collision detection.

That was a bit rude, but let me clarify:

1) It doesn't do the same thing, it calculates a starting point and a predicted end point. His method calculates a direction and will interpolate it.
2) Atan2f is implemented uses a few ifs and atan, while the normalization uses sqrt, no one is "faster" in this point.
3) Breseham will interpolate using integer operations only, while Xaer0's approach used float point math that is slower.
4) The method Xaer0 suggested may move the bullet several pixels at each time the formula is executed, which may lead the bullet to bypass something it shouldn't (such as a wall). The method that I suggested will give the bullet trajectory, pixel by pixel.

Don't get me wrong, both methods will work, it is just a different approach for the same problem, the advantage is that it gives the tragetory, the disadvantage is that it is slower and a bit harder to use.

##### Share on other sites

Thanks guys im going to try em all to see what I get...
First just one question from Xaer0 what is that direction.normalize() and how do I use it?

Normalizing takes any length of vector and turns it into a "unit" vector, with length 1. This is mostly helpful when calculating things like direction (your case, perfect!), because if you then want to use that direction along with a speed or velocity variable, you don't want the "length" of the direction to interfere with the calculation. For example:

If I click on a point all the way across the screen, the initial vector calculated will be incredible long. That represents both the direction and the distance from the player/vehicle to my clicked point. If I used that vector in a multiplication with my bullet's velocity, it would be magnified by how far away the point was (and therefore, I could fire much faster bullets by clicking far away, and slower ones by clicking near myself). By normalizing it, the distance of that vector is changed to 1, while preserving the "direction" value. Multiplying anything by 1 doesn't change your outcome, so it's safe to use in your bullet velocity and travel case.

Edit: forgot to add, it's also crucial when trying to do other vector math like dot and cross products. Without normalized vectors in those instances, your results will be skewed and/or represent different properties of their related data than what you intended. Edited by BCullis

##### Share on other sites

4) The method Xaer0 suggested may move the bullet several pixels at each time the formula is executed, which may lead the bullet to bypass something it shouldn't (such as a wall). The method that I suggested will give the bullet trajectory, pixel by pixel.

This might be a good place to point out that if you do collision detection in "pixel space", you are doing it wrong and should have a close look at why proper collision detection is very different from "checking for intersections every frame". After that you will realize why brute forcing collision detection by moving stuff in a painful pixel by pixel fashion to check every single one along the way is getting you down voted.

Sorry, but every time someone is throwing trigonometry at trivial problems it's making me cry.

##### Share on other sites

1) It doesn't do the same thing, it calculates a starting point and a predicted end point. His method calculates a direction and will interpolate it.
???
There's no interpolation of any kind in Xaer0's code. The only thing it does is directly calculate the end point. The same end point whose components are curiously named "finalX" and "nextY" in your code.

##### Share on other sites

[quote name='KnolanCross' timestamp='1355319181' post='5009816']
4) The method Xaer0 suggested may move the bullet several pixels at each time the formula is executed, which may lead the bullet to bypass something it shouldn't (such as a wall). The method that I suggested will give the bullet trajectory, pixel by pixel.

This might be a good place to point out that if you do collision detection in "pixel space", you are doing it wrong and should have a close look at why proper collision detection is very different from "checking for intersections every frame". After that you will realize why brute forcing collision detection by moving stuff in a painful pixel by pixel fashion to check every single one along the way is getting you down voted.

Sorry, but every time someone is throwing trigonometry at trivial problems it's making me cry.
[/quote]

Sorry I wasn't clear, but I never said he should use pixel by pixel approach on colision, just that this will give him the trajectory that he could use to calculate the collision in a simple way (not using vectors, which is way more complex).

[quote name='KnolanCross' timestamp='1355319181' post='5009816']
1) It doesn't do the same thing, it calculates a starting point and a predicted end point. His method calculates a direction and will interpolate it.
???
There's no interpolation of any kind in Xaer0's code. The only thing it does is directly calculate the end point. The same end point whose components are curiously named "finalX" and "nextY" in your code.
[/quote]

Every dt it will move the bullet, this will interpolate its trajectory.
I took it from a code I use on a game where nextX and nextY was used, it was just adapted to fill the post.

PS: Love how people negativate others without posting a reason around here. Edited by KnolanCross

##### Share on other sites

Actually, depending on his needs, it may be better to use a discrete pixel by pixel method.

You can calculate the angle of the click and the mouse by using:
[source lang="cpp"]angle = atan2f(clickedPosition.y - currentPos.y, clickedPosition.x - currentPos.x);[/source]

Then use the angle to calculate a "final" position, given a maximum distance that a bullet shall move:
[source lang="cpp"]finalX = currentPos.fX + (cos(angle) * maximumMovement);
nextY = currentPos.fY + (sin(angle) * maximumMovement);

[/source]
And finally use the bresenham algorithm to find all the pixels the buttlet would move by:

[source lang="cpp"]void bresenham(unsigned x0, unsigned y0, unsigned x1, unsigned y1){

int dx = absolute(x1-x0);
int dy = absolute(y1-y0);

int sx, sy;
if (x0 < x1){
sx = 1;
}
else{
sx = -1;
}

if (y0 < y1){
sy = 1;
}
else{
sy = -1;
}

int err = dx-dy;
while (!(x0 == x1 && y0 == y1)){

int errTimesTwo = 2 * err;
if (errTimesTwo > -dy){
err -= dy;
x0 = x0 + sx;
}

if (errTimesTwo < dx){
err += dx;
y0 += sy;
}

}

}
[/source]
Of course you would need some adjusts if you want the bullets to be dodgeable/renderable projectiles.
The advantages of this method is that it is really easy to find the bullet path and check for collisions if you need it.

Hope this helps

[quote name='KnolanCross']
PS: Love how people negativate others without posting a reason around here.
[/quote]

since you asked, I downvoted your first post because it's clearly above what the OP is attempting to do, and is imo quite a terrible method for doing collision checks. Xaer0 provided a great explanation about what to do, and is done in linear algebra.

you on the other hand used inconsistent naming convention(finalX, and nextY), didn't explain anything going on in the code you provided(you threw out a name of the algorithm, said what it does, but didn't actually explain how the algorithm achieves what it does, nor how to use it for anything.), that is why i down-voted you.

##### Share on other sites

(snip explanation) ... that is why i down-voted you.

Knolan, you've been around here for a few months, so don't think I'm trying to be patronizing by explaining this. As a forum that does a lot of teaching to beginners and hobbyists in comparison to discourse between experienced programmers, we have to find a balance when sharing information. A negative vote covers areas that include "this is going to confuse the person asking for help, or over-complicates the provided solution scenario".

Just being skilled in a craft doesn't make for a good teacher, it's as important to know how (and how much) to share as knowing what the solution is. While you may be partial to your solution, just like anyone else, is it really, objectively, as easy to implement and straightforward to understand to someone asking for "any" math solutions to a common linear algebra problem? If the answer is honestly "no", then at least indicate as such ("this is another less common approach") and make sure to explain it.

(I minored in math with my undergrad and I have no idea who Bresenham is, it's a likely bet the OP doesn't either, so talking through the algorithm a little would have gone a long way)