# Aiming and shooting in a 2D game

c++

12 replies to this topic

### #1TTTNL

Member

• Members
• 48 posts

Posted 09 March 2013 - 07:52 PM

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).

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.

### #2Reedbeta

DevMaster Staff

• Administrators
• 5309 posts
• LocationSanta Clara, CA

Posted 09 March 2013 - 10:27 PM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #3rouncer

Senior Member

• Members
• 2725 posts

Posted 11 March 2013 - 04:21 AM

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"
you used to be able to fit a game on a disk, then you used to be able to fit a game on a cd, then you used to be able to fit a game on a dvd, now you can barely fit one on your harddrive.

### #4Reedbeta

DevMaster Staff

• Administrators
• 5309 posts
• LocationSanta Clara, CA

Posted 11 March 2013 - 04:31 AM

There's no need to use trigonometry here. You just normalize the vector.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #5Stainless

Member

• Members
• 582 posts
• LocationSouthampton

Posted 11 March 2013 - 09:32 AM

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.

### #6fireside

Senior Member

• Members
• 1590 posts

Posted 11 March 2013 - 02:16 PM

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.
Currently using Blender and Unity.

### #7TTTNL

Member

• Members
• 48 posts

Posted 11 March 2013 - 07:23 PM

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?

### #8fireside

Senior Member

• Members
• 1590 posts

Posted 11 March 2013 - 09:16 PM

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.
Currently using Blender and Unity.

### #9TTTNL

Member

• Members
• 48 posts

Posted 12 March 2013 - 02:44 PM

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[i].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.

### #10Reedbeta

DevMaster Staff

• Administrators
• 5309 posts
• LocationSanta Clara, CA

Posted 12 March 2013 - 05:40 PM

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #11fireside

Senior Member

• Members
• 1590 posts

Posted 12 March 2013 - 06:21 PM

Quote

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.
Currently using Blender and Unity.

### #12TTTNL

Member

• Members
• 48 posts

Posted 12 March 2013 - 07:27 PM

fireside, on 12 March 2013 - 06:21 PM, said:

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 ( ) 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.

### #13rouncer

Senior Member

• Members
• 2725 posts

Posted 13 March 2013 - 09:18 AM

good going man, this code pretty much youll be writing a 1000 times every game you make, its very useful.
you used to be able to fit a game on a disk, then you used to be able to fit a game on a cd, then you used to be able to fit a game on a dvd, now you can barely fit one on your harddrive.

#### 1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users