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>
|
||||
|
||||
Game::Game() :
|
||||
window(448, 496),
|
||||
board(),
|
||||
pacMan(board),
|
||||
Game::Game()
|
||||
: pacMan(board),
|
||||
pellets(board),
|
||||
superPellets(board) {}
|
||||
|
||||
|
|
|
@ -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<SDL_Point> 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<SDL_Point> 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_Window, SDL_Window_Deleter>(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");
|
||||
|
|
|
@ -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<SDL_Window, SDL_Window_Deleter> window;
|
||||
std::unique_ptr<SDL_Renderer, SDL_Renderer_Deleter> renderer;
|
||||
std::unique_ptr<SDL_Surface, SDL_Surface_Deleter> 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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "Pellets.hpp"
|
||||
|
||||
Pellets::Pellets(const Board & board) :
|
||||
positions(board.initialPelletPositions()) {}
|
||||
Pellets::Pellets(const Board & board)
|
||||
: positions(board.initialPelletPositions()) {}
|
||||
|
|
|
@ -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<SDL_Point> positions;
|
||||
};
|
||||
|
|
|
@ -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<SDL_Point> positions;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue