Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Bullets in all directions

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Bullets in all directions
kebapmanager
Member #14,863
January 2013
avatar

I made my player shoot bullets in 2 directions , left and right ,but now I want it to shoot bullets in direction of my mouse , wich would mean in all possible directions , but I have no clue how is this gona work , I would really apriciet some help on tip of how to do this

Jeff Bernard
Member #6,698
December 2005
avatar

Use atan2 to figure out the angle between the mouse and the player, and then use that angle to get the correct dx and dy.

--
I thought I was wrong once, but I was mistaken.

kebapmanager
Member #14,863
January 2013
avatar

I am not shure I know how to use atan2 ,I get error :function declaration conflicts with 'atan2' introduced by using-declaration

and I just copied taht atan2 line from refference u linked me :/
can u explain me a bit more of what values should I use.

pkrcel
Member #14,001
February 2012

atan2 is in the math header....did you copypaste also the leading double?

On the other hand your problem requires you to deal with basic trigonometry, either explicitly calculating angles using arc-tangent function or using vector math (for james_lohr joy)...so you need to read-up something about it if you're not already familiar with it.

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Jeff Bernard
Member #6,698
December 2005
avatar

I am not shure I know how to use atan2 ,I get error :function declaration conflicts with 'atan2' introduced by using-declaration

Don't redeclare atan2, either #include <math.h> if you're C or #include <cmath> if you're C++.

The angle of the vector you're computing is the line from your player to your mouse, which you compute by taking the difference in coordinates, so you'll want something like this:

float angle = atan2(mouse_y-player_y, mouse_x-player_x); // maybe you actually want player_(x,y) to be the center of the player, or some other point?

--
I thought I was wrong once, but I was mistaken.

kebapmanager
Member #14,863
January 2013
avatar

Yeah I forgot to mention I am in c++, and thank you for explainig this to me my line looks like this now :
float angle = atan2(mouse.x - mario.x , mouse.y - mario.y); ( edit: should I replace x and y and yeah my player is mario XD)

I am shure its gona work as soon as I resolve this : 'cmath.h': No such file or directory ...

Arthur Kalliokoski
Second in Command
February 2005
avatar

Either <cmath> or <math.h, but not <cmath.h> in this millennium.

They all watch too much MSNBC... they get ideas.

Jeff Bernard
Member #6,698
December 2005
avatar

atan2(mouse.x - mario.x , mouse.y - mario.y); ( edit: should I replace x and y and yeah my player is mario XD)

