0
101 Feb 22, 2013 at 21:31 c++

My simple demo game now consist of one moving player and multple enemies coming from the bottom of the screen that you have to avoid. I want to add bullets to my game but i don’t really know how to make them spawn and have them keep moving when the player is not holding the fire button. I’m trying to do something with a class but when you press the fire button a new object should be made so it would need to be done with a vector because an array is fixed in size. And when having a function to move the bullets it need to be applied to all of the bullets.

Could someone explain in (pseudocode) how i go around classes & vectors and spawning & moving of multiple bullets with vectors? I’m out of ideas. I am using the template from the “introduction to c with game development” tutorial in.

#### 22 Replies

0
103 Feb 23, 2013 at 09:00

you need an x and y variable, and an “active” boolean for an array of possible onscreen bullets.

when you want to spawn a bullet, find the first active=false slot, and set x and y to be the player location and make active=true.

each frame, run through the bullet array, and if they are active decrement their y coordinate, if y<0 then active=false, kill the bullet.

thatll give you bullets going upwards.

0
122 Feb 23, 2013 at 09:52

bullets are very simple

You need a container to hold them in, if you are using c++ then the best is probably a vector. There are plenty of tutorials on using vectors

The sequence goes like this.

2) Every pass ….
3) Move bullet
4) Check to see if the bullet has hit anything
5) if it has.
6) delete bullet, damage bad guy
7) Check to see if bullet has gone off screen
8) If it has.
9) delete bullet

That applies regardless of the type of game, 2d 3d first person third person whatever, the principle is the same

0
101 Feb 23, 2013 at 11:44

When i try to make a vector in the template like this:

vector<bulletClass> bullets;


I get a red line underneath vector and when i hover over it it says: “Error vector is not a template”, and that’s with or without #include <vector>

0
103 Feb 23, 2013 at 15:36

haha when i first saw this question it amused me, i remember when i first needed to ask myself “now how do i do a bullet” when i was 8-9 years old. the one concept i came up with as the solution was “ah yes, i have to remember the positions of all my objects on the screen” thats pretty much the eureka moment.

spawning bullets is a eureka moment for a beginner programmer, so my heart goes out to you. :)

0
126 Feb 23, 2013 at 16:49

You will need to bone up on a little math at this point. A vector is a way of describing position and direction in 3d space. If you use a coordinate system, with the gun at point zero, then you can describe the angle and location where the bullet will be on the next frame and each next frame will use that same formula by using the same angle and length of a vector on the last position of the bullet, since the bullet is going at a fixed speed. That formula comes from pythagorean theorum of a right triangle. You can always form a right triangle with the beginning point at the center, using x, and y coordinates, so your speed of the bullet is the length of the vector in space. In 3d, it gets a little more complicated because of the extra plane, but same principle.
here’s a vector math tutorial:

http://chortle.ccsu….orIndex.html#05
or you may just want to use pythagorean theorum:

http://en.wikipedia….agorean_theorem if it’s 2d. The speed of the bullet represents the hypotenuse of the right triangle. If you know that and the angle, you can determine the other sides of the triangle which are the x and y distances. You would be assigning the angle based on the direction of the gun.

0
101 Feb 23, 2013 at 21:37

@fireside

You will need to bone up on a little math at this point. A vector is a way of describing position and direction in 3d space. If you use a coordinate system, with the gun at point zero, then you can describe the angle and location where the bullet will be on the next frame and each next frame will use that same formula by using the same angle and length of a vector on the last position of the bullet, since the bullet is going at a fixed speed. That formula comes from pythagorean theorum of a right triangle. You can always form a right triangle with the beginning point at the center, using x, and y coordinates, so your speed of the bullet is the length of the vector in space. In 3d, it gets a little more complicated because of the extra plane, but same principle.
here’s a vector math tutorial:

http://chortle.ccsu….orIndex.html#05
or you may just want to use pythagorean theorum:

http://en.wikipedia….agorean_theorem if it’s 2d. The speed of the bullet represents the hypotenuse of the right triangle. If you know that and the angle, you can determine the other sides of the triangle which are the x and y distances. You would be assigning the angle based on the direction of the gun.

