Started project, implemented keyboard and controller movement

This commit is contained in:
Sarah Faey 2025-04-17 22:53:25 +02:00
parent b1f5d882f0
commit d8fa53801b
33 changed files with 931 additions and 73 deletions

View file

@ -1,22 +1,153 @@
// SPDX-FileCopyrightText: 2025 <copyright holder> <email>
// SPDX-License-Identifier: MIT
#include "Game.h"
#include <SDL3/SDL_assert.h>
#include <SDL3/SDL_log.h>
#include <iostream>
#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"
Game::Game()
Game::Game(SDL_Window *window, SDL_Renderer *renderer)
: m_Window(window, SDL_DestroyWindow),
m_Renderer(renderer, SDL_DestroyRenderer),
m_Gamepad1(nullptr, SDL_CloseGamepad)
{
SDL_assert(1< 0);
SDL_FRect player1Hitbox;
player1Hitbox.x = 0;
player1Hitbox.y = 0;
player1Hitbox.w = 20;
player1Hitbox.h = 20;
m_Player1 = ActorFactory::CreateMovingActor(player1Hitbox);
int i = 7;
i++;
//std::cout << i << std::endl;
}
Game::~Game()
{
//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_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;
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_FRect player = m_Player1->GetHitbox();
SDL_RenderFillRect(m_Renderer.get(), &player);
SDL_RenderPresent(m_Renderer.get());
}
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))
{
float x = m_Player1DirectionInput.x* c_NormalizedDiagonal;
float y = m_Player1DirectionInput.y * c_NormalizedDiagonal;
NormalizedDirection player1InputDirection(x, y, true);
m_Player1->SetDirection(player1InputDirection);
}
else if(abs(m_Player1DirectionInput.x) < c_GamepadAxisDeadzone && abs(m_Player1DirectionInput.y) < c_GamepadAxisDeadzone)
{
m_Player1->SetDirection(NormalizedDirection());
}
else
{
NormalizedDirection player1InputDirection(m_Player1DirectionInput.x, m_Player1DirectionInput.y, true);
m_Player1->SetDirection(player1InputDirection);
}
}
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();
if(!m_ButtonInput || abs(value) > c_GamepadAxisDeadzone)
{
commandIterator->second->Execute(value);
m_ButtonInput = false;
}
}
}
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);
}