The Problem
I've been having problems where if an IF statement is allowed to run inside a Spawner class, it instantly crashes my game. I have no idea what's happening, as it's copied from Ben Wright on YouTube, who has a series of tutorials in which he explains his code (https://www.youtube.com/playlist?list=P ... FMqe_THGh9). I made sure the code is exactly as it should be many times, but I'm still getting the same crash. I discovered that if I just don't allow the statement to run, then the game runs fine, however, without the enemies spawning. I tried to contact him but it's of no help.
The Source Code
Code: Select all
#include <iostream>
#include <irrlicht.h>
#include <vector>
#include <string>
//NAMESPACES
using namespace std;
using namespace irr;
using namespace scene;
using namespace core;
using namespace video;
using namespace io;
using namespace gui;
//INITIALISATION
IrrlichtDevice *device;
IVideoDriver *driver;
ISceneManager *smgr;
class MyEventReceiver : public IEventReceiver
{
public:
//Struct to record info on the mouse state
struct SMouseState
{
core::position2di Position;
bool LeftButtonDown;
SMouseState() : LeftButtonDown(false) { }
} MouseState;
virtual bool OnEvent(const SEvent& event)
{
//Remember whether each key is up or down
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
{
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
//Remember the mouse state
if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) {
switch(event.MouseInput.Event) {
case EMIE_LMOUSE_PRESSED_DOWN:
MouseState.LeftButtonDown = true;
break;
case EMIE_LMOUSE_LEFT_UP:
MouseState.LeftButtonDown = false;
break;
case EMIE_MOUSE_MOVED:
MouseState.Position.X = event.MouseInput.X;
MouseState.Position.Y = event.MouseInput.Y;
break;
default:
break;
}
return false;
}
return 0;
}
const SMouseState & GetMouseState(void) const
{
return MouseState;
}
//Used to check whether each key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
//We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
class Enemy {
IAnimatedMeshSceneNode *enemy;
int state;
public:
Enemy(core::vector3df pos) {
IAnimatedMesh *mesh = smgr->getMesh("media/sydney.md2");
enemy = smgr->addAnimatedMeshSceneNode(mesh);
state = 0;
if (enemy) {
enemy->setMaterialFlag(EMF_LIGHTING, false);
enemy->setMD2Animation(EMAT_RUN);
enemy->setScale(core::vector3df(2,2,2));
enemy->setPosition(pos);
enemy->setMaterialTexture(0, driver->getTexture("media/sydney.bmp"));
}
}
void update(core::vector3df target) {
core::vector3df playerPos = target;
core::vector3df enemyPos = enemy->getPosition();
core::vector3df vec = playerPos - enemyPos;
core::vector3df rot = enemy->getRotation();
//Set up the enemy rotation
rot.Y = atan(vec.Z/vec.X) + (180.0f / core::PI);
if ((playerPos.X - enemyPos.X) > 0) {
rot.Y = 90 - rot.Y;
}
else if ((playerPos.X - enemyPos.X) < 0) {
rot.Y = -90 - rot.Y;
}
rot.Y -= 90;
enemy->setRotation(rot);
//Force the enemy to keep following the player
if (enemyPos.getDistanceFrom(playerPos) < 50) {
if (state == 0) {
state = 1;
enemy->setMD2Animation(EMAT_ATTACK);
}
}
else if (state != 0) {
state = 0;
enemy->setMD2Animation(EMAT_RUN);
}
//Update the animation state
if (state == 0) {
scene::ISceneNodeAnimator *enemy_anim = smgr->createFlyStraightAnimator(enemy->getPosition(), target, 3500, true);
enemy->addAnimator(enemy_anim);
enemy_anim->drop();
}
else {
scene::ISceneNodeAnimator *enemy_anim = smgr->createFlyStraightAnimator(enemy->getPosition(), enemy->getPosition(), 3500, true);
enemy->addAnimator(enemy_anim);
enemy_anim->drop();
}
}
};
class Spawner {
int inc;
int count;
std::vector<Enemy*> enemies;
core::vector3df pos;
public:
Spawner(core::vector3df pos) : pos(pos), count(0), inc(0)
{
}
void update(core::vector3df player)
{
//Check to spawn a new enemy
if (inc++ % 100 == 0 && count < 10) //crashes game without '&& count > 0'
{
Enemy *new_enemy = new Enemy(pos);
enemies.push_back(new_enemy);
count++;
}
for (int i = 0; i < enemies.size(); i++)
{
enemies[i]->update(player);
}
}
};
//ENUMERATORS
enum
{
ID_IsNotPickable = 0,
IDFlag_IsPickable = 1 << 0,
IDFlag_IsHighlightable = 1 << 1
};
int main()
{
//INITIALISE PATHS FOR HEARTS
io::path HeartDepPath = "media/HeartDepleted.png";
io::path HeartFullPath = "media/HeartFull.png";
MyEventReceiver receiver;
//INITIAL DEVICES AND MANAGERS
IrrlichtDevice *device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(1080,720), 16, false, false, false, &receiver);
device->setWindowCaption(L"DOOMENSTEIN");
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
//ABORT IF SOMETHING GOES WRONG
if (!device)
{
return EXIT_FAILURE;
}
//FILE ARCHIVE FOR MAP
device->getFileSystem()->addFileArchive("media/map-20kdm2.pk3");
scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
scene::IMeshSceneNode* node = NULL;
//CROSSHAIRS BILLBOARD
device->getGUIEnvironment()->addImage(driver->getTexture("media/crosshairs.png"),
core::position2d<s32>(508,328));
//GUI
device->getGUIEnvironment()->addImage(driver->getTexture("media/GUI.png"),
core::position2d<s32>(0,0));
//HEARTS
device->getGUIEnvironment()->addImage(driver->getTexture(HeartFullPath), core::position2d<s32>(60,597));
device->getGUIEnvironment()->addImage(driver->getTexture(HeartDepPath), core::position2d<s32>(210,597));
device->getGUIEnvironment()->addImage(driver->getTexture(HeartDepPath), core::position2d<s32>(360,597));
//DISPLAY GUIENV
gui::IGUIStaticText* diagnostics = device->getGUIEnvironment()->addStaticText(
L"", core::rect<s32>(10, 10, 400, 20));
diagnostics->setOverrideColor(video::SColor(255, 255, 255, 0));
//OCTREE AND SELECTOR FOR MAP
if (mesh)
{
node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0 , IDFlag_IsPickable);
}
scene::ITriangleSelector* selector = NULL;
if (node)
{
node->setPosition(core::vector3df(-1350, -130, -1400));
selector = smgr->createOctreeTriangleSelector(node->getMesh(), node, 128);
node->setTriangleSelector(selector);
//not done yet so no drop
}
//CREATES CAMERA AND KEYMAP
SKeyMap keyMap[5];
keyMap[0].Action = EKA_MOVE_FORWARD;
keyMap[0].KeyCode = KEY_KEY_W;
keyMap[1].Action = EKA_MOVE_BACKWARD;
keyMap[1].KeyCode = KEY_KEY_S;
keyMap[2].Action = EKA_STRAFE_LEFT;
keyMap[2].KeyCode = KEY_KEY_A;
keyMap[3].Action = EKA_STRAFE_RIGHT;
keyMap[3].KeyCode = KEY_KEY_D;
keyMap[4].Action = EKA_JUMP_UP;
keyMap[4].KeyCode = KEY_SPACE;
scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 50.f, 0.4f, -1, keyMap, 5, false, 1.99f, false);
camera->setPosition(core::vector3df(50,50,-60));
camera->setTarget(core::vector3df(-70,50,-60));
camera->setFarValue(10000.0f);
device->getCursorControl()->setVisible(false);
//IF A SELECTOR EXISTS:
if (selector)
{
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(selector, camera, core::vector3df(30,50,30), core::vector3df(0,-10,0), core::vector3df(0,30,0));
selector->drop();
camera->addAnimator(anim);
anim->drop();
}
Spawner spawner(core::vector3df(60,50,-40));
//RUN LOOP
while (device->run())
{
//EXTRA CONTROLS
if(receiver.IsKeyDown(irr::KEY_ESCAPE))
{
driver->endScene();
device->drop();
return EXIT_SUCCESS;
}
if(receiver.IsKeyDown(irr::KEY_LBUTTON)) //SET UP SO I DON'T FORGET THE SHOOT BUTTON
{
}
driver->beginScene(true, true, video::SColor(255,113,113,113));
smgr->drawAll();
device->getGUIEnvironment()->drawAll();
driver->endScene();
spawner.update(camera->getPosition());
}
device->drop();
return EXIT_SUCCESS;
}
Code: Select all
class Spawner {
int inc;
int count;
std::vector<Enemy*> enemies;
core::vector3df pos;
public:
Spawner(core::vector3df pos) : pos(pos), count(0), inc(0)
{
}
void update(core::vector3df player)
{
//Check to spawn a new enemy
if (inc++ % 100 == 0 && count < 10) //crashes game without 'count > 0'
{
Enemy *new_enemy = new Enemy(pos);
enemies.push_back(new_enemy);
count++;
}
for (int i = 0; i < enemies.size(); i++)
{
enemies[i]->update(player);
}
}
};
Code: Select all
Spawner spawner(core::vector3df(60,50,-40));
Code: Select all
spawner.update(camera->getPosition());
We suspect it might be a runtime error? If anyone has any idea how to fix it, it would be greatly appreciated as my deadline's getting closer and closer...