Lab 5: Control a character with a controller

Prerequisite: Read Overview of the MVC Pattern

Our goal is to control the astronaut through a game controller (gamepad, mouse, keyboard, buttons, etc.) using the steps mentioned in this article. Along the way, you will learn how the MVC components communicate with each other.

Before we can control an object, we need to create it. Therefore, create a character as specified in Rendering Lab 1

Step 1. Get Character Pointer

In our project, the class Earth implements the View component of the MVC. Whereas, the class GameLogic implements the Model component of the MVC.

Our first step is to get a pointer to the astronaut from the View Component.

In the engine, open the file GameLogic.mm and scroll down to the init() method.

Get a pointer to the View component (Earth class) and then search for the astronaut character as shown in lines 1 & 2.

void GameLogic::init(){
//1. Get a pointer to the Earth object
Earth *pEarth=dynamic_cast<Earth*>(getGameWorld());
//2. Search for the Astronaut object
pAstronaut=dynamic_cast<U4DGameObject*>(pEarth->searchChild("astronaut"));
}

Step 2. Process Message from Controller

Once you have the pointer to the astronaut, you can now process the message from the controller. The message from the controller is handled by the receiveUserInput() method.

For simplicity, I've populated the receiveuserInputUpdate() method with three switch cases. These cases detect if the user-input was an action from Button A, Button B or a Joystick.

In the GameLogic.mm file, go to the receiveUserInputUpdate() method and scroll down to the switch statement.

Within the switch statement, scroll down to case actionButtonA. If this case is detected, i.e., button A is Pressed, we are going to rotate the character, as shown in line 4a.

void GameLogic::receiveUserInputUpdate(void *uData){
//1. Get the user-input message from the structure
ControllerInputMessage controllerInputMessage=*(ControllerInputMessage*)uData;
//2. Determine what was pressed, buttons, keys or joystick
switch (controllerInputMessage.controllerInputType) {
//3. Did Button A on a mobile or game controller receive an action from the user (Key A on a Mac)
case actionButtonA:
{
//4. If button was pressed
if (controllerInputMessage.controllerInputData==buttonPressed) {
//4a. What action to take if button was pressed
std::cout<<"Button A Pressed"<<std::endl;
pAstronaut->rotateBy(0.0, 10.0, 0.0);
//5. If button was released
}else if(controllerInputMessage.controllerInputData==buttonReleased){
}
}
break;
}
//....

Next, scroll down to case actionButtonB. In this instance, we are going to rotate the character in the opposite direction if button B is pressed, as shown in line 7a.

//6. Did Button B on a mobile or game controller receive an action from the user. (Key D on Mac)
case actionButtonB:
{
//7. If button was pressed
if (controllerInputMessage.controllerInputData==buttonPressed) {
//7a. What action to take if button was pressed
std::cout<<"Button B Pressed"<<std::endl;
pAstronaut->rotateBy(0.0, -10.0, 0.0);
//8. If button was released
}else if(controllerInputMessage.controllerInputData==buttonReleased){
}
}
break;

Finally, scroll down to case actionJoystick. If the joystick is moved, we translate the character as shown in line 12.

//9. Did joystic on a mobile or game controller receive an action from the user. (Arrow keys and Mouse on Mac)
case actionJoystick:
{
//10. Joystick was moved
if (controllerInputMessage.controllerInputData==joystickActive) {
//11. Get joystick movement
JoystickMessageData joystickMessageData;
//11a. Get Joystick direction
joystickMessageData.direction=controllerInputMessage.joystickDirection;
//12. What action to take when joystick is moved.
std::cout<<"Joystick moved"<<std::endl;
U4DVector3n dir=joystickMessageData.direction;
dir*=0.01;
pAstronaut->translateBy(dir.x,0.0,dir.z);
}else if(controllerInputMessage.controllerInputData==joystickInactive){
}
}
break;

Results

In Xcode, select either the iOS or Mac device and then click on Run.

If you are running the code on your Mac device, then press the arrow keys to translate the character. Use the keys A and D to rotate the character. Alternatively, you can also use the mouse to translate the character.

image1

Source Code

Download the source game files from our Github Tutorials page.