Hi basically I am creating a zombie survival game using Irrlicht. I have a base class Survival.cpp with my game loop in a method called Survival::Run()
I am trying to call a Shoot()
method from within the game loop from another class within Bullet.cpp
I have included the Shoot()
method within a Bullet.h file and made it public I have also made an #include Bullet.h
in my Survival.cpp file. I thought this was enough to be able to find this method?? Apparently not though. I believe this is due to the program trying to call Shoot();
before it has been created (correct me if I am wrong). This is potentially something very simple I am missing. Please can somebody help me out here. The necessary code is included, however if you need to see any other part of this then let me know. Thanks in advance.
Bullet.h
#pragma once
#include <irrlicht.h>
#include "Survival.h"
#include "CAppReceiver.h"
using namespace irr;
using namespace core;
using namespace video;
using namespace scene;
using namespace gui;
#if defined (_MSC_VER)
#pragma comment (lib, "Irrlicht.lib")
#endif
class Bullet
{
public:
Bullet(void);
virtual ~Bullet(void);
bool Initialize(void);
void Shoot();
void createBulletImpacts();
struct SBullet
{
u32 when;
ISceneNode* node;
vector3df direction;
};
array<SBullet> Bullets;
CAppReceiver appReceiver;
private:
// Interface variables
IrrlichtDevice* device;
IVideoDriver* driver;
ISceneManager* smgr;
IGUIEnvironment* env;
ISceneManager* sm; // = device->getSceneManager();
ICameraSceneNode* camera; // = sm->getActiveCamera();
ISceneNode* node;
// bullet for the shoot method
IMesh* bullet;
IMesh* bullMesh;
IMeshSceneNode* goldBullet;
IMeshSceneNode* bulletMesh;
// More Interfaces
// Meta triangle selector
IMetaTriangleSelector* meta;
// Collision response animator
ISceneNodeAnimator* anim;
};
Bullet.cpp
#include <irrlicht.h>
#include <iostream>
#include "Bullet.h"
using namespace irr;
using namespace core;
using namespace video;
using namespace scene;
using namespace gui;
using namespace std;
Bullet::Bullet(void)
{
goldBullet = 0;
bullMesh = 0;
}
Bullet::~Bullet(void)
{
}
bool Bullet::Initialize(void)
{
return false;
}
void Bullet::Shoot() // The method I am trying to call in the Survival::Run() Survival.cpp
{
sm = device->getSceneManager();
camera = sm->getActiveCamera();
device = createDevice(EDT_OPENGL, dimension2d<u32>(1200,720), 16, false, false, false, &appReceiver);
// create bullet
// Load in the bullet model .obj
bullMesh = sm->getMesh("C:/apps/irrlicht-1.8/irrlicht-1.8/media/bullet.obj");
if (!bullMesh) {
cout << "cannot load bullet" << endl;
//return false;
}
goldBullet = sm->addMeshSceneNode(bullMesh);
if (goldBullet)
{
goldBullet->setMaterialFlag(EMF_LIGHTING, false);
goldBullet->setMaterialTexture(0, driver->getTexture("C:/apps/irrlicht-1.8/irrlicht-1.8/media/roughgold.jpg"));
}
//goldBullet->setParent();
//goldBullet->setPosition(core::vector3df(7,-7,10));
//goldBullet->setScale(core::vector3df(0.8,0.8,0.8));
//goldBullet->setRotation(core::vector3df(0,90,0));
vector3df start = goldBullet->getAbsolutePosition();
vector3df end = (camera->getTarget() - camera->getPosition());
start = camera->getPosition();
end = (camera->getTarget() - camera->getPosition());
goldBullet->setPosition(start);
goldBullet->setScale(core::vector3df(0.8,0.8,0.8));
goldBullet->setRotation(core::vector3df(0,90,0));
end.normalize();
SBullet bullet;
bullet.direction = end;
start += end*20.0f;
end = start + (end * camera->getFarValue());
goldBullet->setRotation(bullet.direction.getHorizontalAngle());
cout << "shoot" << endl;
bullet.node = goldBullet;
node->setName("bullet");
f32 length = (f32)(end - start).getLength();
const f32 speed = 0.6f;
u32 time = (u32)(length / speed);
scene::ISceneNodeAnimator* anim = 0;
// set flight line
anim = sm->createFlyStraightAnimator(start, end, time);
goldBullet->addAnimator(anim);
anim->drop();
// when it should disappear
bullet.when = device->getTimer()->getTime() + (time - 100);
Bullets.push_back(bullet);
return;
}
void Bullet::createBulletImpacts()
{
u32 now = device->getTimer()->getTime();
sm = device->getSceneManager();
// get collision manager
ISceneCollisionManager* collMan = sm->getSceneCollisionManager();
for (s32 i=0; i<(s32)Bullets.size(); ++i)
{
if (now > Bullets[i].when)
{
// out of time, so remove it
Bullets[i].node->remove();
Bullets.erase(i);
i--;
}
else
{
// the particle effect is stationary - does not move around with what is hit
// has there been a collision?
line3d<f32> ray;
ray.start = Bullets[i].node->getPosition();
ray.end = ray.start + Bullets[i].direction*10;
// Tracks the current intersection point with the level or a mesh
vector3df intersection;
// Used to show with triangle has been hit
triangle3df hitTriangle;
// cout << "ray start " << ray.start.X << "," << ray.start.Y << "," << ray.start.Z << endl;
// cout << "ray direction " << Bullets[i].direction.X << "," << Bullets[i].direction.Y << "," << Bullets[i].direction.Z << endl;
if (!collMan)
exit(1);
core::vector3df hitPoint;
scene::ISceneNode* hitNode = 0;
const scene::ISceneNode* nodehit = 0;
core::vector3df collisionPoint(0.0f,0.0f,0.0f);
core::vector3df pnt(0.0f,0.0f,0.0f);
core::triangle3df triangle;
if (meta && collMan->getCollisionPoint(
ray, meta, hitPoint, triangle, hitNode))
{
scene::ISceneNode *nodehit =
collMan->getSceneNodeAndCollisionPointFromRay
(ray, collisionPoint, triangle);
cout << "its a hit with" << hitNode->getName() << " at (" << hitPoint.X << "," << hitPoint.Y << "," << hitPoint.Z << ")" << endl;
cout << "collision point " << collisionPoint.X << "," << collisionPoint.Y << "," << collisionPoint.Y << endl;
cout << "hit node absolute position " << hitNode->getAbsolutePosition().X << "," << hitNode->getAbsolutePosition().Y << "," << hitNode->getAbsolutePosition().Z << endl;
cout << "hit node position " << hitNode->getPosition().X << "," << hitNode->getPosition().Y << "," << hitNode->getPosition().Z << endl;
// create smoke particle system
IParticleSystemSceneNode* pas = 0;
cout << "hit node scale (" << hitNode->getScale().X << "," <<
hitNode->getScale().Y << "," << hitNode->getScale().Z << ")" << endl;
cout << "hit node apos (" << hitNode->getAbsolutePosition().X << "," <<
hitNode->getAbsolutePosition().Y << "," << hitNode->getAbsolutePosition().Z << ")" << endl;
cout << "hit node pos (" << hitNode->getPosition().X << "," <<
hitNode->getPosition().Y << "," << hitNode->getAbsolutePosition().Z << ")" << endl;
cout << "AT THIS BIT" << endl;
if (nodehit) cout << "nodehit is " << nodehit->getName() << endl;
// check nodehit and if the nodehit has collided, set the node invisible
if (nodehit)
nodehit->setVisible(false);
cout << "nodehit pointer is " << nodehit << endl;
// delete entry
Bullets[i].node->remove();
Bullets.erase(i);
i--;
}
}
}
}
Survival.cpp
int Survival::Run()
{
if (!device)
return 1;
wchar_t tmp[255];
// Game Loop
while (device->run())
{
if (device->isWindowActive())
{
camera->getPosition().X,
camera->getPosition().Y,
camera->getPosition().Z;
vector3df campos = camera->getAbsolutePosition();
f32 const vehicleLength = camera->getBoundingBox().getExtent().Z * 0.5f;
vector3df cameraDirection(0, 0, -vehicleLength);
vector3df cameraDown = vector3df(0, 1, 0).crossProduct(cameraDirection);
vector3df frontCentre = campos + cameraDirection + cameraDown;
// This is the way the vehicle is pointing.
// Note that I use Z as forwards
cout << "vehicleDirectionA (" << cameraDirection.X << "," << cameraDirection.Y << "," << cameraDirection.Z << ")" << endl;
//cout << " X = " << camera->getPosition().X << " , Y = " << camera->getPosition().Y << " , Z = " << camera->getPosition().Z << endl;
if (appReceiver.isKeyDown(KEY_ESCAPE))
{
device->closeDevice();
return 1; // appReceiver
}
if (appReceiver.isKeyDown(KEY_KEY_F))
{
Shoot(); // here is where the simple call to the method shoud work (works in a different example)
}
driver->beginScene(true, true, SColor(255, 255, 255, 255));
smgr->drawAll();
// Draw the Crosshairs
driver->draw2DImage(image, position2d<s32>(579,337),
rect<s32>(0, 0, 48, 48), 0,
SColor(255,255,255,255), true);
driver->endScene();
}
else device->yield();
}
device->drop();
return 0;
}