Can't get my class to work

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
kaka
Posts: 12
Joined: Thu Mar 15, 2012 9:08 pm

Can't get my class to work

Post by kaka »

So i have been learning c++ since October and i think i'm understanding how object orienting programming works. Now the problem is i understand the theory of it but can't put them into practical use. Now i have to make a game using Irrlicht for uni assignment :roll: . I've read the book "Irrlicht 1.7 Realtime 3D Engine Beginner's Guide" by Johannes Stein, Aung Sithu Kyaw (skipped the last chapter)which taught me the basics of Irrlicht fine and i've also followed some of the tutorials on the Irrlicht website. Now the problem is i'm trying to create classes that do simple things like creating a device, scene manager and video driver.

So this is what i've done so far. I've created a class called engine which creates a device, scene manager and video driver. This all works fine but when i try to create a void function which has the game loop in it i get errors.

here is the code:

engine.h

Code: Select all

#pragma once
#include<irrlicht.h>
class engine
{
public:
        engine();
        scene::ISceneManager* smgr;
        video::IVideoDriver *driver;
        void engine::loop();
private:
        IrrlichtDevice *device;
 
};
 
engine.cpp

Code: Select all

#include "engine.h"
#include<irrlicht.h>
#include "createTerrain.h"
 
using namespace irr;
 
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
 
 
engine::engine()
{
        IrrlichtDevice *device = createDevice(video::EDT_OPENGL, 
                core::dimension2d<u32>(640, 480), 16,false, false, false, 0);
 
        driver=device->getVideoDriver();
        smgr=device->getSceneManager();
 
}
 
void engine::loop(){
        while(device->run())
        {
                driver->beginScene(true,true,video::SColor(255,100,101,140));
                smgr->drawAll();
 
                driver->endScene();
        }
        device->drop();
 
}
 
I'm using visual studio 2010 and the device ,video and smgr pointers are underlined in red with an error that says <error-type> *engine::device
Error:Expression must have pointer to class type

I know i have probably missed some basic fundementals of c++ but i cant figure it out :cry:

If possible could you point me in the right direction instead of giving me a direct answer so that i can solve it myself. unless this is a really stupid question and the answer is really straightforward :oops:
CuteAlien
Admin
Posts: 9682
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Can't get my class to work

Post by CuteAlien »

Irrlicht is in a namespace. The examples (and the book) often avoid having to type the namespace each time so they are lazy and just add that at the beginning:

Code: Select all

 
using namespace irr; 
 
Also often the same for sub-namespaces like scene, gui and so on. You could do that in the header and your error would go away, but it's not really a clean solution as you should never do "using namespace" in a header as that more or less defeat the purpose of namespaces. Instead in the header type all namespaces explicit before each variable. In your case "irr::IrrlichtDevice". In source-file it's up to you, adding a "using namespace" in sources is usually fine (as it only affect that .cpp file so if it causes trouble with colliding namespaces it's easy to find the reason unlike when it's hidden in some header).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
kaka
Posts: 12
Joined: Thu Mar 15, 2012 9:08 pm

Re: Can't get my class to work

Post by kaka »

O...M...G
I learned about namespaces on the first day of using irrlicht and told myself i wouldn't use them because just like you said it's not very good idea. cant believe i didn't spot that. i'v spent hours on this!!!! RAAAGGEEEE

well thanks anyway. i'll definitely not make this mistake EVER AGAIN!

also can i ask is this the right way to go about making a game? if for example i want to create a terrain. do i make a class terrain and then set attributes to it and then create the object in the engine class?
CuteAlien
Admin
Posts: 9682
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Can't get my class to work

Post by CuteAlien »

There is no single way to do it that is correct, how to split classes and how to name them is more or less up to the programmer. The question is always what the job of class is. In your case "engine" it's a little hard to tell on first view. You already have a 3d-engine (Irrlicht), so you probably don't want to code another one. "engine" could still be a wrapper between your application on the 3D engine, but you shouldn't really add classes before you know you need them.

