summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game.h12
-rw-r--r--src/main.cpp5
-rw-r--r--src/map.cpp46
-rw-r--r--src/map.h41
-rw-r--r--src/renderer.cpp67
-rw-r--r--src/renderer.h5
-rw-r--r--src/vector.h4
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
10struct Input { 11struct 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
65private: 63private:
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
7void loop(Renderer& renderer) { 9void 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
8Map::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
9class Renderer;
10
11struct Tile {
12 unsigned int id = 0;
13 bool flipHorizontal = false;
14 bool flipVertical = false;
15};
16
17class Map {
18public:
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
32private:
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
5Renderer::Renderer() { 6Renderer::Renderer() {
6 win_ = window_ptr( 7 win_ = window_ptr(
@@ -29,14 +30,16 @@ Renderer::Renderer() {
29 } 30 }
30} 31}
31 32
32texture_ptr Renderer::renderMapLayer(const tson::Layer& layer) { 33texture_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
70void Renderer::render(Game& game) { 83void 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
12class Game; 11class Game;
12class Map;
13 13
14class sdl_error : public std::logic_error { 14class sdl_error : public std::logic_error {
15public: 15public:
@@ -122,7 +122,7 @@ public:
122 122
123private: 123private:
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 }