fixed input with keyboard and controller at the same time

This commit is contained in:
Sarah Faey 2025-04-18 15:47:07 +02:00
parent d8fa53801b
commit eabeb55115
11 changed files with 95 additions and 68 deletions

2
.gitignore vendored
View file

@ -465,3 +465,5 @@ FodyWeavers.xsd
# Built Visual Studio Code Extensions
*.vsix
.kateproject.build
.vscode/settings.json

View file

@ -38,7 +38,7 @@ FetchContent_MakeAvailable(SDL3 SDL3_image SDL3_ttf)
set(ACTORS src/Actors/Actor.cpp src/Actors/MovingActor.cpp src/Actors/ActorFactory.cpp)
#set(COMMANDS src/GameCommands/GameCommand.h src/GameCommands/GameCommand.h src/GameCommands/MoveUpCommand.h src/GameCommands/EndGameCommand.h )
set(COMPONENTS src/Components/MoveComponent.cpp )
set(DATA_STRUCTURES src/DataStructures/NormalizedDirection.cpp)
set(DATA_STRUCTURES src/DataStructures/NormalizedDirection.cpp src/DataStructures/DirectionButtonStatus.cpp)
add_executable(Witch-Game main.cpp src/Game.cpp ${ACTORS} ${COMPONENTS} ${DATA_STRUCTURES})
target_compile_features(Witch-Game PRIVATE cxx_std_17)

View file

@ -72,6 +72,6 @@ SDL_AppResult SDL_AppIterate(void *appstate)
/* This function runs once at shutdown. */
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
delete appstate;
delete (Game*)appstate;
/* SDL will clean up the window/renderer for us. */
}

View file

@ -0,0 +1,24 @@
#include "DirectionButtonStatus.h"
#include <SDL3/SDL.h>
#include "NormalizedDirection.h"
bool DirectionButtonStatus::GetDirection(NormalizedDirection & ref_direction)
{
SDL_Point direction = {0,0};
if(UpPressed) direction.y -= 1;
if(DownPressed) direction.y += 1;
if(LeftPressed) direction.x -= 1;
if(RightPressed) direction.x += 1;
float x = direction.x;
float y = direction.y;
if((direction.y == 1 || direction.y == -1)
&& (direction.x == 1 || direction.x == -1))
{
x *= c_NormalizedDiagonal;
y *= c_NormalizedDiagonal;
}
ref_direction = NormalizedDirection(x,y,true);
return UpPressed || DownPressed || LeftPressed || RightPressed;
}

View file

@ -0,0 +1,20 @@
#ifndef DIRECTION_BUTTON_STATUS_H
#define DIRECTION_BUTTON_STATUS_H
#include <math.h>
#include <SDL3/SDL.h>
#include "NormalizedDirection.h"
class DirectionButtonStatus
{
public:
bool UpPressed = false;
bool DownPressed = false;
bool LeftPressed = false;
bool RightPressed = false;
const float c_NormalizedDiagonal = 1 / sqrt(2);
bool GetDirection(NormalizedDirection & ref_direction);
};
#endif

View file

