diff --git a/include/GameObject.h b/include/GameObject.h index b6d1caa..cb87614 100644 --- a/include/GameObject.h +++ b/include/GameObject.h @@ -1,18 +1,39 @@ #pragma once +#include +#include #include +#include "GameState.h" #include "Graphics.h" #include "components/GraphicsComponent.h" +#include "components/InputComponent.h" -class GameObject : std::enable_shared_from_this { +constexpr int HORIZONTAL_SPEED = 10; + +class GameObject { public: - GameObject(std::unique_ptr graphics) - : m_graphics(std::move(graphics)) {} + GameObject( + std::unique_ptr graphics, + std::unique_ptr input) + : m_graphics(std::move(graphics)) + , m_input(std::move(input)) + { /* Intentionally empty */ } void update(Graphics &graphics) { + if (m_input->moveUp) { + speed.x = HORIZONTAL_SPEED; + } m_graphics->update(graphics); } + GameState processInput(SDL_Event const* event) { + return m_input->update(event); + } + private: std::unique_ptr m_graphics; + std::unique_ptr m_input; + + SDL_Point speed; + }; diff --git a/include/GameState.h b/include/GameState.h new file mode 100644 index 0000000..d857c14 --- /dev/null +++ b/include/GameState.h @@ -0,0 +1,5 @@ +#pragma once +enum class GameState { + STOPPING=0, + RUNNING +}; diff --git a/include/Graphics.h b/include/Graphics.h index 004777f..47870a8 100644 --- a/include/Graphics.h +++ b/include/Graphics.h @@ -1,8 +1,32 @@ #pragma once +#include +#include +#include +#include +#include +#include + class Graphics { public: - Graphics(){} + Graphics(std::string_view title){ + // TODO Don't hardcode resolution + if (!SDL_CreateWindowAndRenderer(title.data(), 2560, 1440, SDL_WINDOW_FULLSCREEN, &window, &renderer)) { + throw std::runtime_error(std::format("Couldn't create window and renderer: {}", SDL_GetError())); + } + } + + void drawRect(SDL_FRect const& rect, SDL_Color const& color) { + SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a); + SDL_RenderFillRect(renderer, &rect); + } + + void show() { + SDL_RenderPresent(renderer); + } + private: + SDL_Renderer *renderer = nullptr; + SDL_Window *window = nullptr; }; diff --git a/include/components/GraphicsComponent.h b/include/components/GraphicsComponent.h index eb2cb9f..56707ff 100644 --- a/include/components/GraphicsComponent.h +++ b/include/components/GraphicsComponent.h @@ -2,12 +2,13 @@ #include "Graphics.h" +class GameObject; + class GraphicsComponent { public: virtual ~GraphicsComponent() {} virtual void update(Graphics &graphics) = 0; -private: }; diff --git a/include/components/InputComponent.h b/include/components/InputComponent.h new file mode 100644 index 0000000..3325b82 --- /dev/null +++ b/include/components/InputComponent.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include "GameState.h" + +struct InputComponent { + +public: + virtual ~InputComponent() {}; + virtual GameState update(SDL_Event const* event) = 0; + + bool moveUp; + bool moveDown; + bool moveLeft; + bool moveRight; +}; + diff --git a/include/components/PlayerGraphics.h b/include/components/PlayerGraphics.h index c44d4d4..c40c2c0 100644 --- a/include/components/PlayerGraphics.h +++ b/include/components/PlayerGraphics.h @@ -1,11 +1,31 @@ #pragma once +#include "GameObject.h" #include "Graphics.h" #include "GraphicsComponent.h" -#include +#include +#include +#include class PlayerGraphics : public GraphicsComponent { - void update(Graphics &graphics) { - std::print("Updating player graphics"); +public: + void setPos(int x, int y) { + hitbox.x = x; + hitbox.y = y; } + + void update(GameObject const& object, Graphics &graphics) { + SDL_Color color = { .r = 0, .g = 255, .b = 0, .a = 255}; + + graphics.drawRect(hitbox, color); + } + +private: + SDL_FRect hitbox = { + .x = 40, + .y = 40, + .w = 300, + .h = 300, + }; + }; diff --git a/include/components/PlayerInput.h b/include/components/PlayerInput.h new file mode 100644 index 0000000..59d683c --- /dev/null +++ b/include/components/PlayerInput.h @@ -0,0 +1,30 @@ +#include "components/InputComponent.h" +#include "GameState.h" +#include + +class PlayerInput : public InputComponent { + GameState update(SDL_Event const* event) { + if (SDL_EVENT_QUIT == event->type || SDLK_ESCAPE == event->key.key) { + return GameState::STOPPING; + } + // currently dont care about anything other than down + if (SDL_EVENT_KEY_DOWN != event->type) { + return GameState::RUNNING; + } + + if (SDLK_W == event->key.key) { + moveUp = event->key.type == SDL_EVENT_KEY_DOWN; + } + if (SDLK_S == event->key.key) { + moveDown = event->key.type == SDL_EVENT_KEY_DOWN; + } + if (SDLK_A == event->key.key) { + moveLeft = event->key.type == SDL_EVENT_KEY_DOWN; + } + if (SDLK_D == event->key.key) { + moveRight = event->key.type == SDL_EVENT_KEY_DOWN; + } + + return GameState::RUNNING; + } +}; diff --git a/src/main.cpp b/src/main.cpp index 47b1db7..8afc5f0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,6 +9,8 @@ including commercial applications, and to alter it and redistribute it freely. */ +#include "GameState.h" +#include #include #include #include @@ -20,66 +22,54 @@ #include #include "components/PlayerGraphics.h" +#include "components/PlayerInput.h" #include "Graphics.h" #include "GameObject.h" static SDL_Window *window = nullptr; static SDL_Renderer *renderer = nullptr; -GameObject player(std::make_unique()); -Graphics graphics; +GameObject player( + std::make_unique(), + std::make_unique() +); + +struct state { + Graphics graphics; + /* Physics physics */ +}; /* This function runs once at startup. */ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) { + static struct state state { + Graphics("My Game") + }; + *appstate = &state; + /* Create the window */ - if (!SDL_CreateWindowAndRenderer("Hello World", 800, 600, SDL_WINDOW_FULLSCREEN, &window, &renderer)) { - SDL_Log("Couldn't create window and renderer: %s", SDL_GetError()); - return SDL_APP_FAILURE; - } return SDL_APP_CONTINUE; } /* This function runs when a new event (mouse input, keypresses, etc) occurs. */ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { - if (event->type == SDL_EVENT_KEY_DOWN || - event->type == SDL_EVENT_QUIT) { - return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + + auto state = player.processInput(event); + if (GameState::STOPPING == state) { + return SDL_APP_SUCCESS; } + return SDL_APP_CONTINUE; } /* This function runs once per frame, and is the heart of the program. */ SDL_AppResult SDL_AppIterate(void *appstate) { - std::string message("Hello World!"); - int w = 0, h = 0; - float x, y; - const float scale = 4.0f; + auto game = static_cast(appstate); - /* Center the message and scale it up */ - SDL_GetRenderOutputSize(renderer, &w, &h); - SDL_SetRenderScale(renderer, scale, scale); - x = ((w / scale) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * message.length()) / 2; - y = ((h / scale) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) / 2; - - SDL_FRect rect { - .x = 30, - .y = 30, - .w = 100, - .h = 100 - }; - - - /* Draw the message */ - SDL_SetRenderDrawColor(renderer, 0, 0, 200, 255); - SDL_RenderClear(renderer); - SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); - SDL_RenderFillRect(renderer, &rect); - SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); - SDL_RenderDebugText(renderer, x, y, message.c_str()); - SDL_RenderPresent(renderer); + player.update(game->graphics); + game->graphics.show(); return SDL_APP_CONTINUE; }