NOGDUS $1670.00 has been donated to NOGDUS!
September 21, 2017, 03:47:38 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1]   Go Down
  Print  
Author Topic: Managing STL vectors of Object Pointers  (Read 2411 times)
0 Members and 1 Guest are viewing this topic.
Richard Marks
Administrator
Offline Offline

Respect: 3425
« on: May 19, 2010, 04:52:28 PM »

Managing STL vectors of Object Pointers

Let's say you have a data structure for say an enemy ship:
Code:
struct EnemyShip
{
bool Alive;
// position, etc... *code omitted*
};

Now lets say we want to have enemies spawn every second or so.
So we're going to use an STL vector to hold pointers to our enemies to make it easy to spawn new enemies.
Lets make a class to manage our enemies to make this example code more clear. Roll Eyes

Code:
class EnemyShipManager
{
public:
EnemyShipManager() {}
~EnemyShipManager() { this->Clear(); }
void Clear()
{
// removes all enemies / frees all allocated memory

// make sure there are enemies to even clear out
unsigned int count = enemies_.size();
if (!count)
{
return;
}

for (unsigned int i = 0; i < count; i++)
{
if (enemies_[i])
{
delete enemies_[i];
}
}
enemies_.clear();
}

void Add()
{
// spawns a new enemy and adds it to the vector
enemies_.push_back(new EnemyShip());
}

void Update()
{
// update all enemies that are alive
// and purge (remove) all dead enemies from the enemies vector

for (unsigned int i = 0; i < enemies_.size(); i++)
{
// grab a pointer to the current enemy
EnemyShip* enemy = enemies_[i];

// if the pointer isn't null
if (enemy)
{
// if the enemy is dead
if (!enemy>Alive)
{
// purge the enemy from the vector
// we must delete the pointer because we use the new operator to add enemies
delete enemy;
enemies_.erase(enemies_.begin() + i);
i--;
}
else
{
// the enemy is alive so update the enemy here
// this demo has no real code to update, so for example
// enemy->Position += enemy->Velocity;
}
}
}
}

void Render()
{
// draws all the enemies that are alive
for (unsigned int i = 0; i < enemies_.size(); i++)
{
// grab a pointer to the current enemy
EnemyShip* enemy = enemies_[i];

// if the pointer is null or the enemy is dead
if (!enemy || !enemy->Alive)
{
// skip this enemy
continue;
}

// draw the enemy here
// this example code doesn't have anything to draw
// so lets make up a function ^-^
DrawEnemy(enemy);
}
}
private:
std::vector<EnemyShip*> enemies_;
};

Okay, great, now lets see how we use this class in our game code.
Below is a tiny game framework for demonstration purposes.
I gloss over the details such as API init and things like that.

Code:
class Game
{
public:
Game() { InitAPI(); } ~Game() { this->UnloadContent(); ShutdownAPI(); }
void UpdateFrame();
void RenderFrame();
bool LoadContent();
void UnloadContent();
private:

EnemyShipManager enemyShips_;
};

void Game::UpdateFrame()
{
// update the enemies
enemyShips_.Update();
}

void Game::RenderFrame()
{
// render the enemies
enemyShips_.Render();
}

bool Game::LoadContent()
{
// spawn a few enemies
for (int i = 0; i < 10; i++)
{
enemyShips_.Add();
}

return true;
}

void Game::UnloadContent()
{
}


This is a task that is likely to come up in your time as a game programmer.
Thanks to Mattias Gustavsson for helping me get this working. Cool
Logged

Tags:
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines
.: Theme by Richard Marks :.
Valid XHTML 1.0! Valid CSS!