For a game, I want to have a bunch of enemies which can be divided by type (ie. there are thousands of them but only - say - ten classes, for example gunner, grenadier, tank etc.) - so my approach to implement this in a memory-efficient way is the following:
The Approach/Set-Up
I have a global model structure for each class, like this:
// global scope
Model gunner_model, grenadier_model, tank_model;
Then there's a function that is called when the game starts that loads these models:
// on game start
void LoadEnemyModels ( void )
{
gunner_model.Load ( "gunner_model.3ds", "gunner_texture.png" );
grenadier_model.Load ( "grenadier_model.3ds", "grenadier_texture.png" );
tank_model.Load ( "tank_model.3ds", "tank_texture.png" );
}
Next I have a class called 'Enemy' which includes all kinds of stuff such as a position, rotation, ammunition, whatever,
and a pointer to a model:
class Enemy
{
public:
boost::shared_ptr<Model> model;
//Vector3 Position;
// etc.
};
Now I define a global std::list of my Enemy class:
// global scope again
std::list<Enemy> enemy;
The Problem
I use the following function for adding a new enemy to the vector:
void AddEnemy ( EnemyType type )
{
Enemy _enemy;
if ( type == Gunner )
_enemy.model.reset ( &gunner_model );
else if ( type == Grenadier )
_enemy.model.reset ( &grenadier_model );
else if ( type == Tank )
_enemy.model.reset ( &tank_model );
enemy.push_back ( _enemy );
Console::Print ( "Enemy added - new enemy count: %d", enemy.size ( ) );
}
And this one to get rid of one (which one is not important right now so I just go for the first entry in the list):
void RemoveEnemy ( )
{
if ( enemy.size ( ) > 0 )
enemy.erase ( enemy.begin ( ) );
Console::Print ( "Enemy removed - new enemy count: %d", enemy.size ( ) );
}
So, when I push-back a new Enemy into the list, I make sure to set its pointer to the correct model according to the type that the new enemy should be of.
Like this, however, whenever I call RemoveEnemy ( ) the game crashes with this:
---------------------------
Microsoft Visual C++ Debug Library
---------------------------
Debug Assertion Failed!
Program: c:\Game\Game.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
When I don't set the enemy's model-pointer to anything (leave it as NULL), and then don't try to draw it (access it), removing works fine.
I'm assuming I'm doing something wrong with the boost::shared_ptrs, possibly when setting the smart pointer to point at the correct model structure?
Also, is this approach valid? Does it make sense to do it all this way?
Any help is appreciated!