• Create Account

## Bullet animation

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

13 replies to this topic

### #1Slider_SLO  Members

136
Like
0Likes
Like

Posted 11 December 2012 - 10:47 AM

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...

### #2Xaer0  Members

617
Like
4Likes
Like

Posted 11 December 2012 - 11:37 AM

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 hVector2 direction;Vector2 velocity;vector2 position;float bulletSpeed;///when you fire gundirection = playerPos - mousePos;direction.normalize();///In your bullet update///dt is frame delta timevelocity = direction * bulletSpeed * dt;position += velocity;[/source]

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

### #3Yrjö P.  Members

1416
Like
1Likes
Like

Posted 11 December 2012 - 01:15 PM

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.

### #4KnolanCross  Members

1940
Like
1Likes
Like

Posted 11 December 2012 - 03:25 PM

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, 11 December 2012 - 03:26 PM.

Currently working on a scene editor for ORX (http://orx-project.org), using kivy (http://kivy.org).

### #5Yrjö P.  Members

1416
Like
0Likes
Like

Posted 11 December 2012 - 06:25 PM

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.

### #6Slider_SLO  Members

136
Like
0Likes
Like

Posted 12 December 2012 - 03:44 AM

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?

### #7Xaer0  Members

617
Like
0Likes
Like

Posted 12 December 2012 - 04:16 AM

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

### #8KnolanCross  Members

1940
Like
0Likes
Like

Posted 12 December 2012 - 07:33 AM

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.

Currently working on a scene editor for ORX (http://orx-project.org), using kivy (http://kivy.org).

### #9BCullis  Members

1951
Like
1Likes
Like

Posted 12 December 2012 - 11:03 AM

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, 12 December 2012 - 12:35 PM.

Hazard Pay :: FPS/RTS in SharpDX (gathering dust, retained for... historical purposes)
DeviantArt :: Because right-brain needs love too (also pretty neglected these days)

### #10Trienco  Members

2555
Like
1Likes
Like

Posted 12 December 2012 - 11:34 PM

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.
f@dzhttp://festini.device-zero.de

### #11Yrjö P.  Members

1416
Like
0Likes
Like

Posted 13 December 2012 - 07:18 AM

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.

### #12KnolanCross  Members

1940
Like
0Likes
Like

Posted 13 December 2012 - 01:15 PM

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.

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).

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.

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, 13 December 2012 - 01:21 PM.

Currently working on a scene editor for ORX (http://orx-project.org), using kivy (http://kivy.org).

### #13slicer4ever  GDNet+

6360
Like
0Likes
Like

Posted 13 December 2012 - 04:42 PM

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

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

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.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

### #14BCullis  Members

1951
Like
1Likes
Like

Posted 14 December 2012 - 08:10 AM

(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)

Hazard Pay :: FPS/RTS in SharpDX (gathering dust, retained for... historical purposes)
DeviantArt :: Because right-brain needs love too (also pretty neglected these days)

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.