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;
}

Shoot is a method defined on the object Bullet. In your definition, you can not shoot without a bullet, so to speak. You have a couple of choices:
Create a Bullet object and call shoot through that

Bullet b;
b.Shoot();

Make the Shoot method static on Bullet and call it that way

class Bullet {
 ...
 static void Shoot () { ... }
 ...
};

// Then elsewhere

Bullet::Shoot();

Or, simply define a method Shoot outside the Bullet class and call it exactly as you have it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.