Zadanie 2 WIP3

This commit is contained in:
Michał Leśniak 2021-12-07 06:33:08 +01:00
parent 5b30c6ca45
commit 93afaeb4b3
7 changed files with 148 additions and 59 deletions

View File

@ -29,26 +29,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@ -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;
};
}

View File

@ -4,8 +4,8 @@
#include <SDL.h>
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<int>(controller)].find(name);
const auto buttonBind = ButtonBinds[static_cast<int>(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<int>(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<int>(controller)].end()) {
if (IsControllerButtonPressed(controller, buttonBind->second)) {
return true;
}
}
return false;
case InputState::Released:
if (keyBind != KeyBinds[static_cast<int>(controller)].end()) {
if (IsKeyboardButtonReleased(keyBind->second)) {
return true;
}
}
if (buttonBind != ButtonBinds[static_cast<int>(controller)].end()) {
if (IsControllerButtonReleased(controller, buttonBind->second)) {
return true;
}
}
return false;
case InputState::Hold:
if (keyBind != KeyBinds[static_cast<int>(controller)].end()) {
if (IsKeyboardButtonHeld(keyBind->second)) {
return true;
}
}
if (buttonBind != ButtonBinds[static_cast<int>(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<Controllers>(GamepadsCount - 1)) return false;
bool KInput::IsControllerButtonPressed(const Controllers controllerId, const SDL_GameControllerButton button) const
{
if (controllerId < Controllers::Controller1 || controllerId > static_cast<Controllers>(GamePadsCount - 1)) return false;
return ControllerInputs[static_cast<int>(controllerId)].Buttons[button] && !LastControllerInputs[static_cast<int>(controllerId)].Buttons[button];
}
bool KInput::IsControllerButtonReleased(const Controllers controllerId, const SDL_GameControllerButton button) {
if (controllerId < Controllers::Controller1 || controllerId > static_cast<Controllers>(GamepadsCount - 1)) return false;
bool KInput::IsControllerButtonReleased(const Controllers controllerId, const SDL_GameControllerButton button) const
{
if (controllerId < Controllers::Controller1 || controllerId > static_cast<Controllers>(GamePadsCount - 1)) return false;
return !ControllerInputs[static_cast<int>(controllerId)].Buttons[button] && LastControllerInputs[static_cast<int>(controllerId)].Buttons[button];
}
bool KInput::IsControllerButtonHeld(const Controllers controllerId, const SDL_GameControllerButton button) {
if (controllerId < Controllers::Controller1 || controllerId > static_cast<Controllers>(GamepadsCount - 1)) return false;
bool KInput::IsControllerButtonHeld(const Controllers controllerId, const SDL_GameControllerButton button) const
{
if (controllerId < Controllers::Controller1 || controllerId > static_cast<Controllers>(GamePadsCount - 1)) return false;
return ControllerInputs[static_cast<int>(controllerId)].Buttons[button] && LastControllerInputs[static_cast<int>(controllerId)].Buttons[button];
}
float KInput::GetControllerAxis(const Controllers controllerId, const SDL_GameControllerAxis axis) {
if (controllerId <Controllers::Controller1 || controllerId > static_cast<Controllers>(GamepadsCount - 1)) return 0.0;
float KInput::GetControllerAxis(const Controllers controllerId, const SDL_GameControllerAxis axis) const
{
if (controllerId <Controllers::Controller1 || controllerId > static_cast<Controllers>(GamePadsCount - 1)) return 0.0;
const int value = ControllerInputs[static_cast<int>(controllerId)].Axis[axis];
if (std::abs(value) < Constants::JOYSTICK_DEAD_ZONE) return 0.0;
@ -181,19 +214,22 @@ namespace KapitanGame {
return static_cast<float>(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];

View File

@ -14,9 +14,19 @@ namespace KapitanGame {
std::vector<Uint8> KeyboardInputs;
std::vector<Uint8> LastKeyboardInputs;
std::vector<KActionBind> Actions;
std::unordered_map<std::string, Uint8> KeyBinds;
int GamepadsCount;
std::vector<KAxisBind> Axes;
std::unordered_map<std::string, Uint8> KeyBinds[static_cast<int>(Controllers::Controller4) + 1];
std::unordered_map<std::string, SDL_GameControllerButton> ButtonBinds[static_cast<int>(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);
};
}

View File

@ -1,5 +1,27 @@
#include "KPlayerController.h"
namespace KapitanGame {
#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);
}
}

View File

@ -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);
}

View File

@ -63,7 +63,7 @@ namespace KapitanGame {
void Normalize() {
const float l = Length();
if (l > 0) {
if (l > 1.f) {
(*this) *= 1 / l;
}
}