Bullets in all directions
kebapmanager

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

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.

kebapmanager

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

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.

Jeff Bernard

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?

kebapmanager

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

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

Jeff Bernard

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.

Arthur Kalliokoski

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.

kebapmanager

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

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.

StevenVI

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.

kebapmanager

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

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.

kebapmanager

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

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;

Jonatan Hedborg

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

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

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.

l j

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

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

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.

kebapmanager

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

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

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

kebapmanager

ok tnx alot guys :D

Thread #612478. Printed from Allegro.cc