diff --git a/2dgk_7/2dgk_7/2dgk_7.vcxproj b/2dgk_7/2dgk_7/2dgk_7.vcxproj index 9c54956..42c98b0 100644 --- a/2dgk_7/2dgk_7/2dgk_7.vcxproj +++ b/2dgk_7/2dgk_7/2dgk_7.vcxproj @@ -29,26 +29,26 @@ Application true - v142 + v143 Unicode Application false - v142 + v143 true Unicode Application true - v142 + v143 Unicode Application false - v142 + v143 true Unicode diff --git a/2dgk_7/2dgk_7/KActionBind.h b/2dgk_7/2dgk_7/KActionBind.h index 0cf1f35..e3c1eab 100644 --- a/2dgk_7/2dgk_7/KActionBind.h +++ b/2dgk_7/2dgk_7/KActionBind.h @@ -2,18 +2,30 @@ #include "Controllers.h" #include "KPlayerController.h" -namespace KapitanGame {; +namespace KapitanGame { + ; enum class InputState : int { Pressed, Released, Hold }; struct KActionBind { + KActionBind(std::string name, const InputState expectedInputState, KPlayerController* controllerObject, const KPlayerCommand command, const Controllers controller) : + Name(std::move(name)), ExpectedInputState(expectedInputState), ControllerObject(controllerObject), Command(command), Controller(controller) {} std::string Name; InputState ExpectedInputState; KPlayerController* ControllerObject; KPlayerCommand Command; Controllers Controller; }; + struct KAxisBind + { + KAxisBind(std::string name, KPlayerController* controllerObject, const KPlayerAxisCommand command, const Controllers controller) : + Name(std::move(name)), ControllerObject(controllerObject), AxisCommand(command), Controller(controller) {} + std::string Name; + KPlayerController* ControllerObject; + KPlayerAxisCommand AxisCommand; + Controllers Controller; + }; } diff --git a/2dgk_7/2dgk_7/KInput.cpp b/2dgk_7/2dgk_7/KInput.cpp index 5c1bd78..a108905 100644 --- a/2dgk_7/2dgk_7/KInput.cpp +++ b/2dgk_7/2dgk_7/KInput.cpp @@ -4,8 +4,8 @@ #include namespace KapitanGame { - KInput::KInput() { - Initialized = false; + KInput::KInput() : GamePadsCount(0), Initialized(false) + { } void KInput::Init() { @@ -14,17 +14,17 @@ namespace KapitanGame { SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); const int nJoysticks = SDL_NumJoysticks(); - GamepadsCount = 0; + GamePadsCount = 0; // Count how many controllers there are for (int i = 0; i < nJoysticks; i++) if (SDL_IsGameController(i)) - GamepadsCount++; + GamePadsCount++; // If we have some controllers attached - if (GamepadsCount > 0) + if (GamePadsCount > 0) { - for (int i = 0; i < GamepadsCount; i++) + for (int i = 0; i < GamePadsCount; i++) { // Open the controller and add it to our list SDL_GameController* pad = SDL_GameControllerOpen(i); @@ -37,11 +37,11 @@ namespace KapitanGame { } // Vectors are empty to begin with, this sets their size - ControllerInputs.resize(GamepadsCount); - LastControllerInputs.resize(GamepadsCount); + ControllerInputs.resize(GamePadsCount); + LastControllerInputs.resize(GamePadsCount); // Set the status of the controllers to "nothing is happening" - for (int i = 0; i < GamepadsCount; i++) { + for (int i = 0; i < GamePadsCount; i++) { for (int a = 0; a < SDL_CONTROLLER_AXIS_MAX; a++) { ControllerInputs[i].Axis[a] = 0; LastControllerInputs[i].Axis[a] = 0; @@ -59,10 +59,11 @@ namespace KapitanGame { SDL_GameControllerClose(pad); } ConnectedControllers.clear(); + Actions.clear(); } void KInput::HandleInputPreEvents() { - for (int i = 0; i < GamepadsCount; i++) { + for (int i = 0; i < GamePadsCount; i++) { for (int a = 0; a < SDL_CONTROLLER_AXIS_MAX; a++) { LastControllerInputs[i].Axis[a] = ControllerInputs[i].Axis[a]; } @@ -89,7 +90,7 @@ namespace KapitanGame { // If a controller button is pressed case SDL_CONTROLLERBUTTONDOWN: // Cycle through the controllers - for (int i = 0; i < GamepadsCount; i++) { + for (int i = 0; i < GamePadsCount; i++) { // Looking for the button that was pressed if (event.cbutton.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(ConnectedControllers[i]))) { // So the relevant state can be updated @@ -100,7 +101,7 @@ namespace KapitanGame { // Do the same for releasing a button case SDL_CONTROLLERBUTTONUP: - for (int i = 0; i < GamepadsCount; i++) { + for (int i = 0; i < GamePadsCount; i++) { if (event.cbutton.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(ConnectedControllers[i]))) { ControllerInputs[i].Buttons[event.cbutton.button] = false; } @@ -109,7 +110,7 @@ namespace KapitanGame { // And something similar for axis motion case SDL_CONTROLLERAXISMOTION: - for (int i = 0; i < GamepadsCount; i++) { + for (int i = 0; i < GamePadsCount; i++) { if (event.cbutton.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(ConnectedControllers[i]))) { ControllerInputs[i].Axis[event.caxis.axis] = event.caxis.value; } @@ -118,62 +119,94 @@ namespace KapitanGame { } } - void KInput::BindAction(std::string name, InputState expectedInputState, KPlayerController* controller, - KPlayerCommand command) { - Actions.emplace_back(name, expectedInputState, controller, command); + void KInput::BindAction(const std::string& name, InputState expectedInputState, KPlayerController* controllerObject, + KPlayerCommand command, Controllers controller) { + Actions.emplace_back(name, expectedInputState, controllerObject, command, controller); + } + + void KInput::BindAxis(const std::string& name, KPlayerController* controllerObject, KPlayerAxisCommand command, Controllers controller) + { + Axes.emplace_back(name, controllerObject, command, controller); } bool KInput::CheckAction(const std::string& name, const InputState expectedInputState, Controllers controller) { - switch(expectedInputState) { - + const auto keyBind = KeyBinds[static_cast(controller)].find(name); + const auto buttonBind = ButtonBinds[static_cast(controller)].find(name); + switch (expectedInputState) { case InputState::Pressed: - const auto keyBind = KeyBinds.find(name); - if(keyBind!=KeyBinds.end()) { - if(IsKeyboardButtonPressed(keyBind->second)) { + if (keyBind != KeyBinds[static_cast(controller)].end()) { + if (IsKeyboardButtonPressed(keyBind->second)) { return true; } } - const auto buttonBind = ButtonBinds[controller].find(name); - if(buttonBind!=ButtonBinds[controller].end()) { - if(IsControllerButtonPressed(controller, buttonBind)) { + + if (buttonBind != ButtonBinds[static_cast(controller)].end()) { + if (IsControllerButtonPressed(controller, buttonBind->second)) { + return true; + } + } + return false; + case InputState::Released: + if (keyBind != KeyBinds[static_cast(controller)].end()) { + if (IsKeyboardButtonReleased(keyBind->second)) { + return true; + } + } + + if (buttonBind != ButtonBinds[static_cast(controller)].end()) { + if (IsControllerButtonReleased(controller, buttonBind->second)) { + return true; + } + } + return false; + case InputState::Hold: + if (keyBind != KeyBinds[static_cast(controller)].end()) { + if (IsKeyboardButtonHeld(keyBind->second)) { + return true; + } + } + + if (buttonBind != ButtonBinds[static_cast(controller)].end()) { + if (IsControllerButtonHeld(controller, buttonBind->second)) { return true; } } return false; - case InputState::Released: break; - case InputState::Hold: break; - default: return false; } + return false; } void KInput::ProcessActions() { - for(auto action : Actions) { - if(CheckAction(action.Name, action.ExpectedInputState, action.Controller)) { - //(action.ControllerObject->*action.Command)(); + for (auto &action : Actions) { + if (CheckAction(action.Name, action.ExpectedInputState, action.Controller)) { std::invoke(action.Command, action.ControllerObject); } } } - bool KInput::IsControllerButtonPressed(const Controllers controllerId, const SDL_GameControllerButton button) { - if (controllerId < Controllers::Controller1 || controllerId > static_cast(GamepadsCount - 1)) return false; + bool KInput::IsControllerButtonPressed(const Controllers controllerId, const SDL_GameControllerButton button) const + { + if (controllerId < Controllers::Controller1 || controllerId > static_cast(GamePadsCount - 1)) return false; return ControllerInputs[static_cast(controllerId)].Buttons[button] && !LastControllerInputs[static_cast(controllerId)].Buttons[button]; } - bool KInput::IsControllerButtonReleased(const Controllers controllerId, const SDL_GameControllerButton button) { - if (controllerId < Controllers::Controller1 || controllerId > static_cast(GamepadsCount - 1)) return false; + bool KInput::IsControllerButtonReleased(const Controllers controllerId, const SDL_GameControllerButton button) const + { + if (controllerId < Controllers::Controller1 || controllerId > static_cast(GamePadsCount - 1)) return false; return !ControllerInputs[static_cast(controllerId)].Buttons[button] && LastControllerInputs[static_cast(controllerId)].Buttons[button]; } - bool KInput::IsControllerButtonHeld(const Controllers controllerId, const SDL_GameControllerButton button) { - if (controllerId < Controllers::Controller1 || controllerId > static_cast(GamepadsCount - 1)) return false; + bool KInput::IsControllerButtonHeld(const Controllers controllerId, const SDL_GameControllerButton button) const + { + if (controllerId < Controllers::Controller1 || controllerId > static_cast(GamePadsCount - 1)) return false; return ControllerInputs[static_cast(controllerId)].Buttons[button] && LastControllerInputs[static_cast(controllerId)].Buttons[button]; } - float KInput::GetControllerAxis(const Controllers controllerId, const SDL_GameControllerAxis axis) { - if (controllerId static_cast(GamepadsCount - 1)) return 0.0; + float KInput::GetControllerAxis(const Controllers controllerId, const SDL_GameControllerAxis axis) const + { + if (controllerId static_cast(GamePadsCount - 1)) return 0.0; const int value = ControllerInputs[static_cast(controllerId)].Axis[axis]; if (std::abs(value) < Constants::JOYSTICK_DEAD_ZONE) return 0.0; @@ -181,19 +214,22 @@ namespace KapitanGame { return static_cast(value) / 32768.0f; } - bool KInput::IsKeyboardButtonPressed(const Uint8 scanCode) { + bool KInput::IsKeyboardButtonPressed(const Uint8 scanCode) const + { if (scanCode > KeyboardInputs.size() || scanCode > LastKeyboardInputs.size()) return false; return KeyboardInputs[scanCode] && KeyboardInputs[scanCode] != LastKeyboardInputs[scanCode]; } - bool KInput::IsKeyboardButtonReleased(const Uint8 scanCode) { + bool KInput::IsKeyboardButtonReleased(const Uint8 scanCode) const + { if (scanCode > KeyboardInputs.size() || scanCode > LastKeyboardInputs.size()) return false; return !KeyboardInputs[scanCode] && KeyboardInputs[scanCode] != LastKeyboardInputs[scanCode]; } - bool KInput::IsKeyboardButtonHeld(const Uint8 scanCode) { + bool KInput::IsKeyboardButtonHeld(const Uint8 scanCode) const + { if (scanCode > KeyboardInputs.size()) return false; return KeyboardInputs[scanCode]; diff --git a/2dgk_7/2dgk_7/KInput.h b/2dgk_7/2dgk_7/KInput.h index f580969..37abf8a 100644 --- a/2dgk_7/2dgk_7/KInput.h +++ b/2dgk_7/2dgk_7/KInput.h @@ -14,9 +14,19 @@ namespace KapitanGame { std::vector KeyboardInputs; std::vector LastKeyboardInputs; std::vector Actions; - std::unordered_map KeyBinds; - int GamepadsCount; + std::vector Axes; + std::unordered_map KeyBinds[static_cast(Controllers::Controller4) + 1]; + std::unordered_map ButtonBinds[static_cast(Controllers::Controller4) + 1]; + int GamePadsCount; bool Initialized; + + bool IsControllerButtonPressed(Controllers controllerId, SDL_GameControllerButton button) const; + bool IsControllerButtonReleased(Controllers controllerId, SDL_GameControllerButton button) const; + bool IsControllerButtonHeld(Controllers controllerId, SDL_GameControllerButton button) const; + float GetControllerAxis(Controllers controllerId, SDL_GameControllerAxis axis) const; + bool IsKeyboardButtonHeld(Uint8 scanCode) const; + bool IsKeyboardButtonPressed(Uint8 scanCode) const; + bool IsKeyboardButtonReleased(Uint8 scanCode) const; public: KInput(); void Init(); @@ -24,16 +34,11 @@ namespace KapitanGame { void HandleInputPreEvents(); void HandleInputPostEvents(); void HandleEvent(const SDL_Event& event); - void BindAction(std::string name, InputState expectedInputState, KPlayerController* controller, KPlayerCommand command); + void BindAction(const std::string& name, InputState expectedInputState, KPlayerController* controllerObject, KPlayerCommand command, Controllers + controller); + void BindAxis(const std::string& name, KPlayerController* controllerObject, KPlayerAxisCommand command, Controllers controller); bool CheckAction(const std::string& name, InputState expectedInputState, Controllers controller); void ProcessActions(); - bool IsControllerButtonPressed(Controllers controllerId, SDL_GameControllerButton button); - bool IsControllerButtonReleased(Controllers controllerId, SDL_GameControllerButton button); - bool IsControllerButtonHeld(Controllers controllerId, SDL_GameControllerButton button); - float GetControllerAxis(Controllers controllerId, SDL_GameControllerAxis axis); - bool IsKeyboardButtonHeld(Uint8 scanCode); - bool IsKeyboardButtonPressed(Uint8 scanCode); - bool IsKeyboardButtonReleased(Uint8 scanCode); }; } diff --git a/2dgk_7/2dgk_7/KPlayerController.cpp b/2dgk_7/2dgk_7/KPlayerController.cpp index 19567bb..30d918a 100644 --- a/2dgk_7/2dgk_7/KPlayerController.cpp +++ b/2dgk_7/2dgk_7/KPlayerController.cpp @@ -1,5 +1,27 @@ #include "KPlayerController.h" +#include "KInput.h" + namespace KapitanGame { - + void KPlayerController::SetupInputBindings(KInput& input) + { + input.BindAxis("MoveYAxis", this, &KPlayerController::MoveYAxis, Controller); + input.BindAxis("MoveXAxis", this, &KPlayerController::MoveXAxis, Controller); + } + + void KPlayerController::MoveYAxis(const float axis) + { + Input.Y += axis; + } + void KPlayerController::MoveXAxis(const float axis) + { + Input.X += axis; + } + + void KPlayerController::Update(float deltaTime) + { + Input.Normalize(); + Pawn->AddMovementInput(Input); + Input = KVector2D(0.f, 0.f); + } } diff --git a/2dgk_7/2dgk_7/KPlayerController.h b/2dgk_7/2dgk_7/KPlayerController.h index aa66873..632ef1a 100644 --- a/2dgk_7/2dgk_7/KPlayerController.h +++ b/2dgk_7/2dgk_7/KPlayerController.h @@ -1,15 +1,29 @@ #pragma once +#include "Controllers.h" #include "KShape.h" #include "KVector2d.h" namespace KapitanGame { + class KInput; + class KPlayerController { + public: + explicit KPlayerController(const Controllers controller) : Input(0.f, 0.f), Controller(controller) + { + } + + void SetupInputBindings(KInput& input); + void MoveYAxis(float axis); + void MoveXAxis(float axis); + void Update(float deltaTime); private: KVector2D Input; - KShape Shape; + Controllers Controller; + KPawn Pawn; }; typedef void (KPlayerController::* KPlayerCommand)(); + typedef void (KPlayerController::* KPlayerAxisCommand)(float input); } diff --git a/2dgk_7/2dgk_7/KVector2d.h b/2dgk_7/2dgk_7/KVector2d.h index 5ff7cfe..933ea00 100644 --- a/2dgk_7/2dgk_7/KVector2d.h +++ b/2dgk_7/2dgk_7/KVector2d.h @@ -63,7 +63,7 @@ namespace KapitanGame { void Normalize() { const float l = Length(); - if (l > 0) { + if (l > 1.f) { (*this) *= 1 / l; } }