What it looks like to me so far is that his is your main application class (every applications usually has one of those). I typically name them either "Application" or after the name of my Application for examle "PacmanApp". Terrain - again something Irrlicht already offers, so basically you just need a pointer to the terrain scenenode. If you have a small game with just one terrain you can put it in your main-class. If you have a large game where each level is different you might have "Level" or "Scene" classes. Or maybe you have class for the ingame-state (I call those usually "Game") which contains the 3D Data which is only used while the game is actually played (and not in main-menu or so).

What I often start with in new applications is first thinking about which menus I will need. Those often define the different states of your game rather well. For example old-time homecomputer games usually have "Intro", "MainMenu", "Highscores", "Game" (or "InGame") and maybe some "CutScene". So I would create a GUI-class for each of those. The minimum you usually have is "MainMenu" (to start/quit) and "Game" (to play).

I put Irrlicht-setup and the main-loop usually in my main application class. But the part inside the main-loop can be Update functions from all kind of other classes. Like Physics.Update(), Input.Update(), Game.Update(), which are just functions called in each step and contain the real game-logic.

But really - lots of ways to do it - just think about what you want to do how you would like to group it and make sure you really know what a class should do.
Also always OK to refactor when a class get's too fat - or has nothing to do.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
kaka
Posts: 12
Joined: Thu Mar 15, 2012 9:08 pm

Re: Can't get my class to work

Post by kaka »

oh right yeh. what you have done makes a lot more sense then what i'm doing. I'm just trying to complicate things and making it harder for myself. I think i'll first go and make a class diagram to see what classes i'll need instead of making it up as i go along and work from there.

Thank you so much for your help. i have learnt a lot. if i do complete making a game i'll upload it so that i can show it of :lol:
gerdb
Posts: 194
Joined: Wed Dec 02, 2009 8:21 pm
Location: Dresden, Germany

Re: Can't get my class to work

Post by gerdb »

Code: Select all

class engine
{
public:
        engine();
        scene::ISceneManager* smgr;
        video::IVideoDriver *driver;
        void engine::loop(); // error --> loop() already in class engine, so no need for "engine::"
private:
        IrrlichtDevice *device;
};
 
to

Code: Select all

class Application : public IEventReceiver
{
public:
        Application()
        {
             myDevice = createDevice(video::EDT_OPENGL);
             myDevice->setEventReceiver(this);
        }
        
        ~Application()
        {
             if (myDevice)
                  myDevice->drop();
        }
 
        virtual bool run()
        { 
             bool result = false;
             if (myDevice)
             {
                   result = myDevice->run();
 
                   // do what you like before returning, like check for resize events, move camera, render screen etc.
              }
              return result;
        }
 
        virtual bool OnEvent(const SEvent& event)
        { 
             return false;
        }
 
        virtual IrrlichtDevice* getDevice() { return (myDevice) ? myDevice : 0; }
        virtual IrrlichtDevice* getNullDevice() { return createDevice(video::EDT_NULL); }
        virtual scene::ISceneManager* getSceneManager()  { return (myDevice) ? myDevice->getSceneManager() : 0; }
        virtual video::IVideoDriver* getVideoDriver()  { return (myDevice) ? myDevice->getVideoDriver() : 0; }
private:
        IrrlichtDevice *myDevice;
        scene::ISceneManager* myScene;
        video::IVideoDriver *myDriver;
};
make the pointers internal and show the rest of your app no internal data, just access them by memberfunctions like getDevice(),
so you can test for nullptrs or check user input before changing internal things --> OOP

I also found most sense making, to derive my App class from IEventReceiver, so my Apps set the "this" pointer as irrlicht eventreceiver
per myDevice->setEventReceiver(this), and i implement a method OnEvent that controls the app additionaly, so no extra class MyEventReceiver, just this App class.

Of course you can make more EventReceiver classes, i.e depending on your game state (Menu, Play, etc) and set them to device when needed, i.m.h.o.
test your game logic in main function before implementing and sorting in classes, the main function should be the main playground of your experiments.

have fun
Post Reply