@ -25,14 +25,14 @@ Game::Game(SDL_Window *window, SDL_Renderer *renderer)
//TODO: read keybinds from config if it exists. otherwise initialze standard and write file
m_KeyboardCommandMap.emplace(SDL_SCANCODE_ESCAPE, new EndGameCommand(this));
m_KeyboardCommandMap.emplace(SDL_SCANCODE_W, new MoveUpCommand(m_Player1DirectionInput, m_ButtonInput));
m_KeyboardCommandMap.emplace(SDL_SCANCODE_A, new MoveLeftCommand(m_Player1DirectionInput, m_ButtonInput));
m_KeyboardCommandMap.emplace(SDL_SCANCODE_S, new MoveDownCommand(m_Player1DirectionInput, m_ButtonInput));
m_KeyboardCommandMap.emplace(SDL_SCANCODE_D, new MoveRightCommand(m_Player1DirectionInput, m_ButtonInput));
m_Gamepad1ButtonCommandMap.emplace(SDL_GAMEPAD_BUTTON_DPAD_UP, new MoveUpCommand(m_Player1DirectionInput, m_ButtonInput));
m_Gamepad1ButtonCommandMap.emplace(SDL_GAMEPAD_BUTTON_DPAD_LEFT, new MoveLeftCommand(m_Player1DirectionInput, m_ButtonInput));
m_Gamepad1ButtonCommandMap.emplace(SDL_GAMEPAD_BUTTON_DPAD_DOWN, new MoveDownCommand(m_Player1DirectionInput, m_ButtonInput));
m_Gamepad1ButtonCommandMap.emplace(SDL_GAMEPAD_BUTTON_DPAD_RIGHT, new MoveRightCommand(m_Player1DirectionInput, m_ButtonInput));
m_KeyboardCommandMap.emplace(SDL_SCANCODE_W, new MoveUpCommand(m_Player1DirectionButtonStatus));
m_KeyboardCommandMap.emplace(SDL_SCANCODE_A, new MoveLeftCommand(m_Player1DirectionButtonStatus));
m_KeyboardCommandMap.emplace(SDL_SCANCODE_S, new MoveDownCommand(m_Player1DirectionButtonStatus));
m_KeyboardCommandMap.emplace(SDL_SCANCODE_D, new MoveRightCommand(m_Player1DirectionButtonStatus));
m_Gamepad1ButtonCommandMap.emplace(SDL_GAMEPAD_BUTTON_DPAD_UP, new MoveUpCommand(m_Player1DirectionButtonStatus));
m_Gamepad1ButtonCommandMap.emplace(SDL_GAMEPAD_BUTTON_DPAD_LEFT, new MoveLeftCommand(m_Player1DirectionButtonStatus));
m_Gamepad1ButtonCommandMap.emplace(SDL_GAMEPAD_BUTTON_DPAD_DOWN, new MoveDownCommand(m_Player1DirectionButtonStatus));
m_Gamepad1ButtonCommandMap.emplace(SDL_GAMEPAD_BUTTON_DPAD_RIGHT, new MoveRightCommand(m_Player1DirectionButtonStatus));
m_Gamepad1AxisCommandMap.emplace(SDL_GAMEPAD_AXIS_LEFTX, new MoveXCommand(m_Player1DirectionInput));
m_Gamepad1AxisCommandMap.emplace(SDL_GAMEPAD_AXIS_LEFTY, new MoveYCommand(m_Player1DirectionInput));
@ -41,14 +41,20 @@ Game::Game(SDL_Window *window, SDL_Renderer *renderer)
void Game::Run()
{
float deltaTime = (SDL_GetTicks() - m_TickCount) / 1000.0f;
uint64_t ticks = SDL_GetTicks() - m_TickCount;
ticks = ticks > 0 ? ticks : 1;
int fps = 1000/(ticks);
m_TickCount = SDL_GetTicks();
HandleMovement();
m_Player1->Update(deltaTime);
SDL_SetRenderDrawColor(m_Renderer.get(), 0, 0, 0, 255);
SDL_RenderClear(m_Renderer.get());
SDL_SetRenderDrawColor(m_Renderer.get(), 90, 90, 90, 255);
SDL_SetRenderDrawColor(m_Renderer.get(), 255, 255, 255, 255);
SDL_RenderDebugTextFormat(m_Renderer.get(), 10, 440, "%" SDL_PRIu64 " fps", fps);
SDL_SetRenderDrawColor(m_Renderer.get(), 150, 0, 150, 255);
SDL_FRect player = m_Player1->GetHitbox();
SDL_RenderFillRect(m_Renderer.get(), &player);
SDL_RenderPresent(m_Renderer.get());
@ -57,24 +63,19 @@ void Game::Run()
void Game::HandleMovement()
{
//if both direction buttons are pressed, normalize the direction vector
if((m_Player1DirectionInput.y == 1 || m_Player1DirectionInput.y == -1)
&& (m_Player1DirectionInput.x == 1 || m_Player1DirectionInput.x == -1))
NormalizedDirection direction;
if(m_Player1DirectionButtonStatus.GetDirection(direction))
{
float x = m_Player1DirectionInput.x* c_NormalizedDiagonal;
float y = m_Player1DirectionInput.y * c_NormalizedDiagonal;
NormalizedDirection player1InputDirection(x, y, true);
m_Player1->SetDirection(player1InputDirection);
m_Player1->SetDirection(direction);
return;
}
else if(abs(m_Player1DirectionInput.x) < c_GamepadAxisDeadzone && abs(m_Player1DirectionInput.y) < c_GamepadAxisDeadzone)
{
m_Player1->SetDirection(NormalizedDirection());
}
else
else if(abs(m_Player1DirectionInput.x) > c_GamepadAxisDeadzone || abs(m_Player1DirectionInput.y) > c_GamepadAxisDeadzone)
{
NormalizedDirection player1InputDirection(m_Player1DirectionInput.x, m_Player1DirectionInput.y, true);
m_Player1->SetDirection(player1InputDirection);
return;
}
m_Player1->SetDirection(direction);
}
void Game::HandleKeyboardInput(const SDL_Event &event)
@ -118,11 +119,7 @@ void Game::HandleGamepadAxis(const SDL_Event &event)
if(commandIterator != m_Gamepad1AxisCommandMap.end())
{
float value = (float)event.gaxis.value / std::numeric_limits<int16_t>::max();
if(!m_ButtonInput || abs(value) > c_GamepadAxisDeadzone)
{
commandIterator->second->Execute(value);
m_ButtonInput = false;
}
commandIterator->second->Execute(value);
}
}

View file

