diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/game.h | 12 | ||||
| -rw-r--r-- | src/main.cpp | 5 | ||||
| -rw-r--r-- | src/map.cpp | 46 | ||||
| -rw-r--r-- | src/map.h | 41 | ||||
| -rw-r--r-- | src/renderer.cpp | 67 | ||||
| -rw-r--r-- | src/renderer.h | 5 | ||||
| -rw-r--r-- | src/vector.h | 4 |
7 files changed, 140 insertions, 40 deletions
| diff --git a/src/game.h b/src/game.h index e5976b1..2c1680a 100644 --- a/src/game.h +++ b/src/game.h | |||
| @@ -4,8 +4,9 @@ | |||
| 4 | #include <set> | 4 | #include <set> |
| 5 | #include <range/v3/all.hpp> | 5 | #include <range/v3/all.hpp> |
| 6 | #include <vector> | 6 | #include <vector> |
| 7 | #include <tileson.hpp> | 7 | #include <memory> |
| 8 | #include "sprite.h" | 8 | #include "sprite.h" |
| 9 | #include "map.h" | ||
| 9 | 10 | ||
| 10 | struct Input { | 11 | struct Input { |
| 11 | bool left = false; | 12 | bool left = false; |
| @@ -55,18 +56,15 @@ public: | |||
| 55 | } | 56 | } |
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | void loadMapFromFile(std::string_view filename) { | 59 | void setMap(std::unique_ptr<Map> map) { map_ = std::move(map); } |
| 59 | tson::Tileson t; | ||
| 60 | map_ = t.parse(fs::path(filename)); | ||
| 61 | } | ||
| 62 | 60 | ||
| 63 | tson::Map* getMap() const { return map_.get(); } | 61 | const Map& getMap() const { return *map_; } |
| 64 | 62 | ||
| 65 | private: | 63 | private: |
| 66 | 64 | ||
| 67 | std::vector<Sprite> sprites_; | 65 | std::vector<Sprite> sprites_; |
| 68 | std::set<std::tuple<int, int>> spritesByY_; | 66 | std::set<std::tuple<int, int>> spritesByY_; |
| 69 | std::unique_ptr<tson::Map> map_; | 67 | std::unique_ptr<Map> map_; |
| 70 | }; | 68 | }; |
| 71 | 69 | ||
| 72 | #endif /* end of include guard: GAME_H_E6F1396E */ | 70 | #endif /* end of include guard: GAME_H_E6F1396E */ |
| diff --git a/src/main.cpp b/src/main.cpp index df0bfff..587ae15 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -1,14 +1,17 @@ | |||
| 1 | #include <iostream> | 1 | #include <iostream> |
| 2 | #include <memory> | ||
| 2 | #include "renderer.h" | 3 | #include "renderer.h" |
| 3 | #include "game.h" | 4 | #include "game.h" |
| 4 | #include "party.h" | 5 | #include "party.h" |
| 5 | #include "timer.h" | 6 | #include "timer.h" |
| 7 | #include "map.h" | ||
| 6 | 8 | ||
| 7 | void loop(Renderer& renderer) { | 9 | void loop(Renderer& renderer) { |
| 8 | Game game; | 10 | Game game; |
| 9 | Input keystate; | 11 | Input keystate; |
| 10 | 12 | ||
| 11 | game.loadMapFromFile("../res/map1.json"); | 13 | auto map = std::make_unique<Map>("../res/map1.tmx", renderer); |
| 14 | game.setMap(std::move(map)); | ||
| 12 | 15 | ||
| 13 | int lucasSprite = game.addSprite(Sprite("../res/lucas_anim.txt", renderer)); | 16 | int lucasSprite = game.addSprite(Sprite("../res/lucas_anim.txt", renderer)); |
| 14 | int kumaSprite = game.addSprite(Sprite("../res/kuma_anim.txt", renderer)); | 17 | int kumaSprite = game.addSprite(Sprite("../res/kuma_anim.txt", renderer)); |
| diff --git a/src/map.cpp b/src/map.cpp new file mode 100644 index 0000000..a60cbba --- /dev/null +++ b/src/map.cpp | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | #include "map.h" | ||
| 2 | #include <tmxlite/Map.hpp> | ||
| 3 | #include <tmxlite/Layer.hpp> | ||
| 4 | #include <tmxlite/TileLayer.hpp> | ||
| 5 | #include <tmxlite/Tileset.hpp> | ||
| 6 | #include "renderer.h" | ||
| 7 | |||
| 8 | Map::Map(std::string_view filename, Renderer& renderer) { | ||
| 9 | tmx::Map mapfile; | ||
| 10 | if (!mapfile.load(filename.data())) { | ||
| 11 | throw std::invalid_argument("Could not find map file: " + std::string(filename)); | ||
| 12 | } | ||
| 13 | |||
| 14 | const tmx::Vector2u& mapSize = mapfile.getTileCount(); | ||
| 15 | mapSize_.x() = mapSize.x; | ||
| 16 | mapSize_.y() = mapSize.y; | ||
| 17 | |||
| 18 | const tmx::Vector2u& tileSize = mapfile.getTileSize(); | ||
| 19 | tileSize_.x() = tileSize.x; | ||
| 20 | tileSize_.y() = tileSize.y; | ||
| 21 | |||
| 22 | int firstGID = 0; | ||
| 23 | // There should only be one tileset. | ||
| 24 | for (const tmx::Tileset& tileset : mapfile.getTilesets()) { | ||
| 25 | firstGID = tileset.getFirstGID(); | ||
| 26 | tilesetTextureId_ = renderer.loadImageFromFile(tileset.getImagePath()); | ||
| 27 | tilesetColumns_ = tileset.getColumnCount(); | ||
| 28 | } | ||
| 29 | |||
| 30 | for (const auto& layer : mapfile.getLayers()) { | ||
| 31 | if (layer->getType() == tmx::Layer::Type::Tile) { | ||
| 32 | const auto& tileLayer = layer->getLayerAs<tmx::TileLayer>(); | ||
| 33 | |||
| 34 | std::vector<Tile> tilesToStore; | ||
| 35 | |||
| 36 | for (const auto& maptile : tileLayer.getTiles()) { | ||
| 37 | tilesToStore.push_back(Tile { | ||
| 38 | .id = maptile.ID - firstGID, | ||
| 39 | .flipHorizontal = (maptile.flipFlags & tmx::TileLayer::Horizontal) != 0, | ||
| 40 | .flipVertical = (maptile.flipFlags & tmx::TileLayer::Vertical) != 0 }); | ||
| 41 | } | ||
| 42 | |||
| 43 | layers_.push_back(std::move(tilesToStore)); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | } | ||
| diff --git a/src/map.h b/src/map.h new file mode 100644 index 0000000..1031996 --- /dev/null +++ b/src/map.h | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | #ifndef MAP_H_D95D6D47 | ||
| 2 | #define MAP_H_D95D6D47 | ||
| 3 | |||
| 4 | #include <string_view> | ||
| 5 | #include <vector> | ||
| 6 | #include "renderer.h" | ||
| 7 | #include "vector.h" | ||
| 8 | |||
| 9 | class Renderer; | ||
| 10 | |||
| 11 | struct Tile { | ||
| 12 | unsigned int id = 0; | ||
| 13 | bool flipHorizontal = false; | ||
| 14 | bool flipVertical = false; | ||
| 15 | }; | ||
| 16 | |||
| 17 | class Map { | ||
| 18 | public: | ||
| 19 | |||
| 20 | Map(std::string_view filename, Renderer& renderer); | ||
| 21 | |||
| 22 | const vec2i& getMapSize() const { return mapSize_; } | ||
| 23 | |||
| 24 | const vec2i& getTileSize() const { return tileSize_; } | ||
| 25 | |||
| 26 | const std::vector<std::vector<Tile>>& getLayers() const { return layers_; } | ||
| 27 | |||
| 28 | int getTilesetTextureId() const { return tilesetTextureId_; } | ||
| 29 | |||
| 30 | int getTilesetColumns() const { return tilesetColumns_; } | ||
| 31 | |||
| 32 | private: | ||
| 33 | |||
| 34 | vec2i mapSize_; | ||
| 35 | vec2i tileSize_; | ||
| 36 | std::vector<std::vector<Tile>> layers_; | ||
| 37 | int tilesetTextureId_; | ||
| 38 | int tilesetColumns_; | ||
| 39 | }; | ||
| 40 | |||
| 41 | #endif /* end of include guard: MAP_H_D95D6D47 */ | ||
| diff --git a/src/renderer.cpp b/src/renderer.cpp index 45b9045..9d20fee 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #include "renderer.h" | 1 | #include "renderer.h" |
| 2 | #include "consts.h" | 2 | #include "consts.h" |
| 3 | #include "game.h" | 3 | #include "game.h" |
| 4 | #include "map.h" | ||
| 4 | 5 | ||
| 5 | Renderer::Renderer() { | 6 | Renderer::Renderer() { |
| 6 | win_ = window_ptr( | 7 | win_ = window_ptr( |
| @@ -29,14 +30,16 @@ Renderer::Renderer() { | |||
| 29 | } | 30 | } |
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | texture_ptr Renderer::renderMapLayer(const tson::Layer& layer) { | 33 | texture_ptr Renderer::renderMapLayer(const Map& map, int layer) { |
| 34 | vec2i mapBounds = map.getMapSize() * map.getTileSize(); | ||
| 35 | |||
| 33 | texture_ptr canvas( | 36 | texture_ptr canvas( |
| 34 | SDL_CreateTexture( | 37 | SDL_CreateTexture( |
| 35 | ren_.get(), | 38 | ren_.get(), |
| 36 | SDL_PIXELFORMAT_RGBA8888, | 39 | SDL_PIXELFORMAT_RGBA8888, |
| 37 | SDL_TEXTUREACCESS_TARGET, | 40 | SDL_TEXTUREACCESS_TARGET, |
| 38 | layer.getMap()->getSize().x * layer.getMap()->getTileSize().x, | 41 | mapBounds.w(), |
| 39 | layer.getMap()->getSize().y * layer.getMap()->getTileSize().y)); | 42 | mapBounds.h())); |
| 40 | 43 | ||
| 41 | SDL_SetTextureBlendMode(canvas.get(), SDL_BLENDMODE_BLEND); | 44 | SDL_SetTextureBlendMode(canvas.get(), SDL_BLENDMODE_BLEND); |
| 42 | 45 | ||
| @@ -45,38 +48,44 @@ texture_ptr Renderer::renderMapLayer(const tson::Layer& layer) { | |||
| 45 | SDL_SetRenderDrawColor(ren_.get(), 255, 255, 255, 0); | 48 | SDL_SetRenderDrawColor(ren_.get(), 255, 255, 255, 0); |
| 46 | SDL_RenderClear(ren_.get()); | 49 | SDL_RenderClear(ren_.get()); |
| 47 | 50 | ||
| 48 | for (auto& [pos, tileObject] : layer.getTileObjects()) { | 51 | const std::vector<Tile>& tiles = map.getLayers().at(layer); |
| 49 | int x = tileObject.getPosition().x; | 52 | for (int y = 0; y < map.getMapSize().h(); y++) { |
| 50 | int y = tileObject.getPosition().y; | 53 | for (int x = 0; x < map.getMapSize().w(); x++) { |
| 51 | tson::Rect tileDestRect = tileObject.getDrawingRect(); | 54 | const Tile& tile = tiles.at(x + y * map.getMapSize().w()); |
| 52 | SDL_Rect srcRect { tileDestRect.x, tileDestRect.y, tileDestRect.width, tileDestRect.height }; | 55 | |
| 53 | SDL_Rect destRect { | 56 | SDL_Rect srcRect { |
| 54 | x, y, tileObject.getTile()->getTileSize().x, tileObject.getTile()->getTileSize().y }; | 57 | static_cast<int>((tile.id % map.getTilesetColumns()) * map.getTileSize().w()), |
| 55 | 58 | static_cast<int>((tile.id / map.getTilesetColumns()) * map.getTileSize().h()), | |
| 56 | SDL_RendererFlip flip = SDL_FLIP_NONE; | 59 | map.getTileSize().w(), |
| 57 | if (tileObject.getTile()->hasFlipFlags(tson::TileFlipFlags::Horizontally | tson::TileFlipFlags::Vertically)) { | 60 | map.getTileSize().h() }; |
| 58 | flip = static_cast<SDL_RendererFlip>(SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL); | 61 | |
| 59 | } else if (tileObject.getTile()->hasFlipFlags(tson::TileFlipFlags::Horizontally)) { | 62 | SDL_Rect destRect { |
| 60 | flip = SDL_FLIP_HORIZONTAL; | 63 | x * map.getTileSize().w(), |
| 61 | } else if (tileObject.getTile()->hasFlipFlags(tson::TileFlipFlags::Vertically)) { | 64 | y * map.getTileSize().h(), |
| 62 | flip = SDL_FLIP_VERTICAL; | 65 | map.getTileSize().w(), |
| 66 | map.getTileSize().h() }; | ||
| 67 | |||
| 68 | SDL_RendererFlip flip = SDL_FLIP_NONE; | ||
| 69 | if (tile.flipHorizontal && tile.flipVertical) { | ||
| 70 | flip = static_cast<SDL_RendererFlip>(SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL); | ||
| 71 | } else if (tile.flipHorizontal) { | ||
| 72 | flip = SDL_FLIP_HORIZONTAL; | ||
| 73 | } else if (tile.flipVertical) { | ||
| 74 | flip = SDL_FLIP_VERTICAL; | ||
| 75 | } | ||
| 76 | SDL_RenderCopyEx(ren_.get(), textures_[map.getTilesetTextureId()].get(), &srcRect, &destRect, 0, nullptr, flip); | ||
| 63 | } | 77 | } |
| 64 | SDL_RenderCopyEx(ren_.get(), textures_[tilesetTexId_].get(), &srcRect, &destRect, 0, nullptr, flip); | ||
| 65 | } | 78 | } |
| 66 | 79 | ||
| 67 | return canvas; | 80 | return canvas; |
| 68 | } | 81 | } |
| 69 | 82 | ||
| 70 | void Renderer::render(Game& game) { | 83 | void Renderer::render(Game& game) { |
| 71 | if (tilesetTexId_ == -1) { | ||
| 72 | tilesetTexId_ = loadImageFromFile(game.getMap()->getTileset("fromRom")->getImage().c_str()); | ||
| 73 | } | ||
| 74 | |||
| 75 | if (!renLay1_) { | 84 | if (!renLay1_) { |
| 76 | renLay1_ = renderMapLayer(*game.getMap()->getLayer("Layer 1")); | 85 | renLay1_ = renderMapLayer(game.getMap(), 0); |
| 77 | } | 86 | } |
| 78 | if (!renLay0_) { | 87 | if (!renLay0_) { |
| 79 | renLay0_ = renderMapLayer(*game.getMap()->getLayer("Layer 0")); | 88 | renLay0_ = renderMapLayer(game.getMap(), 1); |
| 80 | } | 89 | } |
| 81 | 90 | ||
| 82 | texture_ptr canvas( | 91 | texture_ptr canvas( |
| @@ -91,15 +100,15 @@ void Renderer::render(Game& game) { | |||
| 91 | throw sdl_error(); | 100 | throw sdl_error(); |
| 92 | } | 101 | } |
| 93 | 102 | ||
| 94 | |||
| 95 | |||
| 96 | SDL_SetRenderTarget(ren_.get(), canvas.get()); | 103 | SDL_SetRenderTarget(ren_.get(), canvas.get()); |
| 97 | SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_NONE); | 104 | SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_NONE); |
| 98 | SDL_SetRenderDrawColor(ren_.get(), 255, 255, 255, 255); | 105 | SDL_SetRenderDrawColor(ren_.get(), 255, 255, 255, 255); |
| 99 | SDL_RenderClear(ren_.get()); | 106 | SDL_RenderClear(ren_.get()); |
| 100 | 107 | ||
| 108 | vec2i mapBounds = game.getMap().getMapSize() * game.getMap().getTileSize(); | ||
| 109 | |||
| 101 | { | 110 | { |
| 102 | SDL_Rect dest { -80, -80, game.getMap()->getSize().x * game.getMap()->getTileSize().x, game.getMap()->getSize().y * game.getMap()->getTileSize().y }; | 111 | SDL_Rect dest { -80, -80, mapBounds.w(), mapBounds.h() }; |
| 103 | SDL_RenderCopy(ren_.get(), renLay1_.get(), nullptr, &dest); | 112 | SDL_RenderCopy(ren_.get(), renLay1_.get(), nullptr, &dest); |
| 104 | } | 113 | } |
| 105 | 114 | ||
| @@ -111,7 +120,7 @@ void Renderer::render(Game& game) { | |||
| 111 | } | 120 | } |
| 112 | 121 | ||
| 113 | { | 122 | { |
| 114 | SDL_Rect dest { -80, -80, game.getMap()->getSize().x * game.getMap()->getTileSize().x, game.getMap()->getSize().y * game.getMap()->getTileSize().y }; | 123 | SDL_Rect dest { -80, -80, mapBounds.w(), mapBounds.h() }; |
| 115 | SDL_RenderCopy(ren_.get(), renLay0_.get(), nullptr, &dest); | 124 | SDL_RenderCopy(ren_.get(), renLay0_.get(), nullptr, &dest); |
| 116 | } | 125 | } |
| 117 | 126 | ||
| diff --git a/src/renderer.h b/src/renderer.h index 9573d8c..f952ab3 100644 --- a/src/renderer.h +++ b/src/renderer.h | |||
| @@ -7,9 +7,9 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <string_view> | 8 | #include <string_view> |
| 9 | #include <vector> | 9 | #include <vector> |
| 10 | #include <tileson.hpp> | ||
| 11 | 10 | ||
| 12 | class Game; | 11 | class Game; |
| 12 | class Map; | ||
| 13 | 13 | ||
| 14 | class sdl_error : public std::logic_error { | 14 | class sdl_error : public std::logic_error { |
| 15 | public: | 15 | public: |
| @@ -122,7 +122,7 @@ public: | |||
| 122 | 122 | ||
| 123 | private: | 123 | private: |
| 124 | 124 | ||
| 125 | texture_ptr renderMapLayer(const tson::Layer& layer); | 125 | texture_ptr renderMapLayer(const Map& map, int layer); |
| 126 | 126 | ||
| 127 | sdl_wrapper sdl_; | 127 | sdl_wrapper sdl_; |
| 128 | img_wrapper img_; | 128 | img_wrapper img_; |
| @@ -130,7 +130,6 @@ private: | |||
| 130 | renderer_ptr ren_; | 130 | renderer_ptr ren_; |
| 131 | 131 | ||
| 132 | std::vector<texture_ptr> textures_; | 132 | std::vector<texture_ptr> textures_; |
| 133 | int tilesetTexId_ = -1; | ||
| 134 | texture_ptr renLay0_; | 133 | texture_ptr renLay0_; |
| 135 | texture_ptr renLay1_; | 134 | texture_ptr renLay1_; |
| 136 | }; | 135 | }; |
| diff --git a/src/vector.h b/src/vector.h index bf38bb2..d54fdbb 100644 --- a/src/vector.h +++ b/src/vector.h | |||
| @@ -91,6 +91,10 @@ public: | |||
| 91 | return *this; | 91 | return *this; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | vec2 operator*(const vec2& other) const { | ||
| 95 | return vec2(x() * other.x(), y() * other.y()); | ||
| 96 | } | ||
| 97 | |||
| 94 | bool operator==(const vec2& other) const { | 98 | bool operator==(const vec2& other) const { |
| 95 | return std::tie(x(), other.x()) == std::tie(y(), other.y()); | 99 | return std::tie(x(), other.x()) == std::tie(y(), other.y()); |
| 96 | } | 100 | } |
