CPlusEngine Controllers
You maybe wondering what a controller is and why you or your players would care. The controller system is how you can make the game engine interact with the player. This is at the core of any game that addresses how players interact with your game world. Because there are so many different ways for players to do this the controller class was designed to be as generic as possible.
The high level interface classes are designed so that your game can implement any kind of input device and then translate it into game commands. In this part of the documentation we will be using a keyboard class which has been provided as part of the engine to show how a controller can be constructed.
Some important things to think about when designing a controller for your game is how customizable do you need the controller to be? Many times game will need a way to remap the controller based on what the player wants for their controls. We can accomplish this by assigning the controller small commands to handle the player's input.
For example many first person shooter games (FPS) use the WASD keys to handle the player moving in the game world. We will map these keys plus the arrow keys to small commandlets that will then control how the game object is affected but the input.
To do this we will need to put together our controller and implement two interfaces in the game engine. The first one is the IController interface that just requires we add an Update() and Add() methods to our class. Let take a look at what we should expect from the controller in each of these methods:
Update(float deltaTime)
The update function will run once every frame during the update process of the engine, this happens before the render stage. This would be where we would add code that will need to simulate the game objects being moved by the controller when not using velocity. The example code in CPlusEgnine::Controller::KeyController supports the velocity system so there wasn’t anything we needed to do in the Update method of this class.
The parameter deltaTime is the difference in time since the last time this update method was called. Note: If your movement seems to stutter a lot make sure your updates are using the deltaTime value. See the deltaTime section for more details.
Add(unsigned int key, LPCOMMAND cmd)
Use the Add method to map keys to the controller. If you look at the constructor for the KeyController you will see how the WASD get mapped to the up, left, down, and right commands respectfully. To change how this controller will use keys on the keyboard it is as simple as telling it the key number and the command you want to add. For example call the add method:
keyController.Add(KC_J, new CmdMoveLeft());
Will map the move left command to the J key on the keyboard.
But what about the instantiation? Like a good programmer you probably already seen that the KeyController requires a parameter to be properly created. It take a LPUPDATEABLE object. This object is what gets passed to the commandlet when a key event has been processed. You controller may want to do things differently and that is okay just make sure you have a way to communicate with your game world and the controller.
All objects in the game engine that implement the IUpdateable interface can be connected to the controller.
The controller as it stands will sit in the game engine and do nothing. This is because we haven’t tied it to the event system. For more details on the event system see the events section.
The KeyController implements the IHandeler interface which just tells us we need to create a HandleEvent(void *obj, EventType type, EventArgs *e) method to our class. Because we implement the IHandler interface our controller can sit right on the Event stack and get input when it is recieved.
Note: A controller doesn’t have to be something real, it can be your AI system, a Network connection, or any other method you want to attach a controller to a game object.
Note: Currently the game engine only supports digital input but in future revisions we will add support for analog devices.
For this controller we connected it to theKeyDown and KeyUp events which then would just adjust the object’s velocity. The reason we did this was because it put the controller into a push method where the only time it needed to do any work was when the key state changed. This was nice because then we didn’t have to deal with polling the keyboard every frame checking for any changes.