Quote: "You're attempting to write to GameObject[2]. Because the indices of arrays in C++ start at 0, The highest index of GameObject is 1, so you can only write to GameObject[0] and GameObject[1]."
Thanks Everyone. As IanM & AndrewT indicated I was using Arrays improperly as they are 0 based. I desired to use them starting with index 1, I added + 1 to the declarations. Lesson Learned.
The Result
// Author: F.L.Taylor
// Title: c e l l u l a r 2.0
// Description: c e l l u l a r - DarkGDK Game
#include <new>
#include <stack>
#include <list>
#include "DarkGDK.h"
using namespace std;
/*
DGDK common namespaces
format: namespace db`Objectname`Object{}
example: namespace dbFontObject{...}
DGDK Objects:
File,Display,2D,Font,3D,Sprite,Sound,Light,Camera,Matrix,World,Terrain,Particles,Memblock
*/
class db3DResource{
//Purpose: the Resource - manages db3DObject IDs; maintains a Pool (1 to n) of db3DObjects;
//Parameters:
//Return: None
private:
static const int MAX;
static std::stack<int> *ObjectIndexStack;
std::stack<int> *UnusedObjectStack;
std::list<int> *UsedObjectList;
protected:
int objectID;
int count;
public:
db3DResource(void);
db3DResource(int db3DObjectID, int db3DObjectCount);
~db3DResource(void);
static int pop(void);
static void push(int db3DObjectID);
static void start(void);
static void stop(void);
void checkin(int db3DObjectID);
int checkout(void);
int total(void);
int used(void);
int unused(void);
};
const int db3DResource::MAX = 4096;
std::stack<int> *db3DResource::ObjectIndexStack = new std::stack<int>;
db3DResource::db3DResource(void){
//Purpose: Default Constructor
//Parameters:
//Return: None
}
db3DResource::db3DResource(int db3DObjectID, int db3DObjectCount){
//Purpose:
//Parameters:
//Return: None
UnusedObjectStack = new std::stack<int>;
UsedObjectList= new std::list<int>;
int ID;
objectID = db3DObjectID;
for(count=0;count < db3DObjectCount;count++){
ID = pop();
dbCloneObject(ID,db3DObjectID);
dbHideObject(ID);
UnusedObjectStack->push(ID);
}
dbHideObject(objectID);
}
db3DResource::~db3DResource(void){
//Purpose: destroy all dbObjects in Resource
//Parameters:
//Return: None
int ID;
while (!UsedObjectList->empty()){
ID = UsedObjectList->back();
UsedObjectList->pop_back();
push(ID);
dbDeleteObject(ID);
}
delete UsedObjectList;
while (!UnusedObjectStack->empty()){
ID = UnusedObjectStack->top();
UnusedObjectStack->pop();
push(ID);
dbDeleteObject(ID);
}
delete UnusedObjectStack;
}
void db3DResource::start(void){
//Purpose: Initializes db3DResource ObjectIndex Stack
//Parameters:
//Return: None
for(int index = MAX; index > 0; index--){
ObjectIndexStack->push(index);
}
}
void db3DResource::stop(void){
//Purpose: Default Constructor
//Parameters:
//Return: None
}
int db3DResource::pop(void){
//Purpose: Pops db3DObjectID from ObjectIndexStack
//Parameters:
//Return: None
int ID = ObjectIndexStack->top();
ObjectIndexStack->pop();
return(ID);
}
void db3DResource::push(int db3DObjectID){
//Purpose: Pushes db3DObjectID to ObjectIndexStack
//Parameters:
//Return: None
ObjectIndexStack->push(db3DObjectID);
}
void db3DResource::checkin(int db3DObjectID){
//Purpose: Check-In db3DResource db3DObject
//Parameters:
//Return: None
UsedObjectList->remove(db3DObjectID);
UnusedObjectStack->push(db3DObjectID);
dbHideObject(db3DObjectID);
}
int db3DResource::checkout(void){
//Purpose: Check-Out db3DResource db3DObject
//Parameters:
//Return: db3DObjectID
int ID = UnusedObjectStack->top();
UnusedObjectStack->pop();
UsedObjectList->push_back(ID);
dbShowObject(ID);
return(ID);
}
int db3DResource::total(void){
//Purpose: Returns total number of db3DObjects
//Parameters:
//Return: total number of db3DObjects
return(UnusedObjectStack->size() + UsedObjectList->size());
}
int db3DResource::used(void){
//Purpose: Returns number of db3DObjects in use.
//Parameters:
//Return:
return(UsedObjectList->size());
}
int db3DResource::unused(void){
//Purpose: Returns number of db3DObjects available for use.
//Parameters:
//Return:
return(UnusedObjectStack->size());
}
class Entity{
//Purpose: Base Class for 3D Game Objects
public:
//static std::map<char,int> NameMap;
//static std::map<char,int>::iterator NameMapIterator;
char *name;
char *description;
int ID;
int objectID;
D3DVECTOR position;
D3DVECTOR size;
D3DVECTOR angle;
D3DVECTOR turn;
D3DVECTOR velocity;
D3DCOLORVALUE color;
void purpose(char *desc){description = desc;}
};
class Enzyme: public Entity{
//Purpose: Enzyme Player
private:
static std::stack<int> UnusedStack;
static std::list<int> UsedList;
static std::list<int>::iterator UsedListIterator;
static int pop(void);
static void push(int index);
protected:
static int profile_index;//profile index
public:
static const int INSTANCE_MAX;
static const int PROFILE_MAX;
static Enzyme *Profile;
static Enzyme *Instance;
static db3DResource *Resource[];
int ProfileID;
D3DVECTOR destPosition; //destx...
D3DVECTOR destTurn; //destpitch...
float booster;
float range;
float power;
int fx;
enum states{IDLE, MOVING, FIRING, DYING, DEAD} state;
static void start(void);
static void stop(void);
static void update(void);
static int create(char *name, int objectID, DWORD color, float size, float velocity, float power, int fx);
static void destroy(void);
static int spawn(int ProfileID);
void death(void);
void process(void);
void control(void);
//void smartBomb();
//void keyMapping(int keys);
//void wobbleView(void);
//void cursor(void);
// class Weapon{
// int AmmunitionID;
// int AmmoCount;
// int AmmoMax;
// float firespeed;
// float loadspeed;
// };
// Weapon Blaster[3];
};
//static definitions
const int Enzyme::PROFILE_MAX = 16;
const int Enzyme::INSTANCE_MAX = 1;
int Enzyme::profile_index = 0;
Enzyme *Enzyme::Profile = new Enzyme[Enzyme::PROFILE_MAX + 1];
Enzyme *Enzyme::Instance = new Enzyme[Enzyme::INSTANCE_MAX + 1];
db3DResource *Enzyme::Resource[Enzyme::PROFILE_MAX + 1];
std::stack<int> Enzyme::UnusedStack;
std::list<int> Enzyme::UsedList;
std::list<int>::iterator Enzyme::UsedListIterator;
int Enzyme::pop(void){
//Purpose:
//Parameters:
//Return: None
int index = UnusedStack.top();
UnusedStack.pop();
UsedList.push_back(index);
return(index);
}
void Enzyme::push(int index){
//Purpose:
//Parameters:
//Return: None
UsedList.remove(index);
UnusedStack.push(index);
}
void Enzyme::start(void){
//Purpose:
//Parameters:
//Return: None
for(int index = INSTANCE_MAX; index > 0; index--){
UnusedStack.push(index);
}
}
void Enzyme::stop(void){
//Purpose: destroys all Enzymes Instances
//Parameters:
//Return: None
delete []Instance;
}
void Enzyme::update(void){
//Purpose:
//Parameters:
//Return: None
UsedListIterator = UsedList.begin();
while(UsedListIterator != UsedList.end()) {
Instance[*UsedListIterator++].process();
}
}
void Enzyme::process(void){
//Purpose:
//Parameters:
//Return: None
switch(state){
case IDLE:
control();
break;
}
}
int Enzyme::create(char *name, int objectID, DWORD color, float size, float velocity, float power, int fx){
//Purpose: Configures a Enzyme Profile. Exist the lifetime of the app;
//Parameters:
//Return: None
++profile_index;
Profile[profile_index].ID = profile_index;
Profile[profile_index].name = name;
Profile[profile_index].objectID = objectID;
Profile[profile_index].size.x = size;
Profile[profile_index].size.y = size;
Profile[profile_index].size.z = size;
Profile[profile_index].velocity.x = velocity;
Profile[profile_index].velocity.y = velocity;
Profile[profile_index].velocity.z = velocity;
Profile[profile_index].power = power;
Profile[profile_index].fx = fx;
// Instance[index].Blaster[0].AmmunitionID = 1;
// Instance[index].Blaster[0].AmmoCount = -1;
// Instance[index].Blaster[1].AmmunitionID = 2;
// Instance[index].Blaster[1].AmmoCount = 3;
Resource[profile_index] = new db3DResource(objectID,PROFILE_MAX);
return(profile_index);
}
void Enzyme::destroy(void){
//Purpose: destroys all Enzymes Profiles at the end of app life.
//Parameters:
//Return: None
delete []*Resource;
delete []Profile;
}
int Enzyme::spawn(int ProfileID){
//Purpose: Initializes a Enzyme Instance based on Enzyme Profile
//Parameters:
//Return: None
int index = pop();
Instance[index] = Profile[ProfileID];
Instance[index].ID = index; //primary key
Instance[index].ProfileID = ProfileID;
Instance[index].state = IDLE;
// Instance[index].Blaster[1].AmmunitionID = 1;
// Instance[index].Blaster[1].AmmoCount = -1;
// Instance[index].Blaster[2].AmmunitionID = 2;
// Instance[index].Blaster[2].AmmoCount = 3;
//create object
Instance[index].objectID = Resource[ProfileID]->checkout();
//glue object to camera
dbLockObjectOn(Instance[index].objectID);
dbPositionObject(Instance[index].objectID,0,0,20);
dbPositionCamera(0, 0, -20);
return(index);
}
void Enzyme::death(void){
//Purpose:
//Parameters:
//Return: None
Resource[ProfileID]->checkin(objectID);
objectID = 0;
UsedList.remove(ID);
UnusedStack.push(ID);
}
void Enzyme::control(void){
//Purpose:
//Parameters:
//Return: None
dbRotateCamera( dbCameraAngleX(0) + (dbMouseMoveY() / 2.0), dbCameraAngleY(0) + (dbMouseMoveX() / 2.0), 0);
switch(dbScanCode()){
//norm
case 17:
dbMoveCamera(velocity.z);
break;
case 31:
dbMoveCamera(-velocity.z);
break;
//warp 1
case 16:
dbMoveCamera(velocity.z * 10);
break;
case 30:
dbMoveCamera(-velocity.z * 10);
break;
//warp 10
case 19:
dbMoveCamera(velocity.z * 100);
break;
case 33:
dbMoveCamera(-velocity.z * 100);
break;
//cruise
case 18:
dbMoveCamera(velocity.z * .10);
break;
case 32:
dbMoveCamera(-velocity.z * .10);
break;
}
}
int rndSgn(void){
//Purpose:
//Parameters:
//Return: None
int sgn = dbRnd(1);
if(!sgn){sgn = -1;}
return(sgn);
}
void DarkGDK(void){
START:
char *GameTitle = "c e l l u l a r 2 . 0";
char *help = "press [space] to toggle starfield.";
int GameObjectID[2];
int EnzymeProfileID;
int EnzymeID;
//Resource Testing
const int DB3DRESOURCEPOOL_MAX = 512;
bool db3DResourceTestToggle = true;
int db3DResourceObjectArray[DB3DRESOURCEPOOL_MAX];
int db3DResourceObjectArrayIterator = 0;
dbSyncOn();
dbSyncRate(60);
dbRandomize(dbTimer());
db3DResource::start();
Enzyme::start();
GameObjectID[0] = db3DResource::pop();
GameObjectID[1] = db3DResource::pop();
dbMakeObjectCube(GameObjectID[0], 1.0f);
dbMakeObjectCone(GameObjectID[1], 1.0f);
EnzymeProfileID = Enzyme::create("PepTyde", GameObjectID[1], 0xffffffff, 1.0f, 1.0f, 1.0f, 1);
EnzymeID = Enzyme::spawn(EnzymeProfileID);
db3DResource *db3DResourcePool = new db3DResource(GameObjectID[1],DB3DRESOURCEPOOL_MAX);
for(int db3DResourceObjectArrayIterator=0;db3DResourceObjectArrayIterator < DB3DRESOURCEPOOL_MAX;db3DResourceObjectArrayIterator++){
db3DResourceObjectArray[db3DResourceObjectArrayIterator] = db3DResourcePool->checkout();
dbPositionObject(db3DResourceObjectArray[db3DResourceObjectArrayIterator], dbRnd(200) * rndSgn(), dbRnd(200) * rndSgn(), dbRnd(200) * rndSgn());
dbRotateObject(db3DResourceObjectArray[db3DResourceObjectArrayIterator], dbRnd(359), dbRnd(359), dbRnd(359));
}
UPDATE:
while(LoopGDK()){
// display some text on screen
dbText(0, 0, Enzyme::Profile[EnzymeProfileID].name);
dbText(0,dbScreenHeight() - 14,help);
dbText(0,14 * 1,dbStr(db3DResourcePool->used()));
dbText(0,14 * 2,dbStr(db3DResourcePool->unused()));
dbRotateObject(GameObjectID[0], dbObjectAngleX(GameObjectID[0]) + 1.0, dbObjectAngleY(GameObjectID[0]) + 2.0, dbObjectAngleZ(GameObjectID[0]) + 3.0);
switch (dbScanCode()){
case 57:
db3DResourceTestToggle = true - db3DResourceTestToggle;
if (db3DResourceTestToggle){
for(int db3DResourceObjectArrayIterator=0;db3DResourceObjectArrayIterator < DB3DRESOURCEPOOL_MAX;db3DResourceObjectArrayIterator++){
db3DResourceObjectArray[db3DResourceObjectArrayIterator] = db3DResourcePool->checkout();
dbPositionObject(db3DResourceObjectArray[db3DResourceObjectArrayIterator], dbRnd(100) * rndSgn(), dbRnd(100) * rndSgn(), dbRnd(100) * rndSgn());
dbRotateObject(db3DResourceObjectArray[db3DResourceObjectArrayIterator], dbRnd(359), dbRnd(359), dbRnd(359));
}
help = "Full";
} else {
for(int db3DResourceObjectArrayIterator=0;db3DResourceObjectArrayIterator < DB3DRESOURCEPOOL_MAX;db3DResourceObjectArrayIterator++){
db3DResourcePool->checkin(db3DResourceObjectArray[db3DResourceObjectArrayIterator]);
}
help = "Empty";
}
break;
}
Enzyme::update();
dbSync();
}
STOP:
delete db3DResourcePool;
dbDeleteObject(GameObjectID[0]);
dbDeleteObject(GameObjectID[1]);
Enzyme::Instance[EnzymeID].death();
Enzyme::stop();
Enzyme::destroy();
return; //return back to Windows
}