@ -7,6 +7,7 @@
#include "GameCommands/GameCommand.h"
#include "GameCommands/AxisCommand.h"
#include "Actors/MovingActor.h"
#include "DataStructures/DirectionButtonStatus.h"
class Game
{
@ -25,7 +26,6 @@ private:
const float c_GamepadAxisDeadzone = 0.2; //TODO: make this a setting?
bool m_running = true;
bool m_ButtonInput = true;
uint64_t m_TickCount;
std::map<SDL_Scancode, GameCommand*> m_KeyboardCommandMap;
std::map<SDL_GamepadButton, GameCommand*> m_Gamepad1ButtonCommandMap;
@ -37,7 +37,8 @@ private:
std::shared_ptr<MovingActor> m_Player2;
SDL_FPoint m_Player1DirectionInput;
SDL_FPoint m_Player2DirectionInput;
const float c_NormalizedDiagonal = 1 / sqrt(2);
DirectionButtonStatus m_Player1DirectionButtonStatus;
DirectionButtonStatus m_Player2DirectionButtonStatus;
std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> m_Window;
std::unique_ptr<SDL_Renderer, decltype(&SDL_DestroyRenderer)> m_Renderer;

View file

@ -2,18 +2,16 @@
#define MOVE_DOWN_COMMAND_H
#include "GameCommand.h"
#include <SDL3/SDL.h>
#include "../DataStructures/DirectionButtonStatus.h"
class MoveDownCommand : public GameCommand
{
public:
MoveDownCommand(SDL_FPoint & directionInput, bool & buttonInput) : m_directionInput(&directionInput), m_buttonInput(&buttonInput) {};
~MoveDownCommand() {};
void Down() override { m_directionInput->y += 1; *m_buttonInput = true;}
void Up() override { m_directionInput->y -= 1; *m_buttonInput = true;}
MoveDownCommand(DirectionButtonStatus & buttonStatus) : m_ButtonStatus(&buttonStatus) {};
void Down() override { m_ButtonStatus->DownPressed = true;}
void Up() override { m_ButtonStatus->DownPressed = false;;}
private:
SDL_FPoint * m_directionInput;
bool * m_buttonInput;
DirectionButtonStatus * m_ButtonStatus;
};
#endif

View file

@ -2,21 +2,16 @@
#define MOVE_LEFT_COMMAND_H
#include "GameCommand.h"
#include <iostream>
#include <memory>
#include <SDL3/SDL.h>
#include "../Components/MoveComponent.h"
#include "../DataStructures/DirectionButtonStatus.h"
class MoveLeftCommand : public GameCommand
{
public:
MoveLeftCommand(SDL_FPoint & directionInput, bool & buttonInput) : m_directionInput(&directionInput), m_buttonInput(&buttonInput) {};
~MoveLeftCommand() {};
void Down() override { m_directionInput->x -= 1; *m_buttonInput = true;}
void Up() override { m_directionInput->x += 1; *m_buttonInput = true;}
MoveLeftCommand(DirectionButtonStatus & buttonStatus) : m_ButtonStatus(&buttonStatus) {};
void Down() override { m_ButtonStatus->LeftPressed = true;}
void Up() override { m_ButtonStatus->LeftPressed = false;;}
private:
SDL_FPoint * m_directionInput;
bool * m_buttonInput;
DirectionButtonStatus * m_ButtonStatus;
};
#endif

View file

@ -2,21 +2,16 @@
#define MOVE_RIGHT_COMMAND_H
#include "GameCommand.h"
#include <iostream>
#include <memory>
#include <SDL3/SDL.h>
#include "../Components/MoveComponent.h"
#include "../DataStructures/DirectionButtonStatus.h"
class MoveRightCommand : public GameCommand
{
public:
MoveRightCommand(SDL_FPoint & directionInput, bool & buttonInput) : m_directionInput(&directionInput), m_buttonInput(&buttonInput) {};
~MoveRightCommand() {};
void Down() override { m_directionInput->x += 1; *m_buttonInput = true;}
void Up() override { m_directionInput->x -= 1; *m_buttonInput = true;}
MoveRightCommand(DirectionButtonStatus & buttonStatus) : m_ButtonStatus(&buttonStatus) {};
void Down() override { m_ButtonStatus->RightPressed = true;}
void Up() override { m_ButtonStatus->RightPressed = false;;}
private:
SDL_FPoint * m_directionInput;
bool * m_buttonInput;
DirectionButtonStatus * m_ButtonStatus;
};
#endif

View file

@ -2,21 +2,16 @@
#define MOVE_UP_COMMAND_H
#include "GameCommand.h"
#include <iostream>
#include <memory>
#include <SDL3/SDL.h>
#include "../Components/MoveComponent.h"
#include "../DataStructures/DirectionButtonStatus.h"
class MoveUpCommand : public GameCommand
{
public:
MoveUpCommand(SDL_FPoint & directionInput, bool & buttonInput) : m_directionInput(&directionInput), m_buttonInput(&buttonInput) {};
~MoveUpCommand() {};
void Down() override { m_directionInput->y -= 1; *m_buttonInput = true;}
void Up() override { m_directionInput->y += 1; *m_buttonInput = true;}
MoveUpCommand(DirectionButtonStatus & buttonStatus) : m_ButtonStatus(&buttonStatus) {};
void Down() override { m_ButtonStatus->UpPressed = true;}
void Up() override { m_ButtonStatus->UpPressed = false;;}
private:
SDL_FPoint * m_directionInput;
bool * m_buttonInput;
DirectionButtonStatus * m_ButtonStatus;
};
#endif