From 0cebd4ae751e0554f948389654fe4ad7e92943f0 Mon Sep 17 00:00:00 2001 From: Charles Date: Sat, 21 Mar 2020 14:52:18 +0100 Subject: Game logic finished (moving player, crates, checking win) --- src/game.cpp | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/graphics.cpp | 8 ++++- src/main.cpp | 2 +- 3 files changed, 100 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/game.cpp b/src/game.cpp index 88ff394..1ab4ab8 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -29,10 +29,12 @@ Game::Game(std::string fmt) m_grid[i][j] = CellWall; break; case CRATE_CHAR: - m_grid[i][j] = CellCrate; + m_grid[i][j] = CellEmpty; + m_cratePos.push_back(makePos(i, j)); break; case PAYLOAD_CHAR: - m_grid[i][j] = CellPayload; + m_grid[i][j] = CellEmpty; + m_payloadPos.push_back(makePos(i, j)); break; case MARIO_CHAR: m_grid[i][j] = CellEmpty; @@ -40,7 +42,6 @@ Game::Game(std::string fmt) m_playerPos.x = j; break; default: - m_grid[i][j] = CellEmpty; exit(1); } } @@ -55,9 +56,18 @@ Game::~Game() delete []m_grid; } +bool Game::won() +{ + for (std::vector::iterator it = m_payloadPos.begin(); it != m_payloadPos.end(); it++) + if (std::find(m_cratePos.begin(), m_cratePos.end(), *it) == m_cratePos.end()) + return false; + return true; +} + void Game::move(Direction direction) { m_playerDirection = direction; + Position saved = m_playerPos; switch (direction) { case DirectionUp: @@ -72,11 +82,38 @@ void Game::move(Direction direction) case DirectionRight: m_playerPos.x++; } + if (!validPosition(m_playerPos) || get(m_playerPos) == CellWall) + { + m_playerPos = saved; + return; + } + + if (get(m_playerPos) == CellCrate || get(m_playerPos) == CellCrateSolved) + { + if (!tryMoveCrate(*std::find( + m_cratePos.begin(), m_cratePos.end(), m_playerPos), + direction)) + m_playerPos = saved; + } } Game::Cell Game::get(int y, int x) const { - return m_grid[y][x]; + return get(makePos(y, x)); +} + +Game::Cell Game::get(const Position pos) const +{ + bool isCrate = std::find(m_cratePos.begin(), m_cratePos.end(), pos) != m_cratePos.end(); + bool isPayload = std::find(m_payloadPos.begin(), m_payloadPos.end(), pos) != m_payloadPos.end(); + + if (isCrate && isPayload) + return CellCrateSolved; + if (isCrate) + return CellCrate; + if (isPayload) + return CellPayload; + return m_grid[pos.y][pos.x]; } size_t Game::getHeight() const @@ -93,3 +130,54 @@ Game::Position const &Game::getPlayer() const { return m_playerPos; } + +#include +bool Game::tryMoveCrate(Position &pos, Direction direction) +{ + Position clone = pos; + + switch (direction) + { + case DirectionUp: + clone.y--; + break; + case DirectionDown: + clone.y++; + break; + case DirectionLeft: + clone.x--; + break; + case DirectionRight: + clone.x++; + } + // std::cout << pos.y << ", " << pos.x << "\n"; + // std::cout << get(pos) << std::endl; + if (!validPosition(clone) || get(clone) == CellCrate || get(clone) == CellWall) + return false; + pos = clone; + return true; +} + +bool Game::validPosition(Position pos) +{ + return pos.x < m_width && pos.y < m_height; // < 0 overflow +} + +Game::Position Game::makePos(int y, int x) +{ + Position p; + + p.y = y; + p.x = x; + return p; +} + +bool operator==(Game::Position const &a, Game::Position const &b) +{ + return a.x == b.x && a.y == b.y; +} + +bool operator!=(Game::Position const &a, Game::Position const &b) +{ + return !(a == b); +} diff --git a/src/graphics.cpp b/src/graphics.cpp index 734fd12..b773827 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -13,6 +13,7 @@ Graphics::Graphics(Game &game, std::string title, int width, int height): error(); m_wallTex = loadImage("sprite/wall.jpg"); m_crateTex = loadImage("sprite/crate.jpg"); + m_crateSolvedTex = loadImage("sprite/crate_solved.jpg"); m_payloadTex = loadImage("sprite/payload.png"); m_playerTex = loadImage("sprite/mario_down.gif"); } @@ -21,6 +22,7 @@ Graphics::~Graphics() { SDL_DestroyTexture(m_playerTex); SDL_DestroyTexture(m_payloadTex); + SDL_DestroyTexture(m_crateSolvedTex); SDL_DestroyTexture(m_crateTex); SDL_DestroyTexture(m_wallTex); SDL_DestroyRenderer(m_renderer); @@ -72,6 +74,9 @@ void Graphics::drawCell(Game::Cell cell, int y, int x) case Game::CellCrate: putImage(m_crateTex, &r); break; + case Game::CellCrateSolved: + putImage(m_crateSolvedTex, &r); + break; case Game::CellPayload: SDL_SetRenderDrawColor(m_renderer, 100, 100, 100, 255); SDL_RenderFillRect(m_renderer, &r); @@ -93,7 +98,6 @@ void Graphics::drawPlayer() r.w = m_width / m_game.getWidth(); r.h = m_height / m_game.getHeight(); putImage(m_playerTex, &r); - } void Graphics::handleEvent() @@ -123,6 +127,8 @@ void Graphics::handleEvent() m_game.move(Game::DirectionRight); break; } + if (m_game.won()) + m_running = false; } } } diff --git a/src/main.cpp b/src/main.cpp index 0bdf404..3f79ca7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,7 +9,7 @@ int main() "#* #\n" "# #\n" "# U #\n" - "# #\n" + "# U #\n" "#######\n" ); -- cgit