Witch-Game/src/Game.cpp
2025-05-07 17:59:50 +02:00

156 lines
No EOL
5.3 KiB
C++

#include "Game.h"
#include <memory>
#include <limits>
#include <SDL3/SDL.h>
#include "Actors/ActorFactory.h"
#include "GameCommands/EndGameCommand.h"
#include "GameCommands/MoveUpCommand.h"
#include "GameCommands/MoveLeftCommand.h"
#include "GameCommands/MoveDownCommand.h"
#include "GameCommands/MoveRightCommand.h"
#include "GameCommands/MoveXCommand.h"
#include "GameCommands/MoveYCommand.h"
#include "DataStructures/Vector2D.h"
#include "DataStructures/Hitbox.h"
Game::Game(SDL_Window *window, SDL_Renderer *renderer)
: m_Window(window, SDL_DestroyWindow),
m_Renderer(renderer, SDL_DestroyRenderer),
m_Gamepad1(nullptr, SDL_CloseGamepad),
m_TickCount(0),
m_Player1DirectionInput({ 0,0 }),
m_Player2DirectionInput({ 0,0 })
{
SDL_FRect player1Hitbox;
player1Hitbox.x = 0;
player1Hitbox.y = 0;
player1Hitbox.w = 20;
player1Hitbox.h = 20;
m_Player1 = ActorFactory::CreateMovingActor(Vector2D(0,0), player1Hitbox, player1Hitbox);
//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_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));
}
void Game::Run()
{
float deltaTime = (SDL_GetTicks() - m_TickCount) / 1000.0f;
uint64_t ticks = SDL_GetTicks() - m_TickCount;
ticks = ticks > 0 ? ticks : 1;
long 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(), 255, 255, 255, 255);
SDL_RenderDebugTextFormat(m_Renderer.get(), 10, 440, "%" SDL_PRIu32 " fps", fps);
SDL_SetRenderDrawColor(m_Renderer.get(), 150, 0, 150, 255);
SDL_FRect player = m_Player1->GetMovementHitbox();
SDL_RenderFillRect(m_Renderer.get(), &player);
SDL_RenderPresent(m_Renderer.get());
}
void Game::HandleMovement()
{
NormalizedDirection direction;
if(m_Player1DirectionButtonStatus.GetDirection(direction))
{
m_Player1->SetDirection(direction);
return;
}
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)
{
if(!event.key.repeat)
{
auto commandIterator = m_KeyboardCommandMap.find(event.key.scancode);
if(commandIterator != m_KeyboardCommandMap.end())
{
if(event.key.down)
{
commandIterator->second->Down();
}
else
{
commandIterator->second->Up();
}
}
}
}
void Game::HandleGamepadButton(const SDL_Event &event)
{
auto commandIterator = m_Gamepad1ButtonCommandMap.find((SDL_GamepadButton)event.gbutton.button);
if(commandIterator != m_Gamepad1ButtonCommandMap.end())
{
if(event.gbutton.down)
{
commandIterator->second->Down();
}
else
{
commandIterator->second->Up();
}
}
}
void Game::HandleGamepadAxis(const SDL_Event &event)
{
auto commandIterator = m_Gamepad1AxisCommandMap.find((SDL_GamepadAxis)event.gaxis.axis);
if(commandIterator != m_Gamepad1AxisCommandMap.end())
{
float value = (float)event.gaxis.value / std::numeric_limits<int16_t>::max();
commandIterator->second->Execute(value);
}
}
void Game::AddGamepad(SDL_JoystickID id)
{
if(!m_Gamepad1)
{
m_Gamepad1.reset(SDL_OpenGamepad(id));
if (!m_Gamepad1) {
SDL_Log("Failed to open gamepad ID %u: %s", (unsigned int) id, SDL_GetError());
}
}
}
void Game::RemoveGamepad(SDL_JoystickID id)
{
if (m_Gamepad1 && (SDL_GetGamepadID(m_Gamepad1.get()) == id)) {
SDL_CloseGamepad(m_Gamepad1.get()); /* our joystick was unplugged. */
m_Gamepad1.release();
}
}
void Game::EndGame()
{
SDL_Event * event = new SDL_Event();
event->type = SDL_EVENT_QUIT;
SDL_PushEvent(event);
}