Skip to content

Commit 61782b5

Browse files
committed
Chapter 8 done
1 parent 4c04879 commit 61782b5

5 files changed

Lines changed: 203 additions & 21 deletions

File tree

Chapter08/InputComponent.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,23 @@ void InputComponent::ProcessInput(const InputState& state)
2424
{
2525
// Calculate forward speed for MoveComponent
2626
float forwardSpeed = 0.0f;
27-
if (state.Keyboard.GetKeyValue(mForwardKey))
27+
if (state.Keyboard.GetKeyValue(SDL_Scancode(mForwardKey)))
2828
{
2929
forwardSpeed += mMaxForwardSpeed;
3030
}
31-
if (state.Keyboard.GetKeyValue(mBackKey))
31+
if (state.Keyboard.GetKeyValue(SDL_Scancode(mBackKey)))
3232
{
3333
forwardSpeed -= mMaxForwardSpeed;
3434
}
3535
SetForwardSpeed(forwardSpeed);
3636

3737
// Calculate angular speed for MoveComponent
3838
float angularSpeed = 0.0f;
39-
if (state.Keyboard.GetKeyValue(mClockwiseKey))
39+
if (state.Keyboard.GetKeyValue(SDL_Scancode(mClockwiseKey)))
4040
{
4141
angularSpeed += mMaxAngularSpeed;
4242
}
43-
if (state.Keyboard.GetKeyValue(mCounterClockwiseKey))
43+
if (state.Keyboard.GetKeyValue(SDL_Scancode(mCounterClockwiseKey)))
4444
{
4545
angularSpeed -= mMaxAngularSpeed;
4646
}

Chapter08/InputSystem.cpp

Lines changed: 136 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
#include <SDL/SDL.h>
1111
#include <cstring>
1212

13-
bool KeyboardState::GetKeyValue(int keyCode) const
13+
bool KeyboardState::GetKeyValue(SDL_Scancode keyCode) const
1414
{
1515
return mCurrState[keyCode] == 1;
1616
}
1717

18-
ButtonState KeyboardState::GetKeyState(int keyCode) const
18+
ButtonState KeyboardState::GetKeyState(SDL_Scancode keyCode) const
1919
{
2020
if (mPrevState[keyCode] == 0)
2121
{
@@ -73,6 +73,37 @@ ButtonState MouseState::GetButtonState(int button) const
7373
}
7474
}
7575

76+
bool ControllerState::GetButtonValue(SDL_GameControllerButton button) const
77+
{
78+
return mCurrButtons[button] == 1;
79+
}
80+
81+
ButtonState ControllerState::GetButtonState(SDL_GameControllerButton button) const
82+
{
83+
if (mPrevButtons[button] == 0)
84+
{
85+
if (mCurrButtons[button] == 0)
86+
{
87+
return ENone;
88+
}
89+
else
90+
{
91+
return EPressed;
92+
}
93+
}
94+
else // Prev state must be 1
95+
{
96+
if (mCurrButtons[button] == 0)
97+
{
98+
return EReleased;
99+
}
100+
else
101+
{
102+
return EHeld;
103+
}
104+
}
105+
}
106+
76107
bool InputSystem::Initialize()
77108
{
78109
// Keyboard
@@ -85,6 +116,16 @@ bool InputSystem::Initialize()
85116
// Mouse (just set everything to 0)
86117
mState.Mouse.mCurrButtons = 0;
87118
mState.Mouse.mPrevButtons = 0;
119+
120+
// Get the connected controller, if it exists
121+
mController = SDL_GameControllerOpen(0);
122+
// Initialize controller state
123+
mState.Controller.mIsConnected = (mController != nullptr);
124+
memset(mState.Controller.mCurrButtons, 0,
125+
SDL_CONTROLLER_BUTTON_MAX);
126+
memset(mState.Controller.mPrevButtons, 0,
127+
SDL_CONTROLLER_BUTTON_MAX);
128+
88129
return true;
89130
}
90131

@@ -104,6 +145,11 @@ void InputSystem::PrepareForUpdate()
104145
mState.Mouse.mPrevButtons = mState.Mouse.mCurrButtons;
105146
mState.Mouse.mIsRelative = false;
106147
mState.Mouse.mScrollWheel = Vector2::Zero;
148+
149+
// Controller
150+
memcpy(mState.Controller.mPrevButtons,
151+
mState.Controller.mCurrButtons,
152+
SDL_CONTROLLER_BUTTON_MAX);
107153
}
108154

109155
void InputSystem::Update()
@@ -123,6 +169,36 @@ void InputSystem::Update()
123169