I’m not talking about a vector as in “line which the bullet must follow”. I’m talking about the storage containter vector used in C++ to store data in. I can’t seem to make one using the template from the tutorials and i want to figure out how i can.

It’s a simple 2d game/demo, i have to add an “object spawner”, when i press space it must spawn a bullet that travels downwards, nothing fancy with direction of the gun. And i need a vector to store those bullet objects in but when i try to make a vector i get an error (see previous comment).

0
126 Feb 24, 2013 at 00:06

I’m not talking about a vector as in “line which the bullet must follow”. I’m talking about the storage containter vector used in C++ to store data in. I can’t seem to make one using the template from the tutorials and i want to figure out how i can.

Oh, never mind.

try
std::vector<whatever> bullets;

with the include

0
122 Feb 24, 2013 at 10:13
std::vector<BulletClass * > bullets;


bullets.push_back(new BulletClass());


To iterate them

for (int i=0; i<bullets.size(); i++)
{
BulletClass * cur = bullets[i];
}

0
101 Feb 24, 2013 at 11:38

#include <vector>


i get a whole list of errors from different files and places of the template

it’s basically this for every error

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\tmmintrin.h(81): error C2146: syntax error : missing ';' before identifier '_mm_sign_epi32'
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\tmmintrin.h(81): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\tmmintrin.h(81): error C2146: syntax error : missing ')' before identifier 'a'


And this:

fatal error C1003: error count exceeds 100; stopping compilation

0
101 Feb 24, 2013 at 12:08

Strange errors like that can be caused by errors earlier in other files.

0
101 Feb 28, 2013 at 14:23

@Stainless

std::vector<BulletClass * > bullets;


bullets.push_back(new BulletClass());


To iterate them

for (int i=0; i<bullets.size(); i++)
{
BulletClass * cur = bullets[i];
}


Ok i’ve got it working now, but without the * after BulletClass. that doesn’t seem to be a problem.

for (int i=0; i<bullets.size(); i++)
{
bulletClass cur = bullets[i];

bullets[i].move();
bullets[i].draw( m_Screen );
}


how can i remove a bullet which y coordinate is higher than 500?

Because i can’t use bullets.delete or something similar to delete the current bullets bullet ( i think )
I’ve tried this:

if (bullets[i].y > 500)
{
bullets.pop_back();
}


but that will delete all of the bullets on screen and not just the last one.

and this:

if (bullets[i].y < 500)
{
bullets[i].move();
bullets[i].draw( m_Screen );
}


But this will create a wall of invisible bullets at y=500 because although they won’t be drawn, y will still be 500.

Any ideas?

0
103 Feb 28, 2013 at 14:53

making them invisible is as good as deleting them, i say, as long as the vector is a fixed size.

0
126 Feb 28, 2013 at 15:43

You could probably just break from the loop and then delete the first one that’s off screen, chances are there will only be one. If not, you will catch up eventually.

0
101 Feb 28, 2013 at 21:10

@fireside

You could probably just break from the loop and then delete the first one that’s off screen, chances are there will only be one. If not, you will catch up eventually.

@rouncer

making them invisible is as good as deleting them, i say, as long as the vector is a fixed size.

Do you mean making the position outside of the screen and outside any posibility of collision? But then after a while i would have hundreds of bullets up there and when i implement collision detection i don’t think that is going to be really good for the performance. I could however implement the ability to only do collision detection for active bullets.

but isn’t there a simple way i can delete the bullet that is outside the screen? Or do i have to dive into memory allocation and all that good stuff?

0
103 Feb 28, 2013 at 21:19

you could reuse the dead bullets when you spawn a new bullet.

0
126 Feb 28, 2013 at 23:22

For a vector in c++ you use erase. I meant iterate through and delete one bullet that’s off screen each loop.

int found = -1;
for(int i =0; i < bullets.size;i++)
{
if(bullets[i].y<500) // move code;
else found = i;
}
if(found > -1) bullets[found].erase;


