aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-03-21 16:12:16 +0100
committerCharles <sircharlesaze@gmail.com>2020-03-21 16:12:16 +0100
commitcaeb26e90ef09fdad85af72f460644e09d3b2c7c (patch)
treefa24199fac41284ddb5bcf6855a0b094de7582a2
parent0cebd4ae751e0554f948389654fe4ad7e92943f0 (diff)
downloadmario_sokoban-caeb26e90ef09fdad85af72f460644e09d3b2c7c.tar.gz
mario_sokoban-caeb26e90ef09fdad85af72f460644e09d3b2c7c.tar.bz2
mario_sokoban-caeb26e90ef09fdad85af72f460644e09d3b2c7c.zip
Player sprite direction, read map file
-rw-r--r--README.md3
-rw-r--r--include/game.hpp7
-rw-r--r--include/graphics.hpp5
-rw-r--r--map/cosomopoly01.sokoban9
-rw-r--r--map/square.sokoban7
-rw-r--r--screenshot.pngbin0 -> 46284 bytes
-rw-r--r--src/game.cpp134
-rw-r--r--src/graphics.cpp26
-rw-r--r--src/main.cpp28
9 files changed, 157 insertions, 62 deletions
diff --git a/README.md b/README.md
index 99861a7..2bbf9af 100644
--- a/README.md
+++ b/README.md
@@ -3,11 +3,14 @@
Mario sokoban project of [openclassrooms](https://openclassrooms.com/fr/courses/19980-apprenez-a-programmer-en-c/18709-tp-mario-sokoban)
(in C++ instead of C because I can't be bothered).
+![screenshot](./screenshot.png)
+
# Usage
```
make all
./mario_sokoban
+./mario_sokoban [mapfile]
```
# Dependencies
diff --git a/include/game.hpp b/include/game.hpp
index 647a12d..946f07c 100644
--- a/include/game.hpp
+++ b/include/game.hpp
@@ -1,6 +1,8 @@
#ifndef GAME_HPP
# define GAME_HPP
+#include <iostream>
+#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
@@ -9,6 +11,7 @@ class Game
{
public:
Game(std::string fmt);
+ Game(std::ifstream &file);
~Game();
enum Direction
@@ -40,6 +43,7 @@ public:
size_t getHeight() const;
size_t getWidth() const;
Position const &getPlayer() const;
+ Direction getPlayerDirection() const;
private:
@@ -51,8 +55,11 @@ private:
std::vector<Position> m_cratePos;
std::vector<Position> m_payloadPos;
+ void construct(std::string fmt);
+ void findWidth(std::string fmt);
bool tryMoveCrate(Position &pos, Direction direction);
bool validPosition(Position pos);
+
static Position makePos(int y, int x);
};
diff --git a/include/graphics.hpp b/include/graphics.hpp
index ea5d70e..5f274a3 100644
--- a/include/graphics.hpp
+++ b/include/graphics.hpp
@@ -28,7 +28,10 @@ private:
SDL_Texture *m_crateTex;
SDL_Texture *m_crateSolvedTex;
SDL_Texture *m_payloadTex;
- SDL_Texture *m_playerTex;
+ SDL_Texture *m_playerUpTex;
+ SDL_Texture *m_playerDownTex;
+ SDL_Texture *m_playerLeftTex;
+ SDL_Texture *m_playerRightTex;
void drawGame();
void drawCell(Game::Cell cell, int y, int x);
diff --git a/map/cosomopoly01.sokoban b/map/cosomopoly01.sokoban
new file mode 100644
index 0000000..7dc5f4e
--- /dev/null
+++ b/map/cosomopoly01.sokoban
@@ -0,0 +1,9 @@
+ ####
+ # ####
+ # #
+## #. #
+# * #*##
+# $ * #
+# # @ #
+# ####
+#####
diff --git a/map/square.sokoban b/map/square.sokoban
new file mode 100644
index 0000000..23d637c
--- /dev/null
+++ b/map/square.sokoban
@@ -0,0 +1,7 @@
+#######
+# m #
+#* #
+# U #
+# U #
+# * #
+#######
diff --git a/screenshot.png b/screenshot.png
new file mode 100644
index 0000000..2e042fd
--- /dev/null
+++ b/screenshot.png
Binary files differ
diff --git a/src/game.cpp b/src/game.cpp
index 1ab4ab8..cdc8937 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -1,52 +1,29 @@
#include "game.hpp"
-#define EMPTY_CHAR ' '
-#define WALL_CHAR '#'
-#define CRATE_CHAR 'U'
-#define PAYLOAD_CHAR '*'
-#define MARIO_CHAR 'm'
+#define EMPTY_CHAR ' '
+#define WALL_CHAR '#'
+#define CRATE_CHAR '$'
+#define CRATE_SOLVED_CHAR '*'
+#define PAYLOAD_CHAR '.'
+#define MARIO_CHAR '@'
Game::Game(std::string fmt)
: m_playerDirection(DirectionDown)
{
- size_t p;
+ construct(fmt);
+}
- m_height = std::count(fmt.begin(), fmt.end(), '\n');
- m_grid = new Cell*[m_height];
- m_width = fmt.find("\n");
- for (int i = 0; (p = fmt.find("\n")) != std::string::npos; i++)
- {
- std::string token = fmt.substr(0, p);
- m_grid[i] = new Cell[m_width];
- for (size_t j = 0; j < token.size(); j++)
- {
- switch (token[j])
- {
- case EMPTY_CHAR:
- m_grid[i][j] = CellEmpty;
- break;
- case WALL_CHAR:
- m_grid[i][j] = CellWall;
- break;
- case CRATE_CHAR:
- m_grid[i][j] = CellEmpty;
- m_cratePos.push_back(makePos(i, j));
- break;
- case PAYLOAD_CHAR:
- m_grid[i][j] = CellEmpty;
- m_payloadPos.push_back(makePos(i, j));
- break;
- case MARIO_CHAR:
- m_grid[i][j] = CellEmpty;
- m_playerPos.y = i;
- m_playerPos.x = j;
- break;
- default:
- exit(1);
- }
- }
- fmt.erase(0, p + 1);
- }
+Game::Game(std::ifstream &file)
+ : m_playerDirection(DirectionDown)
+{
+ std::string fmt;
+ std::string line;
+
+ if (!file)
+ exit(1);
+ while (getline(file, line))
+ fmt += line + "\n";
+ construct(fmt);
}
Game::~Game()
@@ -131,7 +108,73 @@ Game::Position const &Game::getPlayer() const
return m_playerPos;
}
-#include <iostream>
+Game::Direction Game::getPlayerDirection() const
+{
+ return m_playerDirection;
+}
+
+void Game::construct(std::string fmt)
+{
+ size_t p;
+
+ m_height = std::count(fmt.begin(), fmt.end(), '\n');
+ m_grid = new Cell*[m_height];
+ findWidth(fmt);
+ for (int i = 0; (p = fmt.find("\n")) != std::string::npos; i++)
+ {
+ std::string token = fmt.substr(0, p);
+ m_grid[i] = new Cell[m_width];
+ for (size_t j = 0; j < m_width; j++)
+ m_grid[i][j] = CellEmpty;
+ for (size_t j = 0; j < token.size(); j++)
+ {
+ switch (token[j])
+ {
+ case EMPTY_CHAR:
+ m_grid[i][j] = CellEmpty;
+ break;
+ case WALL_CHAR:
+ m_grid[i][j] = CellWall;
+ break;
+ case CRATE_CHAR:
+ m_grid[i][j] = CellEmpty;
+ m_cratePos.push_back(makePos(i, j));
+ break;
+ case CRATE_SOLVED_CHAR:
+ m_grid[i][j] = CellEmpty;
+ m_cratePos.push_back(makePos(i, j));
+ m_payloadPos.push_back(makePos(i, j));
+ break;
+ case PAYLOAD_CHAR:
+ m_grid[i][j] = CellEmpty;
+ m_payloadPos.push_back(makePos(i, j));
+ break;
+ case MARIO_CHAR:
+ m_grid[i][j] = CellEmpty;
+ m_playerPos.y = i;
+ m_playerPos.x = j;
+ break;
+ default:
+ std::cerr << "Cannot parse map" << std::endl;
+ exit(1);
+ }
+ }
+ fmt.erase(0, p + 1);
+ }
+}
+
+void Game::findWidth(std::string fmt)
+{
+ size_t p;
+ m_width = 0;
+
+ for (int i = 0; (p = fmt.find("\n")) != std::string::npos; i++)
+ {
+ m_width = std::max(m_width, p);
+ fmt.erase(0, p + 1);
+ }
+}
+
bool Game::tryMoveCrate(Position &pos, Direction direction)
{
Position clone = pos;
@@ -150,9 +193,8 @@ bool Game::tryMoveCrate(Position &pos, Direction direction)
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)
+ if (!validPosition(clone) || get(clone) == CellCrate
+ || get(clone) == CellCrateSolved || get(clone) == CellWall)
return false;
pos = clone;
return true;
diff --git a/src/graphics.cpp b/src/graphics.cpp
index b773827..298fc43 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -15,12 +15,18 @@ Graphics::Graphics(Game &game, std::string title, int width, int height):
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");
+ m_playerUpTex = loadImage("sprite/mario_up.gif");
+ m_playerDownTex = loadImage("sprite/mario_down.gif");
+ m_playerLeftTex = loadImage("sprite/mario_left.gif");
+ m_playerRightTex = loadImage("sprite/mario_right.gif");
}
Graphics::~Graphics()
{
- SDL_DestroyTexture(m_playerTex);
+ SDL_DestroyTexture(m_playerRightTex);
+ SDL_DestroyTexture(m_playerLeftTex);
+ SDL_DestroyTexture(m_playerDownTex);
+ SDL_DestroyTexture(m_playerUpTex);
SDL_DestroyTexture(m_payloadTex);
SDL_DestroyTexture(m_crateSolvedTex);
SDL_DestroyTexture(m_crateTex);
@@ -97,7 +103,21 @@ void Graphics::drawPlayer()
r.y = pos.y * (m_height / m_game.getHeight());
r.w = m_width / m_game.getWidth();
r.h = m_height / m_game.getHeight();
- putImage(m_playerTex, &r);
+ switch (m_game.getPlayerDirection())
+ {
+ case Game::DirectionUp:
+ putImage(m_playerUpTex, &r);
+ break;
+ case Game::DirectionDown:
+ putImage(m_playerDownTex, &r);
+ break;
+ case Game::DirectionLeft:
+ putImage(m_playerLeftTex, &r);
+ break;
+ case Game::DirectionRight:
+ putImage(m_playerRightTex, &r);
+ break;
+ }
}
void Graphics::handleEvent()
diff --git a/src/main.cpp b/src/main.cpp
index 3f79ca7..b7168d6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,20 +1,24 @@
+#include <iostream>
+#include <fstream>
#include "game.hpp"
#include "graphics.hpp"
-int main()
-{
- Game game(
- "#######\n"
- "# m #\n"
- "#* #\n"
- "# #\n"
- "# U #\n"
- "# U #\n"
- "#######\n"
- );
+#define DEFAULT_MAP_FILENAME "map/square.sokoban"
+int main(int argc, char **argv)
+{
+ std::ifstream file;
+ if (argc == 1)
+ file.open(DEFAULT_MAP_FILENAME);
+ else if (argc == 2)
+ file.open(argv[1]);
+ else
+ {
+ std::cout << "Usage: " << argv[0] << " [mapfile]" << std::endl;
+ return 0;
+ }
+ Game game(file);
Graphics graphics(game, "mario sokoban", 500, 500);
-
while (graphics.isRunning())
graphics.update();
return 0;