124170
mState.Mouse.mMousePos.x = static_cast<float>(x);
125171
mState.Mouse.mMousePos.y = static_cast<float>(y);
172+
173+
// Controller
174+
// Buttons
175+
for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++)
176+
{
177+
mState.Controller.mCurrButtons[i] =
178+
SDL_GameControllerGetButton(mController,
179+
SDL_GameControllerButton(i));
180+
}
181+
182+
// Triggers
183+
mState.Controller.mLeftTrigger =
184+
Filter1D(SDL_GameControllerGetAxis(mController,
185+
SDL_CONTROLLER_AXIS_TRIGGERLEFT));
186+
mState.Controller.mRightTrigger =
187+
Filter1D(SDL_GameControllerGetAxis(mController,
188+
SDL_CONTROLLER_AXIS_TRIGGERRIGHT));
189+
190+
// Sticks
191+
x = SDL_GameControllerGetAxis(mController,
192+
SDL_CONTROLLER_AXIS_LEFTX);
193+
y = -SDL_GameControllerGetAxis(mController,
194+
SDL_CONTROLLER_AXIS_LEFTY);
195+
mState.Controller.mLeftStick = Filter2D(x, y);
196+
197+
x = SDL_GameControllerGetAxis(mController,
198+
SDL_CONTROLLER_AXIS_RIGHTX);
199+
y = -SDL_GameControllerGetAxis(mController,
200+
SDL_CONTROLLER_AXIS_RIGHTY);
201+
mState.Controller.mRightStick = Filter2D(x, y);
126202
}
127203

128204
void InputSystem::ProcessEvent(SDL_Event& event)
@@ -146,3 +222,61 @@ void InputSystem::SetRelativeMouseMode(bool value)
146222

147223
mState.Mouse.mIsRelative = value;
148224
}
225+
226+
float InputSystem::Filter1D(int input)
227+
{
228+
// A value < dead zone is interpreted as 0%
229+
const int deadZone = 250;
230+
// A value > max value is interpreted as 100%
231+
const int maxValue = 30000;
232+
233+
float retVal = 0.0f;
234+
235+
// Take absolute value of input
236+
int absValue = input > 0 ? input : -input;
237+
// Ignore input within dead zone
238+
if (absValue > deadZone)
239+
{
240+
// Compute fractional value between dead zone and max value
241+
retVal = static_cast<float>(absValue - deadZone) /
242+
(maxValue - deadZone);
243+
// Make sure sign matches original value
244+
retVal = input > 0 ? retVal : -1.0f * retVal;
245+
// Clamp between -1.0f and 1.0f
246+
retVal = Math::Clamp(retVal, -1.0f, 1.0f);
247+
}
248+
249+
return retVal;
250+
}
251+
252+
Vector2 InputSystem::Filter2D(int inputX, int inputY)
253+
{
254+
const float deadZone = 8000.0f;
255+
const float maxValue = 30000.0f;
256+
257+
// Make into 2D vector
258+
Vector2 dir;
259+
dir.x = static_cast<float>(inputX);
260+
dir.y = static_cast<float>(inputY);
261+
262+
float length = dir.Length();
263+
264+
// If length < deadZone, should be no input
265+
if (length < deadZone)
266+
{
267+
dir = Vector2::Zero;
268+
}
269+
else
270+
{
271+
// Calculate fractional value between
272+
// dead zone and max value circles
273+
float f = (length - deadZone) / (maxValue - deadZone);
274+
// Clamp f between 0.0f and 1.0f
275+
f = Math::Clamp(f, 0.0f, 1.0f);
276+
// Normalize the vector, and then scale it to the
277+
// fractional value
278+
dir *= f / length;
279+
}
280+
281+
return dir;
282+
}

Chapter08/InputSystem.h

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#pragma once
1010
#include <SDL/SDL_scancode.h>
11+
#include <SDL/SDL_gamecontroller.h>
12+
#include <SDL/SDL_mouse.h>
1113
#include "Math.h"
1214

1315
// The different button states
@@ -26,9 +28,9 @@ class KeyboardState
2628
// Friend so InputSystem can easily update it
2729
friend class InputSystem;
2830
// Get just the boolean true/false value of key
29-
bool GetKeyValue(int keyCode) const;
31+
bool GetKeyValue(SDL_Scancode keyCode) const;
3032
// Get a state based on current and previous frame
31-
ButtonState GetKeyState(int keyCode) const;
33+
ButtonState GetKeyState(SDL_Scancode keyCode) const;
3234
private:
3335
const Uint8* mCurrState;
3436
Uint8 mPrevState[SDL_NUM_SCANCODES];
@@ -60,11 +62,42 @@ class MouseState
6062
bool mIsRelative;
6163
};
6264