or make it invisible or whatever.
Otherwise you could put the off screen bullets at the front and iterate at a higher starting number each time one went off screen, or at the back an stop iterating earlier. For that matter, there’s about a million ways you could do it and why am I suggesting anything?

0
101 Mar 01, 2013 at 08:21

I’ve just gone with placing the bullet at x=-20 when it needs to be removed, and it only checks for collision, moves and draws the bullets when x>=0, so that shouldn’t be really performance heavy. But i will check out fireside’s way to delete them.

0
101 Apr 04, 2013 at 07:52

@fireside

For a vector in c++ you use erase. I meant iterate through and delete one bullet that’s off screen each loop.

int found = -1;
for(int i =0; i < bullets.size;i++)
{
if(bullets[i].y<500) // move code;
else found = i;
}
if(found > -1) bullets[found].erase;


or make it invisible or whatever.
Otherwise you could put the off screen bullets at the front and iterate at a higher starting number each time one went off screen, or at the back an stop iterating earlier. For that matter, there’s about a million ways you could do it and why am I suggesting anything?

Pardon me, but that’s an odd way to solve the problem, I think! :P

This is more or less how I solved it (in English):
I created a self-contained entity (a “bullet”), and assigned that to a “gun,” and assigned that to a “player.”
The gun can fire a bullet (if it contains any). The bullet will update it’s own position. The bullet knows when it has been “fired.”
The bullet also knows when to quit updating itself (due to an ‘out-of-range’ issue). That’s about it!

An example of this (horray YouTube) in action:

Of course: The specifics of what library (if any) that you’re using don’t really apply here.
I figure if you’re going to use C++: Why not do it in a C++-fashion (with objects)? :)

Yes! I am implying C++ should be more object-oriented. It’s a beautiful feature for solving these type problems.

From a pure coding point, this is all that exists in the code that carries any real weight:

player.at(3).gun.loadRound(99);


Player “3” is the yellow box.

0
101 Jun 04, 2013 at 08:43

wouldn’t a list not be better for storing projectiles, since insertion and deletion are faster, and you never really need constant access time since you’re iterating through every element anyway?

0
122 Jun 04, 2013 at 16:46

In general if you have insertions into the data-structure (other than at the end) then vector may be slower, otherwise in most cases vector is expected to perform better than list if only for data locality issues, this means that if two elements that are adjacent in the data-set are adjacent in memory then the next element will already be in the processor’s cache and will not have to page fault the memory into the cache.
Also keep in mind that the space overhead for a vector is constant (3 pointers) while the space overhead for a list is paid for each element, this also reduces the number of full elements (data plus overhead) that can reside in the cache at any one time.

0
139 Jun 04, 2013 at 17:33

@darksmaster923

wouldn’t a list not be better for storing projectiles, since insertion and deletion are faster

Usually it doesn’t matter what order the projectiles are stored in. When order doesn’t matter, you can add/remove items from a vector quite efficiently: always add new ones at the end, and when deleting an item, you can swap it with the last item, so then the item you want to delete is at the end. Or you can mark the deleted item as “dead” using a flag in the item, and clear out the dead items in a compaction pass later.

Moreover, a list does a heap allocation for every single item, while a vector does a heap alloc only occasionally when it needs to grow. As Stainless mentioned this means greater memory overhead for lists (especially if the elements are small - the list overhead could be as high as 4x or 8x the size of the actual elements!) and it also affects performance, since heap allocs aren’t free.

0
117 Aug 09, 2013 at 07:34

@darksmaster923

wouldn’t a list not be better for storing projectiles, since insertion and deletion are faster, and you never really need constant access time since you’re iterating through every element anyway?

Depends on how many bullets we’re talking about.

Insertion and deletion are relatively rare operations compared to accessing the data. If we’re talking about relatively few bullets, the implementation doesn’t matter; if we’re talking about a whole load of bullets, lists will start to add overhead that’s very hard to see in profilers, as the overhead is all over the place due to additional, and completely random, memory accesses.

edit: my bad, I didn’t notice this thread has two pages, and apparently it’s only activity was spam..