Extract Pellets and SuperPellets

All around refactor
This commit is contained in:
Patricia Aas 2020-11-28 14:10:25 +01:00
parent bf9aaa5cfc
commit 4789e93d62
20 changed files with 129 additions and 83 deletions

View File

@ -1,4 +1,4 @@
#include "Board.h" #include "Board.hpp"
// Legend // Legend
// 0 - wall // 0 - wall
@ -7,9 +7,6 @@
// 3 - door // 3 - door
// 4 - superpower // 4 - superpower
// 16 pixels per square
// Maze in pixels - width: 448 - height - 496
static const uint8_t board[ROWS][COLUMNS] = { static const uint8_t board[ROWS][COLUMNS] = {
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 0 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 0
@ -46,17 +43,12 @@ static const uint8_t board[ROWS][COLUMNS] = {
}; };
Board::Board() { Board::Board() {
resetBoardState();
}
void Board::resetBoardState() {
for (uint8_t row = 0; row < ROWS; row++) for (uint8_t row = 0; row < ROWS; row++)
for (uint8_t column = 0; column < COLUMNS; column++) for (uint8_t column = 0; column < COLUMNS; column++)
board_state[row][column] = board[row][column]; board_state[row][column] = board[row][column];
} }
bool Board::isWalkable(Position point, float_t position_delta, Direction direction) const { bool Board::isWalkable(Position point, float_t position_delta, Direction direction) const {
switch (direction) { switch (direction) {
case Direction::LEFT: case Direction::LEFT:
return board_state[int(point.y)][int(point.x - position_delta)] != 0; return board_state[int(point.y)][int(point.x - position_delta)] != 0;
@ -72,15 +64,7 @@ bool Board::isWalkable(Position point, float_t position_delta, Direction directi
} }
} }
SDL_Rect Board::pelletSprite() { std::vector<SDL_Point> Board::initialPelletPositions() const {
return pellet;
}
SDL_Rect Board::superPelletSprite() {
return super_pellet;
}
std::vector<SDL_Point> Board::pelletPositions() {
std::vector<SDL_Point> positions; std::vector<SDL_Point> positions;
for (uint8_t row = 0; row < ROWS; row++) { for (uint8_t row = 0; row < ROWS; row++) {
for (uint8_t column = 0; column < COLUMNS; column++) { for (uint8_t column = 0; column < COLUMNS; column++) {
@ -91,8 +75,7 @@ std::vector<SDL_Point> Board::pelletPositions() {
return positions; return positions;
} }
std::vector<SDL_Point> Board::superPelletPositions() { std::vector<SDL_Point> Board::initialSuperPelletPositions() const {
// Hard coded is probably better than this
std::vector<SDL_Point> positions; std::vector<SDL_Point> positions;
for (uint8_t row = 0; row < ROWS; row++) { for (uint8_t row = 0; row < ROWS; row++) {
for (uint8_t column = 0; column < COLUMNS; column++) { for (uint8_t column = 0; column < COLUMNS; column++) {

View File

@ -1,8 +1,9 @@
#ifndef PACMAN_BOARD_H #ifndef PACMAN_BOARD_H
#define PACMAN_BOARD_H #define PACMAN_BOARD_H
#include "Direction.h" #include "Direction.hpp"
#include "Position.h" #include "Position.hpp"
#include <SDL2/SDL_rect.h> #include <SDL2/SDL_rect.h>
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
@ -16,20 +17,14 @@ public:
[[nodiscard]] bool isWalkable(Position point, float_t d, Direction direction) const; [[nodiscard]] bool isWalkable(Position point, float_t d, Direction direction) const;
SDL_Rect pelletSprite(); [[nodiscard]] std::vector<SDL_Point> initialPelletPositions() const;
SDL_Rect superPelletSprite(); [[nodiscard]] std::vector<SDL_Point> initialSuperPelletPositions() const;
std::vector<SDL_Point> pelletPositions(); static Position initialPacManPosition() { return {14, 23}; }
std::vector<SDL_Point> superPelletPositions();
private: private:
uint8_t board_state[ROWS][COLUMNS]{}; uint8_t board_state[ROWS][COLUMNS]{};
const SDL_Rect super_pellet = {0 * 32, 9 * 32, 32, 32};
const SDL_Rect pellet = {1 * 32, 9 * 32, 32, 32};
void resetBoardState();
}; };
#endif //PACMAN_BOARD_H #endif //PACMAN_BOARD_H

View File

@ -1,12 +1,13 @@
#include "Game.h" #include "Game.hpp"
#include <SDL2/SDL.h>
#include <chrono> #include <chrono>
Game::Game() Game::Game() :
: window(448, 496) { window(448, 496),
} board(),
pacMan(board),
pellets(board),
superPellets(board) {}
auto Game::now() { auto Game::now() {
return std::chrono::system_clock::now(); return std::chrono::system_clock::now();
@ -21,7 +22,7 @@ void Game::run() {
auto milli_delta = std::chrono::duration_cast<std::chrono::milliseconds>(time_delta); auto milli_delta = std::chrono::duration_cast<std::chrono::milliseconds>(time_delta);
pacMan.update(milli_delta, inputState, board); pacMan.update(milli_delta, inputState, board);
current_time += time_delta; current_time += time_delta;
window.update(pacMan, board); window.update(pacMan, pellets, superPellets);
} }
} }

View File

@ -1,10 +1,13 @@
#ifndef PACMAN_GAME_H #ifndef PACMAN_GAME_H
#define PACMAN_GAME_H #define PACMAN_GAME_H
#include "Board.h" #include "Board.hpp"
#include "GameWindow.h" #include "GameWindow.hpp"
#include "InputState.h" #include "PacMan.hpp"
#include "PacMan.h" #include "Pellets.hpp"
#include "SuperPellets.hpp"
class InputState;
class Game { class Game {
public: public:
@ -14,8 +17,10 @@ public:
private: private:
GameWindow window; GameWindow window;
PacMan pacMan;
Board board; Board board;
PacMan pacMan;
Pellets pellets;
SuperPellets superPellets;
static void processEvents(InputState & inputState); static void processEvents(InputState & inputState);

View File

@ -1,10 +1,13 @@
#include "GameWindow.h" #include "GameWindow.hpp"
#include "PacMan.h"
#include <SDL2/SDL_image.h> #include <SDL2/SDL_image.h>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include "PacMan.hpp"
#include "Pellets.hpp"
#include "SuperPellets.hpp"
GameWindow::GameWindow(int width, int height) { GameWindow::GameWindow(int width, int height) {
initSDL(); initSDL();
initSDLImage(); initSDLImage();
@ -16,11 +19,12 @@ GameWindow::GameWindow(int width, int height) {
sprite_texture = loadTexture(sdl_renderer, "sprites32.png"); sprite_texture = loadTexture(sdl_renderer, "sprites32.png");
} }
void GameWindow::update(const PacMan & pacMan, Board board) { void GameWindow::update(const PacMan & pacMan, const Pellets & pellets, const SuperPellets & superPellets) {
SDL_RenderClear(renderer.get()); SDL_RenderClear(renderer.get());
renderMaze(); renderMaze();
renderBoard(board); renderPellets(pellets);
renderSuperPellets(superPellets);
renderPacMan(pacMan); renderPacMan(pacMan);
SDL_RenderPresent(renderer.get()); SDL_RenderPresent(renderer.get());
@ -30,23 +34,18 @@ void GameWindow::renderMaze() const {
renderTexture(maze_texture.get(), nullptr, nullptr); renderTexture(maze_texture.get(), nullptr, nullptr);
} }
void GameWindow::renderBoard(Board board) { void GameWindow::renderSuperPellets(const SuperPellets & superPellets) const {
renderPellets(board); SDL_Rect sprite_rect = superPellets.currentSprite();
renderSuperPellets(board); std::vector<SDL_Point> superPelletPositions = superPellets.currentPositions();
}
void GameWindow::renderSuperPellets(Board & board) const {
SDL_Rect sprite_rect = board.superPelletSprite();
std::vector<SDL_Point> superPelletPositions = board.superPelletPositions();
for (const auto & pos : superPelletPositions) { for (const auto & pos : superPelletPositions) {
SDL_Rect maze_rect = targetRect({float_t(pos.x), float_t(pos.y)}, 8 * SCALE_FACTOR); SDL_Rect maze_rect = targetRect({float_t(pos.x), float_t(pos.y)}, 8 * SCALE_FACTOR);
renderTexture(sprite_texture.get(), &sprite_rect, &maze_rect); renderTexture(sprite_texture.get(), &sprite_rect, &maze_rect);
} }
} }
void GameWindow::renderPellets(Board & board) const { void GameWindow::renderPellets(const Pellets & pellets) const {
SDL_Rect sprite_rect = board.pelletSprite(); SDL_Rect sprite_rect = pellets.currentSprite();
std::vector<SDL_Point> pelletPositions = board.pelletPositions(); std::vector<SDL_Point> pelletPositions = pellets.currentPositions();
for (const auto & pos : pelletPositions) { for (const auto & pos : pelletPositions) {
SDL_Rect maze_rect = targetRect({float_t(pos.x), float_t(pos.y)}, 8 * SCALE_FACTOR); SDL_Rect maze_rect = targetRect({float_t(pos.x), float_t(pos.y)}, 8 * SCALE_FACTOR);
renderTexture(sprite_texture.get(), &sprite_rect, &maze_rect); renderTexture(sprite_texture.get(), &sprite_rect, &maze_rect);

View File

@ -3,8 +3,6 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "PacMan.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
struct SDL_Window_Deleter { struct SDL_Window_Deleter {
@ -32,12 +30,15 @@ struct SDL_Texture_Deleter {
}; };
class PacMan; class PacMan;
class Pellets;
class Position;
class SuperPellets;
class GameWindow { class GameWindow {
public: public:
explicit GameWindow(int width, int height); explicit GameWindow(int width, int height);
void update(const PacMan & pacMan, Board board); void update(const PacMan & pacMan, const Pellets & pellets, const SuperPellets & superPellets);
private: private:
static const int16_t SCALE_FACTOR = 1; static const int16_t SCALE_FACTOR = 1;
@ -70,11 +71,9 @@ private:
void renderPacMan(const PacMan & pac_man) const; void renderPacMan(const PacMan & pac_man) const;
void renderBoard(Board board); void renderPellets(const Pellets & pellets) const;
void renderPellets(Board & board) const; void renderSuperPellets(const SuperPellets & superPellets) const;
void renderSuperPellets(Board & board) const;
static SDL_Rect targetRect(const Position & position, int pixel_increase); static SDL_Rect targetRect(const Position & position, int pixel_increase);

View File

@ -1 +0,0 @@
#include "InputState.h"

View File

@ -1,5 +1,7 @@
#include "PacMan.h" #include "PacMan.hpp"
#include "PacManAnimation.hpp"
PacMan::PacMan(const Board & board) :
pos(board.initialPacManPosition()) {}
SDL_Rect PacMan::currentSprite() const { SDL_Rect PacMan::currentSprite() const {
return pacManAnimation.animationFrame(direction); return pacManAnimation.animationFrame(direction);

View File

@ -1,17 +1,20 @@
#ifndef PACMAN_PACMAN_H #ifndef PACMAN_PACMAN_H
#define PACMAN_PACMAN_H #define PACMAN_PACMAN_H
#include "Board.h" #include "Direction.hpp"
#include "Direction.h" #include "Position.hpp"
#include "InputState.h"
#include "Position.h"
#include "PacManAnimation.hpp" #include "PacManAnimation.hpp"
#include <SDL2/SDL_rect.h> #include <SDL2/SDL_rect.h>
#include <chrono> #include <chrono>
class Board;
class InputState;
class PacMan { class PacMan {
public: public:
explicit PacMan(const Board & board);
[[nodiscard]] SDL_Rect currentSprite() const; [[nodiscard]] SDL_Rect currentSprite() const;
[[nodiscard]] Position currentPosition() const; [[nodiscard]] Position currentPosition() const;
@ -22,7 +25,7 @@ private:
Direction direction = Direction::NONE; Direction direction = Direction::NONE;
Direction desired_direction = Direction::NONE; Direction desired_direction = Direction::NONE;
Position pos = {14, 23}; Position pos;
PacManAnimation pacManAnimation; PacManAnimation pacManAnimation;
void setDirection(const InputState & state); void setDirection(const InputState & state);

View File

@ -1,10 +1,10 @@
#ifndef PACMAN_PACMAN_ANIMATION_HPP #ifndef PACMAN_PACMAN_ANIMATION_HPP
#define PACMAN_PACMAN_ANIMATION_HPP #define PACMAN_PACMAN_ANIMATION_HPP
#include "Board.h" #include "Board.hpp"
#include "Direction.h" #include "Direction.hpp"
#include "InputState.h" #include "InputState.hpp"
#include "Position.h" #include "Position.hpp"
#include <SDL2/SDL_rect.h> #include <SDL2/SDL_rect.h>
#include <chrono> #include <chrono>
@ -12,7 +12,7 @@
class PacManAnimation { class PacManAnimation {
public: public:
SDL_Rect 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);

4
pacman/lib/Pellets.cpp Normal file
View File

@ -0,0 +1,4 @@
#include "Pellets.hpp"
Pellets::Pellets(const Board & board) :
positions(board.initialPelletPositions()) {}

26
pacman/lib/Pellets.hpp Normal file
View File

@ -0,0 +1,26 @@
#ifndef PACMAN_PELLETS_HPP
#define PACMAN_PELLETS_HPP
#include "Position.hpp"
#include "Board.hpp"
#include <SDL2/SDL_rect.h>
class Pellets {
public:
explicit Pellets(const Board & board);
[[nodiscard]] SDL_Rect currentSprite() const {
return pellet;
};
[[nodiscard]] std::vector<SDL_Point> currentPositions() const {
return positions;
}
private:
const SDL_Rect pellet = {1 * 32, 9 * 32, 32, 32};
std::vector<SDL_Point> positions;
};
#endif //PACMAN_PELLETS_HPP

View File

@ -1,7 +1,7 @@
#ifndef PACMAN_POSITION_H #ifndef PACMAN_POSITION_H
#define PACMAN_POSITION_H #define PACMAN_POSITION_H
#include <math.h> #include <cmath>
struct Position { struct Position {
float_t x; float_t x;

View File

@ -0,0 +1,4 @@
#include "SuperPellets.hpp"
SuperPellets::SuperPellets(const Board & board) :
positions(board.initialSuperPelletPositions()) {}

View File

@ -0,0 +1,26 @@
#ifndef PACMAN_SUPERPELLETS_HPP
#define PACMAN_SUPERPELLETS_HPP
#include "Position.hpp"
#include "Board.hpp"
#include <SDL2/SDL_rect.h>
class SuperPellets {
public:
explicit SuperPellets(const Board & board);
[[nodiscard]] SDL_Rect currentSprite() const {
return super_pellet;
}
[[nodiscard]] std::vector<SDL_Point> currentPositions() const {
return positions;
}
private:
const SDL_Rect super_pellet = {0 * 32, 9 * 32, 32, 32};
std::vector<SDL_Point> positions;
};
#endif //PACMAN_SUPERPELLETS_HPP

View File

@ -1,4 +1,4 @@
#include "../lib/Game.h" #include "../lib/Game.hpp"
extern "C" int main([[maybe_unused]] int argc, [[maybe_unused]] char * argv[]) { extern "C" int main([[maybe_unused]] int argc, [[maybe_unused]] char * argv[]) {
Game game; Game game;

View File

@ -6,6 +6,5 @@ include(GoogleTest)
add_executable(tests tests.cpp) add_executable(tests tests.cpp)
target_link_libraries(tests GTest::GTest libpacman) target_link_libraries(tests GTest::GTest libpacman)
#gtest_add_tests(TARGET tests TEST_PREFIX old_pacman:)
gtest_discover_tests(tests TEST_PREFIX pacman:) gtest_discover_tests(tests TEST_PREFIX pacman:)
add_test(NAME monolithic COMMAND tests) add_test(NAME monolithic COMMAND tests)

View File

@ -1,8 +1,9 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "../lib/PacMan.h" #include "../lib/PacMan.hpp"
TEST(PacManTest, InitialPosition) { TEST(PacManTest, InitialPosition) {
PacMan pacMan; Board board;
PacMan pacMan(board);
EXPECT_EQ(pacMan.currentPosition().x, 14); EXPECT_EQ(pacMan.currentPosition().x, 14);
EXPECT_EQ(pacMan.currentPosition().y, 23); EXPECT_EQ(pacMan.currentPosition().y, 23);
} }