Change window geometry for scoring.
* Add margins all around the board for better aestetics. * Add room for scoring * Because the texture atlas is a 32x32 grid, we can manipulate textures as positions on that grid and only create a rectangle for that texture in the rendering code. * Avoid hardcoded values in the rendering code.
This commit is contained in:
parent
27b8d47dec
commit
bbf3731cf4
10 changed files with 92 additions and 62 deletions
|
@ -2,10 +2,8 @@
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
Game::Game() :
|
Game::Game()
|
||||||
window(448, 496),
|
: pacMan(board),
|
||||||
board(),
|
|
||||||
pacMan(board),
|
|
||||||
pellets(board),
|
pellets(board),
|
||||||
superPellets(board) {}
|
superPellets(board) {}
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,13 @@
|
||||||
#include "Pellets.hpp"
|
#include "Pellets.hpp"
|
||||||
#include "SuperPellets.hpp"
|
#include "SuperPellets.hpp"
|
||||||
|
|
||||||
GameWindow::GameWindow(int width, int height) {
|
GameWindow::GameWindow() {
|
||||||
initSDL();
|
initSDL();
|
||||||
initSDLImage();
|
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);
|
auto sdl_renderer = createRenderer(sdl_window);
|
||||||
createWindowSurface(sdl_window);
|
createWindowSurface(sdl_window);
|
||||||
setDrawColor(sdl_renderer);
|
setDrawColor(sdl_renderer);
|
||||||
|
@ -31,47 +34,54 @@ void GameWindow::update(const PacMan & pacMan, const Pellets & pellets, const Su
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameWindow::renderMaze() const {
|
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 {
|
void GameWindow::renderSuperPellets(const SuperPellets & superPellets) const {
|
||||||
SDL_Rect sprite_rect = superPellets.currentSprite();
|
SDL_Rect sprite_rect = textureGeometry(superPellets.currentSprite());
|
||||||
std::vector<SDL_Point> superPelletPositions = superPellets.currentPositions();
|
std::vector<SDL_Point> superPelletPositions = superPellets.currentPositions();
|
||||||
for (const auto & pos : superPelletPositions) {
|
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, pos);
|
||||||
renderTexture(sprite_texture.get(), &sprite_rect, &maze_rect);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameWindow::renderPellets(const Pellets & pellets) const {
|
void GameWindow::renderPellets(const Pellets & pellets) const {
|
||||||
SDL_Rect sprite_rect = pellets.currentSprite();
|
SDL_Rect sprite_rect = textureGeometry(pellets.currentSprite());
|
||||||
std::vector<SDL_Point> pelletPositions = pellets.currentPositions();
|
std::vector<SDL_Point> pelletPositions = pellets.currentPositions();
|
||||||
for (const auto & pos : pelletPositions) {
|
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, pos);
|
||||||
renderTexture(sprite_texture.get(), &sprite_rect, &maze_rect);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameWindow::renderPacMan(const PacMan & pac_man) const {
|
void GameWindow::renderPacMan(const PacMan & pac_man) const {
|
||||||
Position maze_position = pac_man.position();
|
SDL_Rect sprite_rect = textureGeometry(pac_man.currentSprite());
|
||||||
SDL_Rect maze_rect = targetRect(maze_position, 8 * SCALE_FACTOR);
|
Position pacman_pos = pac_man.position();
|
||||||
SDL_Rect sprite_rect = pac_man.currentSprite();
|
renderTexture(sprite_texture.get(), sprite_rect, SDL_Point{ int(pacman_pos.x), int(pacman_pos.y) });
|
||||||
renderTexture(sprite_texture.get(), &sprite_rect, &maze_rect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Rect GameWindow::targetRect(const Position & position, int pixel_increase) {
|
SDL_Rect GameWindow::textureGeometry(SDL_Point p) const {
|
||||||
int pixels = 16 * SCALE_FACTOR;
|
return { p.x * 32, p.y * 32, 32, 32 };
|
||||||
int displacement = pixel_increase / 2;
|
}
|
||||||
return {
|
|
||||||
int(pixels * position.x) - displacement,
|
SDL_Rect GameWindow::windowDimensions() const {
|
||||||
int(pixels * position.y) - displacement,
|
return { 0, 0, LEFT_MARGIN + MAZE_WIDTH + SCORE_WIDTH, TOP_MARGIN + MAZE_HEIGHT + BOTTOM_MARGIN };
|
||||||
(pixels + pixel_increase),
|
}
|
||||||
(pixels + pixel_increase)
|
|
||||||
|
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 {
|
void GameWindow::renderTexture(SDL_Texture * texture, const SDL_Rect & src, const SDL_Rect & target) const {
|
||||||
if (SDL_RenderCopy(renderer.get(), texture, texture_rect, target_rect) < 0)
|
|
||||||
|
if (SDL_RenderCopy(renderer.get(), texture, &src, &target) < 0)
|
||||||
exitFailure("Failed to copy texture to renderer");
|
exitFailure("Failed to copy texture to renderer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,12 +98,12 @@ void GameWindow::initSDLImage() {
|
||||||
|
|
||||||
SDL_Window * GameWindow::createWindow(int width, int height) {
|
SDL_Window * GameWindow::createWindow(int width, int height) {
|
||||||
window = std::unique_ptr<SDL_Window, SDL_Window_Deleter>(SDL_CreateWindow(
|
window = std::unique_ptr<SDL_Window, SDL_Window_Deleter>(SDL_CreateWindow(
|
||||||
"Pacman",
|
"Pacman",
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
SDL_WINDOW_OPENGL));
|
SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI));
|
||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
exitFailure("Failed to create window");
|
exitFailure("Failed to create window");
|
||||||
|
|
|
@ -28,19 +28,34 @@ struct SDL_Texture_Deleter {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TextureSize {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
};
|
||||||
|
|
||||||
class PacMan;
|
class PacMan;
|
||||||
class Pellets;
|
class Pellets;
|
||||||
class Position;
|
//class Position;
|
||||||
class SuperPellets;
|
class SuperPellets;
|
||||||
|
|
||||||
class GameWindow {
|
class GameWindow {
|
||||||
public:
|
public:
|
||||||
explicit GameWindow(int width, int height);
|
explicit GameWindow();
|
||||||
|
|
||||||
void update(const PacMan & pacMan, const Pellets & pellets, const SuperPellets & superPellets);
|
void update(const PacMan & pacMan, const Pellets & pellets, const SuperPellets & superPellets);
|
||||||
|
|
||||||
private:
|
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<SDL_Window, SDL_Window_Deleter> window;
|
std::unique_ptr<SDL_Window, SDL_Window_Deleter> window;
|
||||||
std::unique_ptr<SDL_Renderer, SDL_Renderer_Deleter> renderer;
|
std::unique_ptr<SDL_Renderer, SDL_Renderer_Deleter> renderer;
|
||||||
std::unique_ptr<SDL_Surface, SDL_Surface_Deleter> window_surface;
|
std::unique_ptr<SDL_Surface, SDL_Surface_Deleter> window_surface;
|
||||||
|
@ -74,7 +89,15 @@ private:
|
||||||
|
|
||||||
void renderSuperPellets(const SuperPellets & superPellets) const;
|
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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
PacMan::PacMan(const Board & board) :
|
PacMan::PacMan(const Board & board) :
|
||||||
pos(board.initialPacManPosition()) {}
|
pos(board.initialPacManPosition()) {}
|
||||||
|
|
||||||
SDL_Rect PacMan::currentSprite() const {
|
SDL_Point PacMan::currentSprite() const {
|
||||||
return pacManAnimation.animationFrame(direction);
|
return pacManAnimation.animationFrame(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ class PacMan {
|
||||||
public:
|
public:
|
||||||
explicit PacMan(const Board & board);
|
explicit PacMan(const Board & board);
|
||||||
|
|
||||||
[[nodiscard]] SDL_Rect currentSprite() const;
|
[[nodiscard]] SDL_Point currentSprite() const;
|
||||||
|
|
||||||
[[nodiscard]] Position position() const;
|
[[nodiscard]] Position position() const;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "PacManAnimation.hpp"
|
#include "PacManAnimation.hpp"
|
||||||
|
|
||||||
SDL_Rect PacManAnimation::animationFrame(Direction direction) const {
|
SDL_Point PacManAnimation::animationFrame(Direction direction) const {
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case Direction::NONE:
|
case Direction::NONE:
|
||||||
return closed;
|
return closed;
|
||||||
|
|
|
@ -10,25 +10,24 @@
|
||||||
|
|
||||||
class PacManAnimation {
|
class PacManAnimation {
|
||||||
public:
|
public:
|
||||||
|
[[nodiscard]] SDL_Point animationFrame(Direction direction) const;
|
||||||
[[nodiscard]] SDL_Rect animationFrame(Direction direction) const;
|
|
||||||
|
|
||||||
void updateAnimationPosition(std::chrono::milliseconds time_delta);
|
void updateAnimationPosition(std::chrono::milliseconds time_delta);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t animation_position = 0;
|
uint8_t animation_position = 0;
|
||||||
float animation_position_delta = 0.0;
|
float animation_position_delta = 0.0;
|
||||||
const SDL_Rect right_wide = {0 * 32, 0 * 32, 32, 32};
|
const SDL_Point right_wide = { 0, 0 };
|
||||||
const SDL_Rect right_narrow = {1 * 32, 0 * 32, 32, 32};
|
const SDL_Point right_narrow = { 1, 0 };
|
||||||
const SDL_Rect closed = {2 * 32, 0 * 32, 32, 32};
|
const SDL_Point closed = { 2, 0 };
|
||||||
const SDL_Rect left_narrow = {3 * 32, 0 * 32, 32, 32};
|
const SDL_Point left_narrow = { 3, 0 };
|
||||||
const SDL_Rect left_wide = {4 * 32, 0 * 32, 32, 32};
|
const SDL_Point left_wide = { 4, 0 };
|
||||||
const SDL_Rect up_wide = {5 * 32, 0 * 32, 32, 32};
|
const SDL_Point up_wide = { 5, 0 };
|
||||||
const SDL_Rect up_narrow = {6 * 32, 0 * 32, 32, 32};
|
const SDL_Point up_narrow = { 6, 0 };
|
||||||
const SDL_Rect down_wide = {7 * 32, 0 * 32, 32, 32};
|
const SDL_Point down_wide = { 7, 0 };
|
||||||
const SDL_Rect down_narrow = {8 * 32, 0 * 32, 32, 32};
|
const SDL_Point down_narrow = { 8, 0 };
|
||||||
const SDL_Rect down_animation[4]{down_wide, down_narrow, closed, down_narrow};
|
const SDL_Point 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_Point 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_Point 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 up_animation[4]{ up_wide, up_narrow, closed, up_narrow };
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "Pellets.hpp"
|
#include "Pellets.hpp"
|
||||||
|
|
||||||
Pellets::Pellets(const Board & board) :
|
Pellets::Pellets(const Board & board)
|
||||||
positions(board.initialPelletPositions()) {}
|
: positions(board.initialPelletPositions()) {}
|
||||||
|
|
|
@ -9,7 +9,7 @@ class Pellets {
|
||||||
public:
|
public:
|
||||||
explicit Pellets(const Board & board);
|
explicit Pellets(const Board & board);
|
||||||
|
|
||||||
[[nodiscard]] SDL_Rect currentSprite() const {
|
[[nodiscard]] SDL_Point currentSprite() const {
|
||||||
return sprite;
|
return sprite;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,6 +18,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const SDL_Rect sprite = {1 * 32, 9 * 32, 32, 32};
|
const SDL_Point sprite = { 1, 9 };
|
||||||
std::vector<SDL_Point> positions;
|
std::vector<SDL_Point> positions;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,7 +9,7 @@ class SuperPellets {
|
||||||
public:
|
public:
|
||||||
explicit SuperPellets(const Board & board);
|
explicit SuperPellets(const Board & board);
|
||||||
|
|
||||||
[[nodiscard]] SDL_Rect currentSprite() const {
|
[[nodiscard]] SDL_Point currentSprite() const {
|
||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const SDL_Rect sprite = {0 * 32, 9 * 32, 32, 32};
|
const SDL_Point sprite = { 0, 9 };
|
||||||
std::vector<SDL_Point> positions;
|
std::vector<SDL_Point> positions;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue