States, game and menu classes
States, game and menu classes
Hi, I want to make a simple game. I searched on this forum and I found game called Jetpac and states. So I wrote states like in Jetpac, but I dont know how to correctly use it. I have game class(inherited from IEventReceiver) that contains main menu class, states and changeState function. Main menu inherited from IGUIElemnt. So how to for example close Irrlicht device when user click quit(button in main menu)? I can check in game::onEvent function who called event (and set some buttons constant id), but is it correctly in OOP?
-
- Posts: 363
- Joined: Thu Dec 16, 2010 8:50 pm
- Location: Somewhere in the clouds.. drinking pink lemonade and sunshine..
it shows how to do that in example 5
here's a little snippet from that example
here's a little snippet from that example
Code: Select all
case EGET_BUTTON_CLICKED:
switch(id)
{
case GUI_ID_QUIT_BUTTON:
Context.device->closeDevice();
return true;
ent1ty wrote: success is a matter of concentration and desire
at a cost measure in computer resourcesButler Lampson wrote: all problems in Computer Science can be solved by another level of indirection
Maybe you should try to set up something simpler, like a console app that would switch states or call functions based on the input, then when you understand how it works, try to do the same with irrlicht. But don't start doing stuff with irrlicht untill you understand the very basics of c++, like classes inheritance, containers, Polymorphism and some basics of how to use templates.Galhad wrote:This isnt problem. I know that. But menu cant call function from game class. Game contains menu. What should I do?
EDIT
Sorry I forgot that menu has its own OnEvent function for its childs
Working on game: Marrbles (Currently stopped).
Guys, maybe I asked the wrong.. I understand oop and templates. Maybe code of app help, but I dont know is it make sense to copy all code here.. Game class is event receiver, so events go to it first. I dont know exactly which gui element called event(for example user clicked quit, I know that this is menu event, but in game class I dont know which from menu). So if I give this buttons id, and I will check later id in Game event receiver will it solve problem and it will be still OOP?
well, this is not a question of being OOP or not, you simply don't understand how states work (as far as I understand you)...
a state usually is stored in a variable either a global one (many will say "no, don't use globals") or a variable inside your event receiver...
as long as nothing happened the state (the variable) is set to (eg) STATE_NOTHING...
then when an event happenes the state is set to a new value, maybe to STATE_CLOSE when you click on an exit button...
the state variable must be accessible from everywhere, so either it's global or you provide a function in the event receiver that returns the state value...
so from the main loop you can check the state variable and act on it's value (eg. close the program when the value is STATE_CLOSE)...
I hope this helps
a state usually is stored in a variable either a global one (many will say "no, don't use globals") or a variable inside your event receiver...
as long as nothing happened the state (the variable) is set to (eg) STATE_NOTHING...
then when an event happenes the state is set to a new value, maybe to STATE_CLOSE when you click on an exit button...
the state variable must be accessible from everywhere, so either it's global or you provide a function in the event receiver that returns the state value...
so from the main loop you can check the state variable and act on it's value (eg. close the program when the value is STATE_CLOSE)...
I hope this helps
while(!asleep) sheep++;
IrrExtensions:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
IrrExtensions:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
-
- Posts: 363
- Joined: Thu Dec 16, 2010 8:50 pm
- Location: Somewhere in the clouds.. drinking pink lemonade and sunshine..
if you really understood oop like you say you do you could look through the tutorials and it would answer aaaaaallll your questions you typed there and then someGalhad wrote:Guys, maybe I asked the wrong.. I understand oop and templates. Maybe code of app help, but I dont know is it make sense to copy all code here.. Game class is event receiver, so events go to it first. I dont know exactly which gui element called event(for example user clicked quit, I know that this is menu event, but in game class I dont know which from menu). So if I give this buttons id, and I will check later id in Game event receiver will it solve problem and it will be still OOP?
ent1ty wrote: success is a matter of concentration and desire
at a cost measure in computer resourcesButler Lampson wrote: all problems in Computer Science can be solved by another level of indirection
Complicated state managers quickly turn into a nightmare, hybrid (I think) posted his favorite solution which was used a template and a tree to represent states. I found it to clunky to work right.
I recommend a simple solution, here's mine:
Just extend state and implement virtual functions, then add a STATE enum. Simple.
(I left out the other state classes for simplicity.)
I recommend a simple solution, here's mine:
Code: Select all
/**
StateMngr class
*/
class StateMngr {
private:
// state the game is in
STATES gameState;
// the scene manager
scene::ISceneManager* smgr;
gui::IGUIEnvironment* guienv; // the gui to create buttons
Settings* mainSettings;
State* state;
public:
// construictor
StateMngr(IrrlichtDevice* device,
Settings* inmainSettings
) :
mainSettings(inmainSettings)
{
// init game here
smgr = device->getSceneManager ();
guienv = smgr->getGUIEnvironment();
gameState = STATE_MENU;
};
~StateMngr() {
};
// --- Returns the state this game is in ---
STATES getState() {return gameState;}
// --- update the current state ---
void update (irr::EKEY_CODE k) {
if (!state) return;
state->update(k);
if (state->getState() != state->currentState()) {
printf("change State %d %d\n", state->getState(), state->currentState());
STATES newState = state->getState();
delete state; // remove old state
state = 0;
switch (newState) {
case STATE_NONE:
state = new EndState(smgr);
break;
case STATE_PLAYING:
state = new PlayState(smgr);
break;
case STATE_EDIT:
state = new EditState(smgr);
break;
case STATE_MENU:
state = new MenuState(smgr);
break;
case STATE_OPTIONS:
state = new OptionsState(smgr);
break;
default:
break;
}
}
};
};
#endif
#ifndef _STATE_PARENT_H_
#define _STATE_PARENT_H_
// States of the game
enum STATES {
STATE_NONE = 0, // doing nothing
STATE_PLAYING, // Playing in game
STATE_EDIT, // Creating / editing a map
STATE_MENU, // Upon start, select where to go
STATE_OPTIONS, // edit game options
STATE_INGAMEOPTIONS // edit game options
};
/** State class
*/
class State {
protected:
STATES gameState;
public:
virtual ~State() {
printf("state delete \n");
}
virtual void update(irr::EKEY_CODE k) = 0;
// what state I want to be in
STATES getState () const { return gameState; };
// what state I actually am
virtual STATES currentState () = 0;
};
#endif
Just extend state and implement virtual functions, then add a STATE enum. Simple.
(I left out the other state classes for simplicity.)
-
- Posts: 363
- Joined: Thu Dec 16, 2010 8:50 pm
- Location: Somewhere in the clouds.. drinking pink lemonade and sunshine..
personally i dont find states too attractive... they make me feel like im severaly restricting my gameplay.
my design has a more emergent functionality. now that is a bit dangerous though.. since it could cause bizzare behvaiour, since im not explicitly defining the state of my system but letting it define its own state "by itself".
other concept thing that i am sure will cause some crashes in my design is my event system. it is so convoluted trEventType objects are actually instanced and registered with dynamically generated IDs. all trEvent objects of one type of event have a pointer to an instance of a trEventType.
the trEventFactory manages registration of events keeps tabs on the global count and has a table alphabetized by event name so when a new event needs an event of some type it either goes to that table or is dynamically assigned an event type instance with optimized methods through one of its peers of its parent trEventNode
pretty crazy and not sure it will even work if you ask me
EDIT: those ideas were so crazy i couldnt think of a starting point to start testing that kind of design. so i decided to just hardcode a small game and then reverse engineer that game to get it to fit into the design style i first mentioned.
my design has a more emergent functionality. now that is a bit dangerous though.. since it could cause bizzare behvaiour, since im not explicitly defining the state of my system but letting it define its own state "by itself".
other concept thing that i am sure will cause some crashes in my design is my event system. it is so convoluted trEventType objects are actually instanced and registered with dynamically generated IDs. all trEvent objects of one type of event have a pointer to an instance of a trEventType.
the trEventFactory manages registration of events keeps tabs on the global count and has a table alphabetized by event name so when a new event needs an event of some type it either goes to that table or is dynamically assigned an event type instance with optimized methods through one of its peers of its parent trEventNode
pretty crazy and not sure it will even work if you ask me
EDIT: those ideas were so crazy i couldnt think of a starting point to start testing that kind of design. so i decided to just hardcode a small game and then reverse engineer that game to get it to fit into the design style i first mentioned.
ent1ty wrote: success is a matter of concentration and desire
at a cost measure in computer resourcesButler Lampson wrote: all problems in Computer Science can be solved by another level of indirection
yes, each state has a reference to the GUI items used. I simply cleared the UI state manager between states (on the deconstructor method.) Ultimately you should pass an Event struct on an event instead of a key, but since my game didn't need it I didn't bother with it.Galhad wrote:Thanks for replies
@pippy3
So eg. Options State class should contains gui options menu?
By not clearing the scene manager, it allows for states like paused. If you're changing between two levels clear the scene and the ui manager.