-
Notifications
You must be signed in to change notification settings - Fork 513
Game controller input
This lesson will show how to read user input from game controllers.
First create a new project using the instructions from the first two lessons: The basic game loop and Adding the DirectX Tool Kit which we will use for this lesson.
In the Game.h file, add the following variable to the bottom of the Game class's private declarations:
std::unique_ptr<DirectX::GamePad> m_gamePad;
In Game.cpp, add to the TODO of CreateDevice:
m_gamePad.reset(new GamePad());
In Game.cpp, add to the TODO of OnSuspending and OnDeactivated:
m_gamePad->Suspend();
In Game.cpp, add to the TODO of OnResuming and OnActivated:
m_gamePad->Resume();
In Game.cpp, add to the TODO of Update:
auto state = m_gamePad->GetState(0);
if (state.IsConnected())
{
// TODO: Read controller 0 here
}
Build and run. The application does not display anything or respond to input, but if a Xbox 360 Common Controller or Xbox One controller is plugged into the PC, then it will be detected.
Here we wire up the View button (know as the Back button on Xbox 360 Controllers) to exit the application.
In Game.cpp, modify the TODO section of Update:
auto state = m_gamePad->GetState(0);
if (state.IsConnected())
{
if (state.IsViewPressed())
{
PostQuitMessage(0); // Win32 desktop API for exiting the application
}
}
Build and run. The application exits when you press View / Back.
In Game.cpp, modify the TODO section of Update:
auto state = m_gamePad->GetState(0);
if (state.IsConnected())
{
if (state.IsViewPressed())
{
PostQuitMessage(0);
}
else
{
float left = (state.IsAPressed()) ? 1.f : 0;
float right = (state.IsBPressed()) ? 1.f : 0;
m_gamePad->SetVibration(0, left, right);
}
}
Build and run. If you press and hold A or B, you get vibration motors of the controller to activate.
In this version, we tie the left and right triggers to the vibration which provides an example of reading position information from a game controller.
In Game.cpp, modify the TODO section of Update:
if (state.IsConnected())
{
if (state.IsViewPressed())
{
PostQuitMessage(0);
}
else
{
m_gamePad->SetVibration( 0, state.triggers.left, state.triggers.right );
}
Build and run. Slowly depress the left and right triggers to feel the vibration motor change intensity.
Because we are checking the button states each frame, you need to track the button state to track transitions like "the button just went down" rather than "the button is down now".
In the Game.h file, add the following variable to the bottom of the Game class's private declarations:
DirectX::GamePad::ButtonStateTracker m_buttons;
In Game.cpp, add to the TODO of OnResuming and OnActivated:
m_buttons.Reset();
In *Game.cpp, modify the TODO section of Update:
if (state.IsConnected())
{
if (state.IsViewPressed())
{
PostQuitMessage(0);
}
m_buttons.Update(state);
if (m_buttons.a == GamePad::ButtonStateTracker::PRESSED)
{
// A was up last frame, it just went down this frame
}
if (m_buttons.b == GamePad::ButtonStateTracker::RELEASED)
{
// B was down last frame, it just went up this frame
}
}
Next lessons: Using the SimpleMath library, Adding the DirectX Tool Kit for Audio
DirectX Tool Kit docs GamePad
DirectX Tool Kit: Now with GamePads
XInput and Windows 8
All content and source code for this package are subject to the terms of the MIT License.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.
- Universal Windows Platform apps
- Windows desktop apps
- Windows 11
- Windows 10
- Windows 8.1
- Xbox One
- x86
- x64
- ARM64
- Visual Studio 2022
- Visual Studio 2019 (16.11)
- clang/LLVM v12 - v18
- MinGW 12.2, 13.2
- CMake 3.20