From a475b843e7d37f128ce30140d193f0312aa70c9c Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Tue, 2 Feb 2021 15:36:09 -0500 Subject: Using tmxlite instead of Tileson --- src/game.h | 12 +++++----- src/main.cpp | 5 ++++- src/map.cpp | 46 ++++++++++++++++++++++++++++++++++++++ src/map.h | 41 ++++++++++++++++++++++++++++++++++ src/renderer.cpp | 67 ++++++++++++++++++++++++++++++++------------------------ src/renderer.h | 5 ++--- src/vector.h | 4 ++++ 7 files changed, 140 insertions(+), 40 deletions(-) create mode 100644 src/map.cpp create mode 100644 src/map.h (limited to 'src') 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 @@ #include #include #include -#include +#include #include "sprite.h" +#include "map.h" struct Input { bool left = false; @@ -55,18 +56,15 @@ public: } } - void loadMapFromFile(std::string_view filename) { - tson::Tileson t; - map_ = t.parse(fs::path(filename)); - } + void setMap(std::unique_ptr map) { map_ = std::move(map); } - tson::Map* getMap() const { return map_.get(); } + const Map& getMap() const { return *map_; } private: std::vector sprites_; std::set> spritesByY_; - std::unique_ptr map_; + std::unique_ptr map_; }; #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 @@ #include +#include #include "renderer.h" #include "game.h" #include "party.h" #include "timer.h" +#include "map.h" void loop(Renderer& renderer) { Game game; Input keystate; - game.loadMapFromFile("../res/map1.json"); + auto map = std::make_unique("../res/map1.tmx", renderer); + game.setMap(std::move(map)); int lucasSprite = game.addSprite(Sprite("../res/lucas_anim.txt", renderer)); 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 @@ +#include "map.h" +#include +#include +#include +#include +#include "renderer.h" + +Map::Map(std::string_view filename, Renderer& renderer) { + tmx::Map mapfile; + if (!mapfile.load(filename.data())) { + throw std::invalid_argument("Could not find map file: " + std::string(filename)); + } + + const tmx::Vector2u& mapSize = mapfile.getTileCount(); + mapSize_.x() = mapSize.x; + mapSize_.y() = mapSize.y; + + const tmx::Vector2u& tileSize = mapfile.getTileSize(); + tileSize_.x() = tileSize.x; + tileSize_.y() = tileSize.y; + + int firstGID = 0; + // There should only be one tileset. + for (const tmx::Tileset& tileset : mapfile.getTilesets()) { + firstGID = tileset.getFirstGID(); + tilesetTextureId_ = renderer.loadImageFromFile(tileset.getImagePath()); + tilesetColumns_ = tileset.getColumnCount(); + } + + for (const auto& layer : mapfile.getLayers()) { + if (layer->getType() == tmx::Layer::Type::Tile) { + const auto& tileLayer = layer->getLayerAs(); + + std::vector tilesToStore; + + for (const auto& maptile : tileLayer.getTiles()) { + tilesToStore.push_back(Tile { + .id = maptile.ID - firstGID, + .flipHorizontal = (maptile.flipFlags & tmx::TileLayer::Horizontal) != 0, + .flipVertical = (maptile.flipFlags & tmx::TileLayer::Vertical) != 0 }); + } + + layers_.push_back(std::move(tilesToStore)); + } + } +} 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 @@ +#ifndef MAP_H_D95D6D47 +#define MAP_H_D95D6D47 + +#include +#include +#include "renderer.h" +#include "vector.h" + +class Renderer; + +struct Tile { + unsigned int id = 0; + bool flipHorizontal = false; + bool flipVertical = false; +}; + +class Map { +public: + + Map(std::string_view filename, Renderer& renderer); + + const vec2i& getMapSize() const { return mapSize_; } + + const vec2i& getTileSize() const { return tileSize_; } + + const std::vector>& getLayers() const { return layers_; } + + int getTilesetTextureId() const { return tilesetTextureId_; } + + int getTilesetColumns() const { return tilesetColumns_; } + +private: + + vec2i mapSize_; + vec2i tileSize_; + std::vector> layers_; + int tilesetTextureId_; + int tilesetColumns_; +}; + +#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 @@ #include "renderer.h" #include "consts.h" #include "game.h" +#include "map.h" Renderer::Renderer() { win_ = window_ptr( @@ -29,14 +30,16 @@ Renderer::Renderer() { } } -texture_ptr Renderer::renderMapLayer(const tson::Layer& layer) { +texture_ptr Renderer::renderMapLayer(const Map& map, int layer) { + vec2i mapBounds = map.getMapSize() * map.getTileSize(); + texture_ptr canvas( SDL_CreateTexture( ren_.get(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, - layer.getMap()->getSize().x * layer.getMap()->getTileSize().x, - layer.getMap()->getSize().y * layer.getMap()->getTileSize().y)); + mapBounds.w(), + mapBounds.h())); SDL_SetTextureBlendMode(canvas.get(), SDL_BLENDMODE_BLEND); @@ -45,38 +48,44 @@ texture_ptr Renderer::renderMapLayer(const tson::Layer& layer) { SDL_SetRenderDrawColor(ren_.get(), 255, 255, 255, 0); SDL_RenderClear(ren_.get()); - for (auto& [pos, tileObject] : layer.getTileObjects()) { - int x = tileObject.getPosition().x; - int y = tileObject.getPosition().y; - tson::Rect tileDestRect = tileObject.getDrawingRect(); - SDL_Rect srcRect { tileDestRect.x, tileDestRect.y, tileDestRect.width, tileDestRect.height }; - SDL_Rect destRect { - x, y, tileObject.getTile()->getTileSize().x, tileObject.getTile()->getTileSize().y }; - - SDL_RendererFlip flip = SDL_FLIP_NONE; - if (tileObject.getTile()->hasFlipFlags(tson::TileFlipFlags::Horizontally | tson::TileFlipFlags::Vertically)) { - flip = static_cast(SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL); - } else if (tileObject.getTile()->hasFlipFlags(tson::TileFlipFlags::Horizontally)) { - flip = SDL_FLIP_HORIZONTAL; - } else if (tileObject.getTile()->hasFlipFlags(tson::TileFlipFlags::Vertically)) { - flip = SDL_FLIP_VERTICAL; + const std::vector& tiles = map.getLayers().at(layer); + for (int y = 0; y < map.getMapSize().h(); y++) { + for (int x = 0; x < map.getMapSize().w(); x++) { + const Tile& tile = tiles.at(x + y * map.getMapSize().w()); + + SDL_Rect srcRect { + static_cast((tile.id % map.getTilesetColumns()) * map.getTileSize().w()), + static_cast((tile.id / map.getTilesetColumns()) * map.getTileSize().h()), + map.getTileSize().w(), + map.getTileSize().h() }; + + SDL_Rect destRect { + x * map.getTileSize().w(), + y * map.getTileSize().h(), + map.getTileSize().w(), + map.getTileSize().h() }; + + SDL_RendererFlip flip = SDL_FLIP_NONE; + if (tile.flipHorizontal && tile.flipVertical) { + flip = static_cast(SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL); + } else if (tile.flipHorizontal) { + flip = SDL_FLIP_HORIZONTAL; + } else if (tile.flipVertical) { + flip = SDL_FLIP_VERTICAL; + } + SDL_RenderCopyEx(ren_.get(), textures_[map.getTilesetTextureId()].get(), &srcRect, &destRect, 0, nullptr, flip); } - SDL_RenderCopyEx(ren_.get(), textures_[tilesetTexId_].get(), &srcRect, &destRect, 0, nullptr, flip); } return canvas; } void Renderer::render(Game& game) { - if (tilesetTexId_ == -1) { - tilesetTexId_ = loadImageFromFile(game.getMap()->getTileset("fromRom")->getImage().c_str()); - } - if (!renLay1_) { - renLay1_ = renderMapLayer(*game.getMap()->getLayer("Layer 1")); + renLay1_ = renderMapLayer(game.getMap(), 0); } if (!renLay0_) { - renLay0_ = renderMapLayer(*game.getMap()->getLayer("Layer 0")); + renLay0_ = renderMapLayer(game.getMap(), 1); } texture_ptr canvas( @@ -91,15 +100,15 @@ void Renderer::render(Game& game) { throw sdl_error(); } - - SDL_SetRenderTarget(ren_.get(), canvas.get()); SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_NONE); SDL_SetRenderDrawColor(ren_.get(), 255, 255, 255, 255); SDL_RenderClear(ren_.get()); + vec2i mapBounds = game.getMap().getMapSize() * game.getMap().getTileSize(); + { - SDL_Rect dest { -80, -80, game.getMap()->getSize().x * game.getMap()->getTileSize().x, game.getMap()->getSize().y * game.getMap()->getTileSize().y }; + SDL_Rect dest { -80, -80, mapBounds.w(), mapBounds.h() }; SDL_RenderCopy(ren_.get(), renLay1_.get(), nullptr, &dest); } @@ -111,7 +120,7 @@ void Renderer::render(Game& game) { } { - SDL_Rect dest { -80, -80, game.getMap()->getSize().x * game.getMap()->getTileSize().x, game.getMap()->getSize().y * game.getMap()->getTileSize().y }; + SDL_Rect dest { -80, -80, mapBounds.w(), mapBounds.h() }; SDL_RenderCopy(ren_.get(), renLay0_.get(), nullptr, &dest); } 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 @@ #include #include #include -#include class Game; +class Map; class sdl_error : public std::logic_error { public: @@ -122,7 +122,7 @@ public: private: - texture_ptr renderMapLayer(const tson::Layer& layer); + texture_ptr renderMapLayer(const Map& map, int layer); sdl_wrapper sdl_; img_wrapper img_; @@ -130,7 +130,6 @@ private: renderer_ptr ren_; std::vector textures_; - int tilesetTexId_ = -1; texture_ptr renLay0_; texture_ptr renLay1_; }; 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: return *this; } + vec2 operator*(const vec2& other) const { + return vec2(x() * other.x(), y() * other.y()); + } + bool operator==(const vec2& other) const { return std::tie(x(), other.x()) == std::tie(y(), other.y()); } -- cgit 1.4.1