Aiming and shooting in a 2D game

991c178cbb1237d5e8e147aae5782cb9
0
TTTNL 101 Mar 09, 2013 at 19:52 c++

So if you followed my previous posts you may know i have got my bullets implemented thanks to you guys and did some work to optimize it a bit. I added an ammo variable and changed the container for the bulletclass from a vector to an fixed size array. And using a for loop that will put every bullets’ “active” boolean to false if it’s of the screen. So there are only 12 bullets (because of the use of an array) but since every bullet that’s off the screen gets put to non active i can use it again when needed, see my code below

spawning a bullet

for (//loop through bullets)
   {
    if ( bullets[i].active == false )
    {
     bullets[i].active = true;
     bullets[i].x = (player.x + player.rad - bullets[i].rad); //Middle of player bubble
     bullets[i].y = (player.y + player.rad - bullets[i].rad); //
     player.ammo--;
     break;
    }
   }

checking if it’s of the screen

for ( //loop through all bullets)
{
    if (//bullets[i].x or bullets[i].y out of screen)
    {
        bullets[i].active = false;
    }
    if (bullets[i].active == true)
    {
        bullets[i].move();
        bullets[i].draw( m_Screen );
    }
}

After reading a tutorials on this site which involved working with the mouse i used that so it draws a line between the middle of my player bubble to the mouse x and y coordinates (blue line in screenshot).

VDVA2Bk.png

Currently the bullets are just travelling downwards to face the upcomping horde of bubbles, but now i want to be able to shoot the bullets towards the end of the line and keep them moving towards that point even if the mouse has moved. I tried to do so with slope values and such but i can’t get my head around the maths that is needed here.

If i click, it spawns a bullet at my player’s x and y coordinates. I have added a variable which can hold the direction for every bullet object but i don’t know how to get that direction and how to keep a bubble moving towards the point that i defined with the cursor when i clicked.

12 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Mar 09, 2013 at 22:27

Sounds like you want to use vectors. Try reading this article, and the next two in the series. What you will want to do is create a vector pointing from the player toward the cursor position, and scale its length to be the desired speed of the bullet. Then that will be the velocity vector of the bullet and you can use it to update the bullet’s position each frame.

Fd80f81596aa1cf809ceb1c2077e190b
0
rouncer 103 Mar 11, 2013 at 04:21

first work out the angle of the bullet.
to get the angle to the cursor bullet angle=atan2(cursor_pos.x-player_pos.x,cursor.pos.y-player_pos.y);

then to update bullet position per frame=

bullet x+=sin(angle of bullet)*bullet_speed
bullet y+=cos(angle of bullet)*bullet_speed

you need to include “math.h”

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Mar 11, 2013 at 04:31

There’s no need to use trigonometry here. You just normalize the vector.

B5262118b588a5a420230bfbef4a2cdf
0
Stainless 151 Mar 11, 2013 at 09:32

Vectors are the way to go, write a good vector class,either 2D or 3D as you require and just use that.

It makes everything so much easier.

A direction vector becomes as easy as

  Vector direction = (target_position-player_position).Normalise();

Moving a bullet becomes as easy as

 position +=  (direction*velocity*time_step);

Checking for a collision becomes as easy as

 if ((position - target_position).Length()<target_radius)

Then there are all the other things you can do, you can do so many things with vectors that are just a pain to do in any other way.

A638aa42130293f319eda7fa4ba121f4
0
fireside 141 Mar 11, 2013 at 14:16

I have to try out vector normalizing myself. I was using trig. Thanks for that link Reedbeta. It’s going to be fun to do some small html5 2d games for a break, if nothing else.

991c178cbb1237d5e8e147aae5782cb9
0
TTTNL 101 Mar 11, 2013 at 19:23

Ok i’ve read through that article two times already but it still don’t get it. I now know what a vector is, how to get it’s length and what normalizing means, but it still isn’t really clear how to get the direction and how to make that bullet move over that vector.
Could someone explain it a bit more focused to my subject?

A638aa42130293f319eda7fa4ba121f4
0
fireside 141 Mar 11, 2013 at 21:16

Stainless explained it. You subtract the player position from the target position:

player 1,2
target 12,18

(12-1),(18-2)
11,16
get square root of 11*11 + 16*16
divide each value (11,16) by that number to normalize
Now you have a unit length.
You can multiply each of those numbers by a constant velocity and add them to the player position where the bullet starts traveling. You’ll have to keep a real value and use a rounded value to place the bullet. You can just experiment with velocity numbers till you find something that your eye can see. It will probably be very small because of the frame timing. I don’t know if there’s a normalize function somewhere or you have to do it using square root or trig. This is using square root like the link.

991c178cbb1237d5e8e147aae5782cb9
0
TTTNL 101 Mar 12, 2013 at 14:44

YES, it’s working, my code is a mess so i will clean it up a bit but it works!! Thanks!

I will post my code here in a few hours/days

EDIT:

Ok, when i spawn a bullet this is the code it runs:

for (//loop through bullets)
{
    if ( bullets[i].active == false )
    {
     bullets[i].active = true;

     bullets[i].x = (player.x + player.rad - bullets[i].rad);
     bullets[i].y = (player.y + player.rad - bullets[i].rad);

     bullets[i].getUnitLenght( mousex, mousey);

     player.ammo--;
     break;
    }
}

This is bulletClass::getUnitLenght()

void bulletClass::getUnitLenght( int a_mousex, int a_mousey)
{
   dx = ( (x + rad ) - a_mousex );
   dy = ( (y + rad ) - a_mousey );

   vecLength = sqrtf( (dx * dx) + (dy * dy) );

   unitLength1 = ( dx / vecLength );
   unitLength2 = ( dy / vecLength );
}

And in a loop in the Tick function of game.cpp i call bullets.move() which looks like this:

void bulletBubble::move()
{
   x -= (unitLength1 * 2); //velocity of 2
   y -= (unitLength2 * 2);
}

Please comment if you think this code can be optimized.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Mar 12, 2013 at 17:40

Cool, good to hear you got it working! :) Why are you adding and subtracting ‘rad’ from your vectors at some places, though? That’s a rotation angle, right? It doesn’t belong in the vector.

EDIT: Oh, I think it’s a radius, not an angle (I was thinking radians). In that case, never mind. :)

A638aa42130293f319eda7fa4ba121f4
0
fireside 141 Mar 12, 2013 at 18:21

Oh, I think it’s a radius, not an angle

Over abbreviation can cause code to be more unreadable. It doesn’t hurt to splurge a little and write it out, especially if you have intellisense with your compiler. All in all, your code looks pretty readable, though. Glad you got it working.

991c178cbb1237d5e8e147aae5782cb9
0
TTTNL 101 Mar 12, 2013 at 19:27

@fireside

Over abbreviation can cause code to be more unreadable. It doesn’t hurt to splurge a little and write it out, especially if you have intellisense with your compiler. All in all, your code looks pretty readable, though. Glad you got it working.

Thanks guys, i use rad everywhere in my game so i understand it may be confusing if you only read this part, but when reviewing my whole code it will be pretty clear it means radius.

Speaking of whole code ( :D) when the deadline (17th may) is reached for the IGAD assignment i will upload my “game” here so everyone can look into it, but only if that’s allowed by the teachers at IGAD. I think it will be useful for others who are just starting the tutorials.

Fd80f81596aa1cf809ceb1c2077e190b
0
rouncer 103 Mar 13, 2013 at 09:18

good going man, this code pretty much youll be writing a 1000 times every game you make, its very useful.