-
Notifications
You must be signed in to change notification settings - Fork 164
Game
The entry point to a game made in Halley is a class derived from Halley::Game
. This represents the unique instance of your game, and controls the running of the engine.
In your .cpp file corresponding to your implementation of the game class, you'll need to implement the following magical macro, which initialises Halley with an instance of your game class:
class MyGame final : public Halley::Game
{
// ...
}
HalleyGame(MyGame);
In a nutshell, this function defines a main() function, and creates a Halley::Core and instantiates MyGame with it.
When the game engine runs, it will call the Game methods in the following order:
- Game Constructor
- Game::init()
- Game::initPlugins()
- Game::initResourceLocator()
- Game::startGame()
- Halley Main Loop
- Game::endGame()
- Game Destructor
Some const methods (such as Game::getName()) will be called inbetween those.
virtual void init(const Environment&, const Vector<String>& args);
This method allows you to parse the command line arguments passed to the game and store them in your instance.
virtual int initPlugins(IPluginRegistry& registry) = 0;
This method allows you to initialise the plugins (see API) needed for this version of the game. Because plugins are linked as headerless libraries, you'll often want to declare a prototype for the plugin you're invoking here, and call it at this point, so Halley registers it. This method also returns which types of plugins Halley should attempt to initialise.
For a typical example of a game on PC:
void initOpenGLPlugin(IPluginRegistry ®istry);
void initSDLSystemPlugin(IPluginRegistry ®istry);
void initSDLAudioPlugin(IPluginRegistry ®istry);
void initSDLInputPlugin(IPluginRegistry ®istry);
void initDX11Plugin(IPluginRegistry ®istry);
void initWinRTPlugin(IPluginRegistry ®istry);
void initMFPlugin(IPluginRegistry ®istry);
int MyGame::initPlugins(IPluginRegistry ®istry)
{
#ifdef WITH_SDL2
initSDLSystemPlugin(registry);
initSDLInputPlugin(registry);
initSDLAudioPlugin(registry);
#endif
#ifdef WITH_WINRT
initWinRTPlugin(registry);
#endif
#ifdef WITH_MEDIA_FOUNDATION
initMFPlugin(registry);
#endif
#ifdef WITH_OPENGL
initOpenGLPlugin(registry);
#endif
#ifdef WITH_DX11
initDX11Plugin(registry);
#endif
return HalleyAPIFlags::Video | HalleyAPIFlags::Audio | HalleyAPIFlags::Input | HalleyAPIFlags::Movie;
}
virtual void initResourceLocator(Path path, ResourceLocator& locator);
Allows you to configure the resource locator, used for loading assets. A typical implementation is simply:
void MyGame::initResourceLocator(Path dataPath, ResourceLocator& locator)
{
locator.addFileSystem(dataPath);
}
virtual std::unique_ptr<Stage> startGame(const HalleyAPI* api) = 0;
This method is called after the API has been initialised. It has two primary functions:
You may also want to perform other initialisation here, before the game starts. At this point, most of the engine is fully functional, and it's generally safe to use the various APIs (provided you've initialised anything you needed).
A simple example:
std::unique_ptr<Stage> MyGame::startGame(const HalleyAPI* api)
{
api->video->setWindow(WindowDefinition(WindowType::BorderlessWindow, Vector2i(1280, 720), getName()), true);
api->audio->startPlayback(audioDeviceN);
return std::make_unique<MyStage>();
}
virtual void endGame();
This method provides you a chance to do clean-up before exiting. You don't typically need to do anything here.