Switching level

Post your questions, suggestions and experiences regarding game design, integration of external libraries here. For irrEdit, irrXML and irrKlang, see the
ambiera forums
Post Reply
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Switching level

Post by Virion »

hello guys, i have a question. normally we initialize a level before the main loop right? but what if I want to switch to the second level? what you guys normally do, init some other levels in the main loops or init all levels before the main loop?
torleif
Posts: 188
Joined: Mon Jun 30, 2008 4:53 am

Post by torleif »

I usually create a game state manager class. This creates and destroys the current game state, or adds and removes GUI elements.

The benefit of using this approach is that the main loop is very tidy, and it hides the init function in the state constructor. it's also a handy place to put the game factory for creating in game objects (though I like to put this in the base game state manager, in a static pointer that all game states extend) and to put all GUI elements, (or if you have many GUI states, a pointer to the current UI state)

This can get confusing in lingo terms, as pausing the game may seem like a state, but in fact is not. it's simply changing the GUI object (as well as stopping time).
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

how to prevent adding the same object multiple time, if say, the constructor is inside the main loop?
Laptev
Posts: 27
Joined: Tue Jun 03, 2008 4:36 am
Location: Romania

Post by Laptev »

use this:

game.h

Code: Select all

enum GameState
{
	EGS_NONE,
	EGS_LOGOSCREEN,
	EGS_MAINMENU,
	EGS_INGAME
};

class MyGame : public IEventReceiver 
{
public:
	MyGame(){};

	bool Initiate(E_DRIVER_TYPE driverType, dimension2d<u32> screenSize, bool fullscreen);
	void Loop();
	bool CloseGame();

	bool OnEvent(const SEvent& event);

private:
	void RenderLogoScreen();
	void RenderMainMenu();
	void RenderInGame();
	void ClearAll();

	GameState CState;

private:
	bool logoloaded;
	bool menuloaded;
	bool gameloaded;

	IrrlichtDevice  *Device;
	IVideoDriver    *Driver;
	ISceneManager   *SceneManager;
	IGUIEnvironment *Gui;

	bool keys[KEY_KEY_CODES_COUNT];

};
game.cpp

Code: Select all

#include "MyGame.h"

// Initiate the Device
bool MyGame::Initiate(E_DRIVER_TYPE driverType, dimension2d<u32> screensize, bool fullscreen)
{
	Device       = createDevice(driverType, screenSize, 32, fullscreen, false, false);
	Device->setEventReceiver(this);

	Driver       = Device->getVideoDriver();
	SceneManager = Device->getSceneManager();
	Gui          = Device->getGUIEnvironment();
	
	logoloaded = menuloaded = gameloaded = false;
	CState = EGS_LOGOSCREEN;

	return true;
}

// Logo Screen
void MyGame::RenderLogoScreen()
{
	if(logoloaded == false)
	{
		ClearAll();
// Init Logo

		logoloaded = true;
	}
// Update Logo 
}

// Main Menu
void MyGame::RenderMainMenu()
{
	if(menuloaded == false)
	{
		ClearAll();
//Init Menu Scene

		menuloaded = true;
	}
//Update Menu Scene

}

// In Game
void MyGame::RenderInGame()
{
	if(gameloaded == false)
	{
		ClearAll();
// Init InGame Scene

		gameloaded = true;
	}
// Update InGame Scene

}

// Main Loop
void MyGame::Loop()
{
	while( Device->run() )
    {
		if(Device->isWindowActive())
		{

			Driver->beginScene(true, true, SColor(0,0,0,0) );

			SceneManager->drawAll();
			Gui         ->drawAll();

			// Switch Game State
			switch (CState)
			{
			case EGS_LOGOSCREEN :
					 RenderLogoScreen();
				break;
			case EGS_MAINMENU :
					 RenderMainMenu();
				break;
			case EGS_INGAME :
					 RenderInGame();
				break;
			default:
				CloseGame();
				break;
			}

			Driver->endScene();
		}
	}
}

// Clear Scene Manager and GUI Environment
void MyGame::ClearAll()
{
	SceneManager->clear();
	Gui->clear();

	logoloaded = false;
	menuloaded = false;
	gameloaded = false;
}

// Close Game
bool MyGame::CloseGame()
{
	ClearAll();
	Device->closeDevice();
	return 0;
}

// On Event
bool MyGame::OnEvent(const SEvent& event)
{
	if(event.EventType == EET_KEY_INPUT_EVENT)
	{
		keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
		if(keys[KEY_ESCAPE] == true)
		{
			switch(CState)
			{
			case EGS_LOGOSCREEN:
				CState = EGS_MAINMENU; 
				break;
			case EGS_MAINMENU:
				CState = EGS_NONE;
				break;
			case EGS_INGAME:
				CState = EGS_MAINMENU;
				break;
			default:
				CState = EGS_NONE;
				break;
			}
		}

		return true;
	}
	return false;
}

...and you can use this to load different levels too
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I'm partial to the state machine implementations describe here.

Travis
Post Reply