The guy that wrote atan2 was drunk (or knew stuff about math that I don't), but the y component is the first argument, x is second.

--
I thought I was wrong once, but I was mistaken.

Arthur Kalliokoski
Second in Command
February 2005
avatar

Straight from my man page:

double atan2(double y, double x);

and I looked it up just yesterday because I couldn't remember the order.

They all watch too much MSNBC... they get ideas.

kebapmanager
Member #14,863
January 2013
avatar

Artur I just figured taht out :P ,but yet errors :S

'atan2' : ambiguous call to overloaded function

and gives me some examples :

could be 'long double atan2(long double,long double)'
or 'float atan2(float,float)'
or 'double atan2(double,double)'

ahmmm I got no clue why my code is wrong O.o ,and yeah its really weird how y is before x ;D

pkrcel
Member #14,001
February 2012

Actually it's quite usual to think as the tangent as the ratio of the "vertical" side of the triangle and the "horizontal" one, so I think that's why the Y component is seen first.

EDIT: How are you X and Y components declared?

EDIT2: to clarify, return type does not identify the called function but ONLY the argument type, if you defined your X an Y compenents as ints the compiler is unable to determine to what them should be cast.

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

StevenVI
Member #562
July 2000
avatar

The guy that wrote atan2 was drunk (or knew stuff about math that I don't), but the y component is the first argument, x is second.

The function returns an output based on the arctangent of y / x, which is why y comes first.

Edit: Simply using atan(y/x) does not account for the quadrant the point is in and thus can only return a value in <math>[-\pi/2, \pi/2]</math>. In other words, only half of the angles on a unit circle can be represented. It also could result in a division by zero.

__________________________________________________
Skoobalon Software
[ Lander! v2.5 ] [ Zonic the Hog v1.1 ] [ Raid 2 v1.0 ]

kebapmanager
Member #14,863
January 2013
avatar

Tbh guys , ahmm I am just begginer in this hole programming thing , and I would really like if someone can just show me example(c++) , because all I want is my bullet have direction towards mouse pointer :/

EDIT : I got the function working , but I am just getting taht angle wich is angle from what? , from 0,0 or ? and how to amke it angle from my mouse .

StevenVI
Member #562
July 2000
avatar

Without seeing your code I can't comment on what you're doing wrong, but here's a quick test program that I wrote demonstrating the use of atan2. You can see that I like to use the olde fashioned C-style output over C++'s way:

atan2test.cc#SelectExpand
1#include <stdio.h> 2#include <cmath> 3 4int main() { 5 double player_x = 10; 6 double player_y = 10; 7 double mouse_x = 100; 8 double mouse_y = 100; 9 double angle = atan2(mouse_y - player_y, mouse_x - player_x); 10 printf("Angle between player and mouse is %f\n", angle); 11 return 0; 12}

I get the following output:

Angle between player and mouse is 0.785398

This is approximately <math>\pi/4</math>, which is the angle that we would expect.

Edit: In response to your edit...

I got the function working , but I am just getting taht angle wich is angle from what? , from 0,0 or ? and how to amke it angle from my mouse .

It is the angle between the mouse and your player, in radians:
{"name":"607470","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/9\/49aa36391b11c62e67219bdd6b09509f.png","w":362,"h":276,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/9\/49aa36391b11c62e67219bdd6b09509f"}607470
Note that in this diagram, it assumes that the registration point for your player is at their feet, which may or may not be the case.

__________________________________________________
Skoobalon Software
[ Lander! v2.5 ] [ Zonic the Hog v1.1 ] [ Raid 2 v1.0 ]

kebapmanager
Member #14,863
January 2013
avatar

ok I got it all working about atan2 , but I still dont understand wich values am I gona give to my bullets speedx and speedy like , whta is the use of angle? , am I gona give angle to booth my x and y ? ( <-- then it would go diagonaly on 45 degrees)

Jeff Bernard
Member #6,698
December 2005
avatar

You use more trigonometry for updating the position.

// once you have the angle, calculate values to add to x and y that will make
// the bullet travel along the hypotenuse of the triangle in Steven's illustration
// at a certain speed
float dx = bullet_speed*cos(angle);
float dy = bullet_speed*sin(angle);

//...

// then when it comes time in your game loop to update the bullet's position,
// all the hard work is already done, you've just got two single values to add:
bullet_x += dx;
bullet_y += dy;

--
I thought I was wrong once, but I was mistaken.

Jonatan Hedborg
Member #4,886
July 2004
avatar

Generally it'll probably be faster to do:

// (untested code)

// Instead of getting the angle and then using that to get the vector for that angle...
// We normalize the difference between player and mouse. Unless my math escapes me, it should give the same result.

float dx = mouse.x - mario.x;
float dy = mouse.y - mario.y;
float length = sqrt(dx*dx + dy*dy);
dx /= length;
dy /= length;

dx = dx * bullet_speed;
dy = dy * bullet_speed;

Than using atan2, sin and cos. But YMMV...

Of course, if you actually need the angle to draw something in the correct direction, you may as well use atan2 directly.

And lastly, ignore this post since you shouldn't optimize unless you need to :)

kebapmanager
Member #14,863
January 2013
avatar

I just wanted to tell you taht I got it full working , only problem is its updating my bullets direction while bullet is live and I am moving my mouse , so it kinda folows it , but I got idea why taht is happening , thank you everyone its good to know there are still alot of people who are wiling to help with problems that may seem funny to them :P

jonathan I am not shure what are u talking about ,but Il shure chechk it out :D

Thank you everonye.

Arthur Kalliokoski
Second in Command
February 2005
avatar

only problem is its updating my bullets direction while bullet is live and I am moving my mouse

You should only set the bullet direction ONCE, (firing the gun), then you let the bullet continue by adding dx to bulletx and dy to bullety in a loop. Naturally you stop when it hits an obstruction or goes off screen.

They all watch too much MSNBC... they get ideas.

l j
Member #10,584
January 2009
avatar

You should only set the bullet direction ONCE

so it kinda folows it , but I got idea why taht is happening

I think he already realizes that.

edit: Damn you '>'

kebapmanager
Member #14,863
January 2013
avatar

Yeah I solved the problem with bullet changing direction while me moving mouse , but only 1 thing bothers me and tahts is why I cant use struct variable in atan2

marioy= mario.y
mariox= mario.x
float angle = atan2(mouse.y - marioy, mouse.x - mariox); <--- what I use now

what I woud like to use

float angle = atan2(mouse.y - mario.y, mouse.x - mario.x); <--- sends out error :

atan2' : ambiguous call to overloaded function .... stupid atan2

Jeff Bernard
Member #6,698
December 2005
avatar

What are the types of mouse.x/y, mario.x/y, and mariox/marioy?

Like pkrcel mentioned earlier, if you use int then the compiler might not know whether it should cast to float or double (or I guess apparently long double). I'm guessing mariox/marioy are float and the others are int? In that case, mouse.y/y gets casted to float for the subtraction, and then you're left with a float to pass into atan2 so the compiler knows which version to use.

--
I thought I was wrong once, but I was mistaken.

kebapmanager
Member #14,863
January 2013
avatar

Yes they were int , now I replaced int with float , and it works , thanks alot for this explanation , but why cant it be int? , because it cant hold decimals?

Pls tell me if I am annyoing , but I am really curiouse about this :P

l j
Member #10,584
January 2009
avatar

but why cant it be int? , because it cant hold decimals?

I assume there is no int version because atan2 internally will have to divide y by x and some other things and will require enough precision to get an accurate result.

Jonatan Hedborg
Member #4,886
July 2004
avatar

Since it returns radians (-PI to +PI), int wouldn't really be very helpful.

 1   2 


Go to: