Allegro.cc Forums » Programming Questions » Bullet move in certain direction based on mouse

 Bullet move in certain direction based on mouse
 Mindsc2tv Member #14,277 May 2012 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).
 SpectreNectar Member #10,969 May 2009 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); 
 Mindsc2tv Member #14,277 May 2012 I would like to move bullet in the direction of the mouse pointer, not to the exact point :-).
 Stas B. Member #9,615 March 2008 Mindsc2tv said: I would like to move bullet in the direction of the mouse pointer, not to the exact point :-). That's what his code does.
 Mindsc2tv Member #14,277 May 2012 Now I see. "sp" stands for speed?
 Edgar Reynaldo Member #8,592 May 2007 @SpectreNectar - why do you convert to allegro degrees and then back? Just use radians....double bullet_direction = atan2(mousey - bullety , mousex - bulletx); bulletx += speed*cos(bullet_direction); bullety += speed*sin(bullet_direction); 
 Mindsc2tv Member #14,277 May 2012 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: #SelectExpand 1Bullet *bullet = new Bullet (player->GetX() + 10, player->GetY()+15); 2double dir = atan2(pos_y - bullet->GetY() , pos_x - bullet->GetX()); 3bullet->SetDirX(dir); 4bullet->SetDirY(dir); 5//bullet->bullDirection = !player->animationRow; 6objects.push_back(bullet); Bullet update: #SelectExpand 2void Bullet:: Update() 3{ 4 //if(this->bullDirection) 5 //{ 6 //x += dirX; 7 //y += dirY ; 8 9 x += velX*cos(dirX); 10 y += velY*sin(dirY); 11 //} 12 //else 13 //{ 14 //x -= velX * dirX; 15 //y += velY * dirY; 16 //} 17 if(x>WIDTH || x< 0) 18 Collided(BORDER); 19}
 Arthur Kalliokoski Second in Command February 2005 Mindsc2tv said: 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? “Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”― Robert A. Heinlein
 Edgar Reynaldo Member #8,592 May 2007 Quote: bullet->SetDirX(dir); bullet->SetDirY(dir);  Umm, what's this about? Is Dir your name for velocity?bullet->SetXVelocity(speed*cos(dir)); bullet->SetYVelocity(speed*sin(dir)); 
 SpectreNectar Member #10,969 May 2009 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.
 Mindsc2tv Member #14,277 May 2012 Arthur Kalliokoski said:You mean you want the bullet to go toward the mouse pointer, but not stop there? Exactly.Edgar Reynaldo said: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.
 Stas B. Member #9,615 March 2008 Mindsc2tv said: 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?
 Edgar Reynaldo Member #8,592 May 2007 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...
 Mindsc2tv Member #14,277 May 2012 Those are double. Actually dirX = dirY and velX = velY. Names are different because of old system of shooting.
 Stas B. Member #9,615 March 2008 Your old code:x += velX*cos(dirX); y += velY*sin(dirY);  Should be:x += speed*cos(dir); y += speed*sin(dir);  I'm guessing what's going on is that velY = 0, so you only get left\right.
 Mindsc2tv Member #14,277 May 2012 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 .
 Edgar Reynaldo Member #8,592 May 2007
 Mindsc2tv Member #14,277 May 2012  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); }  #SelectExpand 1void Bullet:: Update() 2{ 3 //if(this->bullDirection) 4 //{ 5 //x += dirX; 6 //y += dirY ; 7 velY = 1; //it's pretty hardcoded, I don't know why velY was 0 8 x += velX*cos(dirX); 9 y += velY*sin(dirY); 10 //} 11 //else 12 //{ 13 //x -= velX * dirX; 14 //y += velY * dirY; 15 //} 16 if(x>WIDTH || x< 0) 17 Collided(BORDER); 18} Ignore the dirX and dirY, those have the same values, I'll change the names later. Same for velX and VelY.
 Stas B. Member #9,615 March 2008 Oh, atan2 is tricky.double dir = atan2(pos_y - bullet->GetY() , pos_x - bullet->GetX());  Should be:double dir = atan2(bullet->GetY() - pos_y , pos_x - bullet->GetX()); 
 Mindsc2tv Member #14,277 May 2012 Stas B. said: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.
 SpectreNectar Member #10,969 May 2009 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
 Edgar Reynaldo Member #8,592 May 2007 @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.direction = atan2(pos_y - bullet->GetY() , pos_x - bullet->GetX()); bullet->SetXVelocity(bullet->Speed()*cos(direction)); bullet->SetYVelocity(bullet->Speed()*sin(direction));  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.
 Mindsc2tv Member #14,277 May 2012 @EditNevermind, it's working, thank you so much!
 Stas B. Member #9,615 March 2008 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.
 Edgar Reynaldo Member #8,592 May 2007 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); } 
 Go to: Allegro Development Installation, Setup & Configuration Allegro.cc Comments Off-Topic Ordeals The Depot Game Design & Concepts Programming Questions Recent Threads