65+
// Helper for controller input
66+
class ControllerState
67+
{
68+
public:
69+
friend class InputSystem;
70+
71+
// For buttons
72+
bool GetButtonValue(SDL_GameControllerButton button) const;
73+
ButtonState GetButtonState(SDL_GameControllerButton button) const;
74+
75+
const Vector2& GetLeftStick() const { return mLeftStick; }
76+
const Vector2& GetRightStick() const { return mRightStick; }
77+
float GetLeftTrigger() const { return mLeftTrigger; }
78+
float GetRightTrigger() const { return mRightTrigger; }
79+
80+
bool GetIsConnected() const { return mIsConnected; }
81+
private:
82+
// Current/previous buttons
83+
Uint8 mCurrButtons[SDL_CONTROLLER_BUTTON_MAX];
84+
Uint8 mPrevButtons[SDL_CONTROLLER_BUTTON_MAX];
85+
// Left/right sticks
86+
Vector2 mLeftStick;
87+
Vector2 mRightStick;
88+
// Left/right trigger
89+
float mLeftTrigger;
90+
float mRightTrigger;
91+
// Is this controller connected?
92+
bool mIsConnected;
93+
};
94+
6395
// Wrapper that contains current state of input
6496
struct InputState
6597
{
6698
KeyboardState Keyboard;
6799
MouseState Mouse;
100+
ControllerState Controller;
68101
};
69102

70103
class InputSystem
@@ -84,5 +117,8 @@ class InputSystem
84117

85118
void SetRelativeMouseMode(bool value);
86119
private:
120+
float Filter1D(int input);
121+
Vector2 Filter2D(int inputX, int inputY);
87122
InputState mState;
123+
SDL_GameController* mController;
88124
};

Chapter08/Ship.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,45 +8,54 @@
88

99
#include "Ship.h"
1010
#include "SpriteComponent.h"
11-
#include "InputComponent.h"
1211
#include "Game.h"
1312
#include "Laser.h"
1413
#include "InputSystem.h"
1514

1615
Ship::Ship(Game* game)
1716
:Actor(game)
17+
,mSpeed(400.0f)
1818
,mLaserCooldown(0.0f)
1919
{
2020
// Create a sprite component
2121
SpriteComponent* sc = new SpriteComponent(this, 150);
2222
sc->SetTexture(game->GetTexture("Assets/Ship.png"));
23-
24-
// Create an input component and set keys/speed
25-
InputComponent* ic = new InputComponent(this);
26-
ic->SetForwardKey(SDL_SCANCODE_W);
27-
ic->SetBackKey(SDL_SCANCODE_S);
28-
ic->SetClockwiseKey(SDL_SCANCODE_A);
29-
ic->SetCounterClockwiseKey(SDL_SCANCODE_D);
30-
ic->SetMaxForwardSpeed(300.0f);
31-
ic->SetMaxAngularSpeed(Math::TwoPi);
3223
}
3324

3425
void Ship::UpdateActor(float deltaTime)
3526
{
3627
mLaserCooldown -= deltaTime;
28+
29+
// Update position based on velocity
30+
Vector2 pos = GetPosition();
31+
pos += mVelocityDir * mSpeed * deltaTime;
32+
SetPosition(pos);
33+
34+
// Update rotation
35+
float angle = Math::Atan2(mRotationDir.y, mRotationDir.x);
36+
SetRotation(angle);
3737
}
3838

3939
void Ship::ActorInput(const InputState& state)
4040
{
41-
if (state.Keyboard.GetKeyValue(SDL_SCANCODE_SPACE)
41+
if (state.Controller.GetRightTrigger() > 0.25f
4242
&& mLaserCooldown <= 0.0f)
4343
{
4444
// Create a laser and set its position/rotation to mine
4545
Laser* laser = new Laser(GetGame());
4646
laser->SetPosition(GetPosition());
4747
laser->SetRotation(GetRotation());
4848

49-
// Reset laser cooldown (half second)
50-
mLaserCooldown = 0.5f;
49+
// Reset laser cooldown (quarter second)
50+
mLaserCooldown = 0.25f;
51+
}
52+
53+
if (state.Controller.GetIsConnected())
54+
{
55+
mVelocityDir = state.Controller.GetLeftStick();
56+
if (!Math::NearZero(state.Controller.GetRightStick().Length()))
57+
{
58+
mRotationDir = state.Controller.GetRightStick();
59+
}
5160
}
5261
}

Chapter08/Ship.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,8 @@ class Ship : public Actor
1616
void UpdateActor(float deltaTime) override;
1717
void ActorInput(const struct InputState& state) override;
1818
private:
19+
Vector2 mVelocityDir;
20+
Vector2 mRotationDir;
21+
float mSpeed;
1922
float mLaserCooldown;
2023
};

0 commit comments

Comments
 (0)