diff --git a/lib/Game.cpp b/lib/Game.cpp index b6ceca1..806f1e7 100644 --- a/lib/Game.cpp +++ b/lib/Game.cpp @@ -2,10 +2,8 @@ #include -Game::Game() : - window(448, 496), - board(), - pacMan(board), +Game::Game() + : pacMan(board), pellets(board), superPellets(board) {} diff --git a/lib/GameWindow.cpp b/lib/GameWindow.cpp index b19200e..9209d32 100644 --- a/lib/GameWindow.cpp +++ b/lib/GameWindow.cpp @@ -8,10 +8,13 @@ #include "Pellets.hpp" #include "SuperPellets.hpp" -GameWindow::GameWindow(int width, int height) { +GameWindow::GameWindow() { initSDL(); initSDLImage(); - auto sdl_window = createWindow(width * SCALE_FACTOR, height * SCALE_FACTOR); + + const auto window_dimension = windowDimensions(); + + auto sdl_window = createWindow(window_dimension.w, window_dimension.h); auto sdl_renderer = createRenderer(sdl_window); createWindowSurface(sdl_window); setDrawColor(sdl_renderer); @@ -31,47 +34,54 @@ void GameWindow::update(const PacMan & pacMan, const Pellets & pellets, const Su } void GameWindow::renderMaze() const { - renderTexture(maze_texture.get(), nullptr, nullptr); + SDL_Rect maze_rect = { 0, 0, MAZE_WIDTH, MAZE_HEIGHT }; + SDL_Rect maze_translated = { LEFT_MARGIN, TOP_MARGIN, MAZE_WIDTH, MAZE_HEIGHT }; + renderTexture(maze_texture.get(), maze_rect, maze_translated); } void GameWindow::renderSuperPellets(const SuperPellets & superPellets) const { - SDL_Rect sprite_rect = superPellets.currentSprite(); + SDL_Rect sprite_rect = textureGeometry(superPellets.currentSprite()); std::vector superPelletPositions = superPellets.currentPositions(); for (const auto & pos : superPelletPositions) { - SDL_Rect maze_rect = targetRect({float(pos.x), float(pos.y)}, 8 * SCALE_FACTOR); - renderTexture(sprite_texture.get(), &sprite_rect, &maze_rect); + renderTexture(sprite_texture.get(), sprite_rect, pos); } } void GameWindow::renderPellets(const Pellets & pellets) const { - SDL_Rect sprite_rect = pellets.currentSprite(); + SDL_Rect sprite_rect = textureGeometry(pellets.currentSprite()); std::vector pelletPositions = pellets.currentPositions(); for (const auto & pos : pelletPositions) { - SDL_Rect maze_rect = targetRect({float(pos.x), float(pos.y)}, 8 * SCALE_FACTOR); - renderTexture(sprite_texture.get(), &sprite_rect, &maze_rect); + renderTexture(sprite_texture.get(), sprite_rect, pos); } } void GameWindow::renderPacMan(const PacMan & pac_man) const { - Position maze_position = pac_man.position(); - SDL_Rect maze_rect = targetRect(maze_position, 8 * SCALE_FACTOR); - SDL_Rect sprite_rect = pac_man.currentSprite(); - renderTexture(sprite_texture.get(), &sprite_rect, &maze_rect); + SDL_Rect sprite_rect = textureGeometry(pac_man.currentSprite()); + Position pacman_pos = pac_man.position(); + renderTexture(sprite_texture.get(), sprite_rect, SDL_Point{ int(pacman_pos.x), int(pacman_pos.y) }); } -SDL_Rect GameWindow::targetRect(const Position & position, int pixel_increase) { - int pixels = 16 * SCALE_FACTOR; - int displacement = pixel_increase / 2; - return { - int(pixels * position.x) - displacement, - int(pixels * position.y) - displacement, - (pixels + pixel_increase), - (pixels + pixel_increase) +SDL_Rect GameWindow::textureGeometry(SDL_Point p) const { + return { p.x * 32, p.y * 32, 32, 32 }; +} + +SDL_Rect GameWindow::windowDimensions() const { + return { 0, 0, LEFT_MARGIN + MAZE_WIDTH + SCORE_WIDTH, TOP_MARGIN + MAZE_HEIGHT + BOTTOM_MARGIN }; +} + +void GameWindow::renderTexture(SDL_Texture * texture, const SDL_Rect & src, SDL_Point p) const { + SDL_Rect target = { + LEFT_MARGIN + int((p.x * DEFAULT_TEXTURE_WIDTH - src.w / 2) * TEXTURE_SCALE_FACTOR), + TOP_MARGIN + int((p.y * DEFAULT_TEXTURE_WIDTH - src.h / 2) * TEXTURE_SCALE_FACTOR), + src.w, + src.h }; + renderTexture(texture, src, target); } -void GameWindow::renderTexture(SDL_Texture * texture, SDL_Rect * texture_rect, SDL_Rect * target_rect) const { - if (SDL_RenderCopy(renderer.get(), texture, texture_rect, target_rect) < 0) +void GameWindow::renderTexture(SDL_Texture * texture, const SDL_Rect & src, const SDL_Rect & target) const { + + if (SDL_RenderCopy(renderer.get(), texture, &src, &target) < 0) exitFailure("Failed to copy texture to renderer"); } @@ -88,12 +98,12 @@ void GameWindow::initSDLImage() { SDL_Window * GameWindow::createWindow(int width, int height) { window = std::unique_ptr(SDL_CreateWindow( - "Pacman", - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - width, - height, - SDL_WINDOW_OPENGL)); + "Pacman", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + width, + height, + SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI)); if (!window) exitFailure("Failed to create window"); diff --git a/lib/GameWindow.hpp b/lib/GameWindow.hpp index 81b4cb1..57e12c0 100644 --- a/lib/GameWindow.hpp +++ b/lib/GameWindow.hpp @@ -28,19 +28,34 @@ struct SDL_Texture_Deleter { } }; +struct TextureSize { + int width; + int height; +}; + class PacMan; class Pellets; -class Position; +//class Position; class SuperPellets; class GameWindow { public: - explicit GameWindow(int width, int height); + explicit GameWindow(); void update(const PacMan & pacMan, const Pellets & pellets, const SuperPellets & superPellets); private: - static const int16_t SCALE_FACTOR = 1; + static constexpr int16_t SCALE_FACTOR = 1; + static constexpr int16_t LEFT_MARGIN = 40; + static constexpr int16_t TOP_MARGIN = 40; + static constexpr int16_t BOTTOM_MARGIN = 40; + static constexpr int16_t MAZE_WIDTH = 448; + static constexpr int16_t MAZE_HEIGHT = 496; + static constexpr int16_t SCORE_WIDTH = 200; + static constexpr int16_t DEFAULT_TEXTURE_WIDTH = 32; + static constexpr int16_t DEFAULT_TEXTURE_HEIGHT = 32; + static constexpr float TEXTURE_SCALE_FACTOR = 0.5; + std::unique_ptr window; std::unique_ptr renderer; std::unique_ptr window_surface; @@ -74,7 +89,15 @@ private: void renderSuperPellets(const SuperPellets & superPellets) const; - static SDL_Rect targetRect(const Position & position, int pixel_increase); + //static SDL_Rect targetRect(const Position & position, int pixel_increase); - void renderTexture(SDL_Texture * texture, SDL_Rect * texture_rect, SDL_Rect * target_rect) const; + SDL_Rect windowDimensions() const; + + // Given an x - y coordinate of a texture in the assets file, + // returns a rectangle for the whole texture. + // Assumes texture are laid out in a 32x32 grid + SDL_Rect textureGeometry(SDL_Point) const; + + void renderTexture(SDL_Texture * texture, const SDL_Rect & src, SDL_Point) const; + void renderTexture(SDL_Texture * texture, const SDL_Rect & src, const SDL_Rect & target) const; }; diff --git a/lib/PacMan.cpp b/lib/PacMan.cpp index 1967426..1234703 100644 --- a/lib/PacMan.cpp +++ b/lib/PacMan.cpp @@ -3,7 +3,7 @@ PacMan::PacMan(const Board & board) : pos(board.initialPacManPosition()) {} -SDL_Rect PacMan::currentSprite() const { +SDL_Point PacMan::currentSprite() const { return pacManAnimation.animationFrame(direction); } diff --git a/lib/PacMan.hpp b/lib/PacMan.hpp index 2f30703..fe1ff90 100644 --- a/lib/PacMan.hpp +++ b/lib/PacMan.hpp @@ -14,7 +14,7 @@ class PacMan { public: explicit PacMan(const Board & board); - [[nodiscard]] SDL_Rect currentSprite() const; + [[nodiscard]] SDL_Point currentSprite() const; [[nodiscard]] Position position() const; diff --git a/lib/PacManAnimation.cpp b/lib/PacManAnimation.cpp index 8365bbc..a0375c1 100644 --- a/lib/PacManAnimation.cpp +++ b/lib/PacManAnimation.cpp @@ -1,6 +1,6 @@ #include "PacManAnimation.hpp" -SDL_Rect PacManAnimation::animationFrame(Direction direction) const { +SDL_Point PacManAnimation::animationFrame(Direction direction) const { switch (direction) { case Direction::NONE: return closed; diff --git a/lib/PacManAnimation.hpp b/lib/PacManAnimation.hpp index f75da46..5af50df 100644 --- a/lib/PacManAnimation.hpp +++ b/lib/PacManAnimation.hpp @@ -10,25 +10,24 @@ class PacManAnimation { public: - - [[nodiscard]] SDL_Rect animationFrame(Direction direction) const; + [[nodiscard]] SDL_Point animationFrame(Direction direction) const; void updateAnimationPosition(std::chrono::milliseconds time_delta); private: uint8_t animation_position = 0; float animation_position_delta = 0.0; - const SDL_Rect right_wide = {0 * 32, 0 * 32, 32, 32}; - const SDL_Rect right_narrow = {1 * 32, 0 * 32, 32, 32}; - const SDL_Rect closed = {2 * 32, 0 * 32, 32, 32}; - const SDL_Rect left_narrow = {3 * 32, 0 * 32, 32, 32}; - const SDL_Rect left_wide = {4 * 32, 0 * 32, 32, 32}; - const SDL_Rect up_wide = {5 * 32, 0 * 32, 32, 32}; - const SDL_Rect up_narrow = {6 * 32, 0 * 32, 32, 32}; - const SDL_Rect down_wide = {7 * 32, 0 * 32, 32, 32}; - const SDL_Rect down_narrow = {8 * 32, 0 * 32, 32, 32}; - const SDL_Rect down_animation[4]{down_wide, down_narrow, closed, down_narrow}; - const SDL_Rect left_animation[4]{left_wide, left_narrow, closed, left_narrow}; - const SDL_Rect right_animation[4]{right_wide, right_narrow, closed, right_narrow}; - const SDL_Rect up_animation[4]{up_wide, up_narrow, closed, up_narrow}; + const SDL_Point right_wide = { 0, 0 }; + const SDL_Point right_narrow = { 1, 0 }; + const SDL_Point closed = { 2, 0 }; + const SDL_Point left_narrow = { 3, 0 }; + const SDL_Point left_wide = { 4, 0 }; + const SDL_Point up_wide = { 5, 0 }; + const SDL_Point up_narrow = { 6, 0 }; + const SDL_Point down_wide = { 7, 0 }; + const SDL_Point down_narrow = { 8, 0 }; + const SDL_Point down_animation[4]{ down_wide, down_narrow, closed, down_narrow }; + const SDL_Point left_animation[4]{ left_wide, left_narrow, closed, left_narrow }; + const SDL_Point right_animation[4]{ right_wide, right_narrow, closed, right_narrow }; + const SDL_Point up_animation[4]{ up_wide, up_narrow, closed, up_narrow }; }; diff --git a/lib/Pellets.cpp b/lib/Pellets.cpp index 138e755..b8a63f3 100644 --- a/lib/Pellets.cpp +++ b/lib/Pellets.cpp @@ -1,4 +1,4 @@ #include "Pellets.hpp" -Pellets::Pellets(const Board & board) : - positions(board.initialPelletPositions()) {} +Pellets::Pellets(const Board & board) + : positions(board.initialPelletPositions()) {} diff --git a/lib/Pellets.hpp b/lib/Pellets.hpp index 8b8dec6..daca2df 100644 --- a/lib/Pellets.hpp +++ b/lib/Pellets.hpp @@ -9,7 +9,7 @@ class Pellets { public: explicit Pellets(const Board & board); - [[nodiscard]] SDL_Rect currentSprite() const { + [[nodiscard]] SDL_Point currentSprite() const { return sprite; }; @@ -18,6 +18,6 @@ public: } private: - const SDL_Rect sprite = {1 * 32, 9 * 32, 32, 32}; + const SDL_Point sprite = { 1, 9 }; std::vector positions; }; diff --git a/lib/SuperPellets.hpp b/lib/SuperPellets.hpp index 5d795f4..fd8d07b 100644 --- a/lib/SuperPellets.hpp +++ b/lib/SuperPellets.hpp @@ -9,7 +9,7 @@ class SuperPellets { public: explicit SuperPellets(const Board & board); - [[nodiscard]] SDL_Rect currentSprite() const { + [[nodiscard]] SDL_Point currentSprite() const { return sprite; } @@ -18,6 +18,6 @@ public: } private: - const SDL_Rect sprite = {0 * 32, 9 * 32, 32, 32}; + const SDL_Point sprite = { 0, 9 }; std::vector positions; };