Hello. I'm trying to make a side shooting game and I've encountered a problem. I'm trying to make a bullet moving in certain direction based on mouse position. Was thinking for hours about this and I can't figure it out. My bullet update code looks like :
[code] if(this->bullDirection)
{
x += velX * dirX;
y += velY * dirY;
}
else
{
x -= velX * dirX;
y += velY * dirY;
}[/code]
Now it will shoot in two directions based on which side is player facing (left or right) changing only x. Hope you can help me, I should sent my game project to lecturer soon, so I hope you will help me soon(ish).
Would you like the bullet to move towards the mouse or do you want it to move in a direction depending on where the cursor is on screen? Maybe relative to a point?
Here's how to get the direction to the cursor from a point:
double dir = atan2( point_y-mouse_y, mouse_x-point_x )*180.0/ALLEGRO_PI;
(remember to check if the points are equal)
If this isn't what you wanted please clarify
Edit:
Oh yes by the way you might need these as well:
double velocity_x = sp*cos(dir*ALLEGRO_PI/180.0); double velocity_y = -sp*sin(dir*ALLEGRO_PI/180.0);
I would like to move bullet in the direction of the mouse pointer, not to the exact point :-).
I would like to move bullet in the direction of the mouse pointer, not to the exact point :-).
That's what his code does.
Now I see. "sp" stands for speed?
Hm, it's not working for me, but I'm 99% sure I've did something wrong. The bullet is going only into two directions; left or right. Here's my code:
Bullet spawn:
Bullet update:
I would like to move bullet in the direction of the mouse pointer, not to the exact point :-).
You mean you want the bullet to go toward the mouse pointer, but not stop there?
You have to remember to invert the y axis.
Screen co-ordinates go from the top left corner and down while atan2 goes to the right and upwards.
EDIT: Wait disregard this post.
You mean you want the bullet to go toward the mouse pointer, but not stop there?
Exactly.
Umm, what's this about? Is Dir your name for velocity?
To be honest I don't know for what part dirX and dirY stands for, because this part of code was made by my buddy. I'll try to figure it out.
Hm, it's not working for me, but I'm 99% sure I've did something wrong. The bullet is going only into two directions; left or right. Here's my code:
Your code appears to be correct.
What's the type of dirX\dirY?
Perhaps they're being rounded?
It might be correct - but it is confusing. There should only be one direction variable, and only one speed variable, that you then split into component velocities...
Those are double. Actually dirX = dirY and velX = velY. Names are different because of old system of shooting.
Well, it's working, the Y is changing, but I think something's wrong with dir, because the bullets are not going towards the mouse .
Post the code you're currently using.
if(ev.mouse.button &1) { pos_x = ev.mouse.x; pos_y = ev.mouse.y; Bullet *bullet = new Bullet (player->GetX() + 10, player->GetY()+15); double dir = atan2(pos_y - bullet->GetY(), pos_x - bullet->GetX()); bullet->SetDirX(dir); bullet->SetDirY(dir); //bullet->bullDirection = !player->animationRow; //zeby bylo wiadomo w ktorym kierunku ma leciec kula objects.push_back(bullet); }
Ignore the dirX and dirY, those have the same values, I'll change the names later. Same for velX and VelY.
Should be:
double dir = atan2(bullet->GetY() - pos_y , pos_x - bullet->GetX());
I've tried that and nope, that's not it :/. In this case bullets are going in opposite direction, f.e. if I have mouse in right corner, the bullets will go to the down corner.
See my last post. So you want to invert y in atan2() but also invert it in sin().
This is because:
.....................
.....................
.....................
.....................
................X....
.....................
.....................
...X.................
.....................
.....................
Is not the inverted version of:
.....................
.....................
.....................
.....................
...X.................
.....................
.....................
................X....
.....................
.....................
When it comes to angles. Something like this is:
.....................
.....................
.....X...............
.....................
.....................
.....................
.....................
..............X......
.....................
.....................
If I'm wrong then please disregard this post too.
EDIT Also, you're not testing if the points are identical. Using atan2 with 0 as both arguments is very similar to dividing with 0.
EDIT OK Disregard this post as well
@Stas, no that's wrong. For the angle from Point1 to Point2 it should be :
angle = atan2(Point2.y - Point1.y , Point2.x - Point1.x);, so he's right.
Like I said before, DON'T use two variables for direction and speed.
void Bullet::Update() { x += xvel; y += yvel; }
@Spectre, no that's wrong. You don't need to invert anything. If you keep everything in screen coordinates or in world coordinates and then convert to screen coordinates later, you're fine.
Don't invert anything.
@Edit
Nevermind, it's working, thank you so much!
Gosh. Just do what Edgar Reynaldo says...
Your velX and velY things probably just scale the result in a non-uniform way and mess it up.
Oh, I think I see what you're doing wrong. You're mixing screen and world coordinates together. That's a no no.
So, you want to get the world coordinates of the mouse, and use those instead.
Something like :
// screen = world - camera; // world = camera + screen; if(ev.mouse.button &1) { pos_x = camera_x + ev.mouse.x; pos_y = camera_y + ev.mouse.y; Bullet *bullet = new Bullet (player->GetX() + 10, player->GetY()+15); double dir = atan2(pos_y - bullet->GetY(), pos_x - bullet->GetX()); bullet->SetXVel(bullet->Speed()*cos(dir)); bullet->SetYVel(bullet->Speed()*sin(dir)); objects.push_back(bullet); }