Advertisement

Drawing Multiple Sprites (projectiles)

Started by January 07, 2015 11:23 AM
18 comments, last by BeerNutts 10 years ago


I was setting i=0 so that it would re-iterate through the loop after the loop had reached PROJECTILES.

I see no reason why you should need to 're-iterate' through that loop. In fact, the way that loop is currently presented is an infinite loop. The snippets of code as you've presented them aren't going to draw anything cause it never gets out of that 'Spacebar to fire' loop, so what are we missing?

It's not an infinite loop. PROJECTILES is 5, so the most i will ever be inside the for loop is 4. When i is incremented to 5 at the end of the 5th iteration, the for loop will no longer execute, since 5 < 5 is false.

The if (i == 5) i = 0; is never hit.

Hello to all my stalkers.


It's not an infinite loop. PROJECTILES is 5, so the most i will ever be inside the for loop is 4. When i is incremented to 5 at the end of the 5th iteration, the for loop will no longer execute, since 5 < 5 is false.
The if (i == 5) i = 0; is never hit.

Well that was an embarrassing misread on my part. Thanks for the correction Lactose!

Advertisement


Another way of doing this would be to e.g. have a std::vector of projectiles, and add a new projectile to the vector when you press the spacebar.

How would you go about using std::vector. I've heard of it but never used it or seen it implemented.

I have a better idea.

Don't try and initialize all the projectiles at the start. Instead, in your Update code, where you check for SpaceBar, do something like this:

// lets assume you have a vector that holds all the active projectiles
std::vector<Projectile> ProjectilesList;
...
 
// Later, in your Update() code, where IsTimeToFire checks if enough time has elapsed since the player last shoot a projectile
if (SpaceBarPressed && _player->IsTimeToFire()) {
  // Create a new projectile, giving it it's starting location.  In Projectile constructor, we create the texture and rectangle for it and give it it's speed, etc.
  Projectile newProjectile(_player->_position);
 
  // now add it to the projectiles list
  ProjectilesList.push_back(newProjectile);
 
  // finally, tell the player you just shot a projectile
  _player->ProjectileFire();
}
 
// Also in the Update() code, loop through all projectiles, see if they hit an enemy, or if they went off the screen, and remove them from the list
...
 
// Later, in your Draw() function, loop through the projectiles, drawing everything
for (int i = 0; i < ProjectilesList.size(); ++i) {
  ProjectileList[i].Draw();
}
 

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)


Another way of doing this would be to e.g. have a std::vector of projectiles, and add a new projectile to the vector when you press the spacebar.

How would you go about using std::vector. I've heard of it but never used it or seen it implemented.

google it

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

I have a better idea.

Don't try and initialize all the projectiles at the start. Instead, in your Update code, where you check for SpaceBar, do something like this:


// lets assume you have a vector that holds all the active projectiles
std::vector<Projectile> ProjectilesList;
...
 
// Later, in your Update() code, where IsTimeToFire checks if enough time has elapsed since the player last shoot a projectile
if (SpaceBarPressed && _player->IsTimeToFire()) {
  // Create a new projectile, giving it it's starting location.  In Projectile constructor, we create the texture and rectangle for it and give it it's speed, etc.
  Projectile newProjectile(_player->_position);
 

I have a better idea.

Don't try and initialize all the projectiles at the start. Instead, in your Update code, where you check for SpaceBar, do something like this:


// lets assume you have a vector that holds all the active projectiles
std::vector<Projectile> ProjectilesList;
...
 
// Later, in your Update() code, where IsTimeToFire checks if enough time has elapsed since the player last shoot a projectile
if (SpaceBarPressed && _player->IsTimeToFire()) {
  // Create a new projectile, giving it it's starting location.  In Projectile constructor, we create the texture and rectangle for it and give it it's speed, etc.
  Projectile newProjectile(_player->_position);
 
  // now add it to the projectiles list
  ProjectilesList.push_back(newProjectile);
 
  // finally, tell the player you just shot a projectile
  _player->ProjectileFire();
}
 
// Also in the Update() code, loop through all projectiles, see if they hit an enemy, or if they went off the screen, and remove them from the list
...
 
// Later, in your Draw() function, loop through the projectiles, drawing everything
for (int i = 0; i < ProjectilesList.size(); ++i) {
  ProjectileList[i].Draw();
}
 

Is "Projectile newProjectile()" a class or a structure. Because my "Projectile" is a structure, I'm not sure you can have constructors for structures, no?

// now add it to the projectiles list ProjectilesList.push_back(newProjectile); // finally, tell the player you just shot a projectile _player->ProjectileFire(); } // Also in the Update() code, loop through all projectiles, see if they hit an enemy, or if they went off the screen, and remove them from the list ... // Later, in your Draw() function, loop through the projectiles, drawing everything for (int i = 0; i < ProjectilesList.size(); ++i) { ProjectileList.Draw(); }

Would I initialise the variables and content within the projectile structure then?

Advertisement


Would I initialise the variables and content within the projectile structure then?

Exactly, you'd do it in the Projectile class constructor. Like this

// in Projectile.h
 
class Projectile
{
public:
  Projectile(Rect location);
 
  // other class function definitions
 ...
 
private:
  Rect Location;
  // other class variable definitions
  ...
};
 
 
// Now in Projectile.cpp
void Projectile::Projectile(Rect location)
{
  // Set Where this Projectile is starting
  Location.x = location.x;
  Location.y = location.y;
 
  // Set the texture, speed, and the rest of the initializers
 ...
}

Good luck.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

You don’t need a Rect structure just to set a position.
Since the original poster is new to std::vector, I will suggest a “Point” structure to avoid confusion (I’d otherwise suggest a Vector, but you can see how that might be confusing…).


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

You probably still want to rate limit the total number of bullets visible on screen at any one time regardless of if you correctly use a vector to hold them.

If you do not, players will spam the screen full of bullets and make the game extremely easy, moving back and forth spraying bullets in a wave so that no enemies can appear.

My attempt at a side scrolling shooter worked in a similar way to the OP, with an array (this is because i did not know a better way to do it back then) which could hold a maximum of 1000 bullets. Yes, this did slow down quite significantly with a lot of bullets on screen as firing bullets, and removing bullets that had left the screen were both O(n)... If you use a vector, they don't need to be quite so inefficient.


You probably still want to rate limit the total number of bullets visible on screen at any one time regardless of if you correctly use a vector to hold them.

If you do not, players will spam the screen full of bullets and make the game extremely easy, moving back and forth spraying bullets in a wave so that no enemies can appear.

The best way to do this is to set a refire rate for your weapon type. Fro example, a laser weapon might shoot a bullet every 50 milliseconds, move very fast and not hit hard, but the missile weapon might shoot a missile every 500 mS, move slower and hit hard. This will both limit the number of bullets on the screen, and provide a good way to make different bullet types.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

This topic is closed to new replies.

Advertisement