summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/animation_system.cpp6
-rw-r--r--src/animation_system.h3
-rw-r--r--src/camera_system.cpp6
-rw-r--r--src/camera_system.h4
-rw-r--r--src/game.cpp60
-rw-r--r--src/game.h4
-rw-r--r--src/main.cpp43
-rw-r--r--src/map.cpp5
-rw-r--r--src/map.h12
-rw-r--r--src/renderer.cpp19
-rw-r--r--src/renderer.h3
-rw-r--r--src/script_system.cpp6
-rw-r--r--src/sprite.h2
-rw-r--r--src/system.h2
-rw-r--r--src/transform_system.cpp8
-rw-r--r--src/transform_system.h2
16 files changed, 119 insertions, 66 deletions
diff --git a/src/animation_system.cpp b/src/animation_system.cpp index cf34066..997b7f7 100644 --- a/src/animation_system.cpp +++ b/src/animation_system.cpp
@@ -6,7 +6,7 @@
6#include "vector.h" 6#include "vector.h"
7#include "util.h" 7#include "util.h"
8 8
9void AnimationSystem::initSprite(int spriteId, std::string_view filename, Renderer& renderer) { 9void AnimationSystem::initSprite(int spriteId, std::string_view filename) {
10 std::ifstream datafile(filename.data()); 10 std::ifstream datafile(filename.data());
11 if (!datafile.is_open()) { 11 if (!datafile.is_open()) {
12 throw std::invalid_argument(std::string("Could not find sprite datafile: ") + std::string(filename)); 12 throw std::invalid_argument(std::string("Could not find sprite datafile: ") + std::string(filename));
@@ -18,9 +18,7 @@ void AnimationSystem::initSprite(int spriteId, std::string_view filename, Render
18 char ch; 18 char ch;
19 std::string line; 19 std::string line;
20 20
21 std::string imagename; 21 datafile >> sprite.spritesheet;
22 datafile >> imagename;
23 sprite.textureId = renderer.loadImageFromFile(imagename);
24 22
25 std::string framefilename; 23 std::string framefilename;
26 datafile >> framefilename; 24 datafile >> framefilename;
diff --git a/src/animation_system.h b/src/animation_system.h index 2e13784..a116673 100644 --- a/src/animation_system.h +++ b/src/animation_system.h
@@ -7,7 +7,6 @@
7#include "timer.h" 7#include "timer.h"
8 8
9class Game; 9class Game;
10class Renderer;
11 10
12class AnimationSystem : public System { 11class AnimationSystem : public System {
13public: 12public:
@@ -18,7 +17,7 @@ public:
18 17
19 void tick(double dt) override; 18 void tick(double dt) override;
20 19
21 void initSprite(int spriteId, std::string_view filename, Renderer& renderer); 20 void initSprite(int spriteId, std::string_view filename);
22 21
23 void setSpriteDirection(int spriteId, Direction dir); 22 void setSpriteDirection(int spriteId, Direction dir);
24 23
diff --git a/src/camera_system.cpp b/src/camera_system.cpp index 4709d01..991d096 100644 --- a/src/camera_system.cpp +++ b/src/camera_system.cpp
@@ -4,7 +4,7 @@
4#include "map.h" 4#include "map.h"
5 5
6void CameraSystem::tick(double dt) { 6void CameraSystem::tick(double dt) {
7 if (!locked_) { 7 if (!locked_ && followingSprite_ != -1) {
8 const Sprite& follow = game_.getSprite(followingSprite_); 8 const Sprite& follow = game_.getSprite(followingSprite_);
9 const Map& map = game_.getMap(); 9 const Map& map = game_.getMap();
10 vec2i mapBounds = map.getMapSize() * map.getTileSize(); 10 vec2i mapBounds = map.getMapSize() * map.getTileSize();
@@ -25,3 +25,7 @@ void CameraSystem::tick(double dt) {
25 } 25 }
26 } 26 }
27} 27}
28
29void CameraSystem::clearSpriteCache() {
30 followingSprite_ = -1;
31}
diff --git a/src/camera_system.h b/src/camera_system.h index 3eb8374..77d813f 100644 --- a/src/camera_system.h +++ b/src/camera_system.h
@@ -26,12 +26,14 @@ public:
26 26
27 void tick(double dt) override; 27 void tick(double dt) override;
28 28
29 void clearSpriteCache() override;
30
29private: 31private:
30 Game& game_; 32 Game& game_;
31 33
32 vec2i pos_; 34 vec2i pos_;
33 vec2i fov_ { CANVAS_WIDTH, CANVAS_HEIGHT }; 35 vec2i fov_ { CANVAS_WIDTH, CANVAS_HEIGHT };
34 int followingSprite_; 36 int followingSprite_ = -1;
35 bool locked_ = true; 37 bool locked_ = true;
36}; 38};
37 39
diff --git a/src/game.cpp b/src/game.cpp index 447b62a..861e8ee 100644 --- a/src/game.cpp +++ b/src/game.cpp
@@ -1,4 +1,8 @@
1#include "game.h" 1#include "game.h"
2#include "transform_system.h"
3#include "animation_system.h"
4#include "character_system.h"
5#include "camera_system.h"
2 6
3int Game::emplaceSprite(std::string alias) { 7int Game::emplaceSprite(std::string alias) {
4 int id = sprites_.size(); 8 int id = sprites_.size();
@@ -7,3 +11,59 @@ int Game::emplaceSprite(std::string alias) {
7 spritesByAlias_[alias] = id; 11 spritesByAlias_[alias] = id;
8 return id; 12 return id;
9} 13}
14
15void Game::clearSprites() {
16 sprites_.clear();
17 spriteIds_.clear();
18 spritesByAlias_.clear();
19
20 for (std::unique_ptr<System>& system : systems_) {
21 system->clearSpriteCache();
22 }
23}
24
25void Game::loadMap(std::string filename, std::string warpPoint) {
26 clearSprites();
27
28 map_ = std::make_unique<Map>(filename);
29
30 int lucasSprite = emplaceSprite("lucas");
31 getSystem<TransformSystem>().initSprite(lucasSprite, map_->getWarpPoint(warpPoint));
32 getSystem<TransformSystem>().setUpCollision(lucasSprite, {-8, -8}, {12, 8}, true);
33 getSystem<AnimationSystem>().initSprite(lucasSprite, "../res/sprites/lucas_anim.txt");
34 getSprite(lucasSprite).controllable = true;
35 getSystem<CharacterSystem>().initSprite(lucasSprite);
36
37 int kumaSprite = emplaceSprite("kuma");
38 getSystem<TransformSystem>().initSprite(kumaSprite, {32, 32});
39 getSystem<AnimationSystem>().initSprite(kumaSprite, "../res/sprites/kuma_anim.txt");
40 getSystem<CharacterSystem>().addSpriteToParty(lucasSprite, kumaSprite);
41
42 int dusterSprite = emplaceSprite("duster");
43 getSystem<TransformSystem>().initSprite(dusterSprite, {32, 32});
44 getSystem<AnimationSystem>().initSprite(dusterSprite, "../res/sprites/duster_anim.txt");
45 getSystem<CharacterSystem>().addSpriteToParty(lucasSprite, dusterSprite);
46
47 int boneySprite = emplaceSprite("boney");
48 getSystem<TransformSystem>().initSprite(boneySprite, {32, 32});
49 getSystem<AnimationSystem>().initSprite(boneySprite, "../res/sprites/boney_anim.txt");
50 getSystem<CharacterSystem>().addSpriteToParty(lucasSprite, boneySprite);
51
52 for (const Prototype& p : map_->getPrototypes()) {
53 int spriteId = emplaceSprite(p.name);
54 getSystem<TransformSystem>().initSprite(spriteId, p.pos);
55 getSystem<TransformSystem>().setUpCollision(spriteId, p.collisionOffset, p.collisionSize, true);
56 getSystem<AnimationSystem>().initSprite(spriteId, p.animationFilename);
57 getSprite(spriteId).interactionScript = p.interactionScript;
58 }
59
60 for (const Trigger& t : map_->getTriggers()) {
61 int spriteId = emplaceSprite(t.name);
62 getSystem<TransformSystem>().initSprite(spriteId, t.pos);
63 getSystem<TransformSystem>().setUpCollision(spriteId, {0, 0}, t.size, false);
64 getSprite(spriteId).walkthroughScript = t.script;
65 }
66
67 getSystem<CameraSystem>().setFollowingSprite(lucasSprite);
68 getSystem<CameraSystem>().unlockCamera();
69}
diff --git a/src/game.h b/src/game.h index 87e23d3..8ea7576 100644 --- a/src/game.h +++ b/src/game.h
@@ -73,7 +73,7 @@ public:
73 }); 73 });
74 } 74 }
75 75
76 void setMap(std::unique_ptr<Map> map) { map_ = std::move(map); } 76 void loadMap(std::string filename, std::string warpPoint);
77 77
78 const Map& getMap() const { return *map_; } 78 const Map& getMap() const { return *map_; }
79 79
@@ -81,6 +81,8 @@ public:
81 81
82private: 82private:
83 83
84 void clearSprites();
85
84 Mixer mixer_; 86 Mixer mixer_;
85 bool shouldQuit_ = false; 87 bool shouldQuit_ = false;
86 88
diff --git a/src/main.cpp b/src/main.cpp index a350c8d..5f28408 100644 --- a/src/main.cpp +++ b/src/main.cpp
@@ -22,48 +22,7 @@ void loop(Renderer& renderer) {
22 game.emplaceSystem<MessageSystem>(); 22 game.emplaceSystem<MessageSystem>();
23 game.emplaceSystem<ScriptSystem>(); 23 game.emplaceSystem<ScriptSystem>();
24 24
25 auto map = std::make_unique<Map>("../res/maps/map1.tmx", renderer); 25 game.loadMap("../res/maps/map1.tmx", "spawn");
26 game.setMap(std::move(map));
27
28 int lucasSprite = game.emplaceSprite("lucas");
29 game.getSystem<TransformSystem>().initSprite(lucasSprite, game.getMap().getWarpPoint("spawn"));
30 game.getSystem<TransformSystem>().setUpCollision(lucasSprite, {-8, -8}, {12, 8}, true);
31 game.getSystem<AnimationSystem>().initSprite(lucasSprite, "../res/sprites/lucas_anim.txt", renderer);
32 game.getSprite(lucasSprite).controllable = true;
33 game.getSystem<CharacterSystem>().initSprite(lucasSprite);
34
35 int kumaSprite = game.emplaceSprite("kuma");
36 game.getSystem<TransformSystem>().initSprite(kumaSprite, {32, 32});
37 game.getSystem<AnimationSystem>().initSprite(kumaSprite, "../res/sprites/kuma_anim.txt", renderer);
38 game.getSystem<CharacterSystem>().addSpriteToParty(lucasSprite, kumaSprite);
39
40 int dusterSprite = game.emplaceSprite("duster");
41 game.getSystem<TransformSystem>().initSprite(dusterSprite, {32, 32});
42 game.getSystem<AnimationSystem>().initSprite(dusterSprite, "../res/sprites/duster_anim.txt", renderer);
43 game.getSystem<CharacterSystem>().addSpriteToParty(lucasSprite, dusterSprite);
44
45 int boneySprite = game.emplaceSprite("boney");
46 game.getSystem<TransformSystem>().initSprite(boneySprite, {32, 32});
47 game.getSystem<AnimationSystem>().initSprite(boneySprite, "../res/sprites/boney_anim.txt", renderer);
48 game.getSystem<CharacterSystem>().addSpriteToParty(lucasSprite, boneySprite);
49
50 for (const Prototype& p : game.getMap().getPrototypes()) {
51 int spriteId = game.emplaceSprite(p.name);
52 game.getSystem<TransformSystem>().initSprite(spriteId, p.pos);
53 game.getSystem<TransformSystem>().setUpCollision(spriteId, p.collisionOffset, p.collisionSize, true);
54 game.getSystem<AnimationSystem>().initSprite(spriteId, p.animationFilename, renderer);
55 game.getSprite(spriteId).interactionScript = p.interactionScript;
56 }
57
58 for (const Trigger& t : game.getMap().getTriggers()) {
59 int spriteId = game.emplaceSprite(t.name);
60 game.getSystem<TransformSystem>().initSprite(spriteId, t.pos);
61 game.getSystem<TransformSystem>().setUpCollision(spriteId, {0, 0}, t.size, false);
62 game.getSprite(spriteId).walkthroughScript = t.script;
63 }
64
65 game.getSystem<CameraSystem>().setFollowingSprite(lucasSprite);
66 game.getSystem<CameraSystem>().unlockCamera();
67 26
68 renderer.render(game); 27 renderer.render(game);
69 28
diff --git a/src/map.cpp b/src/map.cpp index b6f6755..99711c6 100644 --- a/src/map.cpp +++ b/src/map.cpp
@@ -4,9 +4,8 @@
4#include <tmxlite/Property.hpp> 4#include <tmxlite/Property.hpp>
5#include <tmxlite/TileLayer.hpp> 5#include <tmxlite/TileLayer.hpp>
6#include <tmxlite/Tileset.hpp> 6#include <tmxlite/Tileset.hpp>
7#include "renderer.h"
8 7
9Map::Map(std::string_view filename, Renderer& renderer) { 8Map::Map(std::string_view filename) : filename_(filename) {
10 tmx::Map mapfile; 9 tmx::Map mapfile;
11 if (!mapfile.load(filename.data())) { 10 if (!mapfile.load(filename.data())) {
12 throw std::invalid_argument("Could not find map file: " + std::string(filename)); 11 throw std::invalid_argument("Could not find map file: " + std::string(filename));
@@ -24,7 +23,7 @@ Map::Map(std::string_view filename, Renderer& renderer) {
24 // There should only be one tileset. 23 // There should only be one tileset.
25 const tmx::Tileset& tileset = mapfile.getTilesets()[0]; 24 const tmx::Tileset& tileset = mapfile.getTilesets()[0];
26 firstGID = tileset.getFirstGID(); 25 firstGID = tileset.getFirstGID();
27 tilesetTextureId_ = renderer.loadImageFromFile(tileset.getImagePath()); 26 tilesetFilename_ = tileset.getImagePath();
28 tilesetColumns_ = tileset.getColumnCount(); 27 tilesetColumns_ = tileset.getColumnCount();
29 28
30 for (const auto& layer : mapfile.getLayers()) { 29 for (const auto& layer : mapfile.getLayers()) {
diff --git a/src/map.h b/src/map.h index 4c5d6d4..adf9b80 100644 --- a/src/map.h +++ b/src/map.h
@@ -5,12 +5,9 @@
5#include <string> 5#include <string>
6#include <string_view> 6#include <string_view>
7#include <vector> 7#include <vector>
8#include "renderer.h"
9#include "vector.h" 8#include "vector.h"
10#include "step_type.h" 9#include "step_type.h"
11 10
12class Renderer;
13
14struct Tile { 11struct Tile {
15 unsigned int id = 0; 12 unsigned int id = 0;
16 bool flipHorizontal = false; 13 bool flipHorizontal = false;
@@ -38,7 +35,9 @@ struct Trigger {
38class Map { 35class Map {
39public: 36public:
40 37
41 Map(std::string_view filename, Renderer& renderer); 38 explicit Map(std::string_view filename);
39
40 const std::string& getName() const { return filename_; }
42 41
43 const vec2i& getMapSize() const { return mapSize_; } 42 const vec2i& getMapSize() const { return mapSize_; }
44 43
@@ -46,7 +45,7 @@ public:
46 45
47 const std::vector<std::vector<Tile>>& getLayers() const { return layers_; } 46 const std::vector<std::vector<Tile>>& getLayers() const { return layers_; }
48 47
49 int getTilesetTextureId() const { return tilesetTextureId_; } 48 const std::string& getTilesetFilename() const { return tilesetFilename_; }
50 49
51 int getTilesetColumns() const { return tilesetColumns_; } 50 int getTilesetColumns() const { return tilesetColumns_; }
52 51
@@ -62,10 +61,11 @@ public:
62 61
63private: 62private:
64 63
64 std::string filename_;
65 vec2i mapSize_; 65 vec2i mapSize_;
66 vec2i tileSize_; 66 vec2i tileSize_;
67 std::vector<std::vector<Tile>> layers_; 67 std::vector<std::vector<Tile>> layers_;
68 int tilesetTextureId_; 68 std::string tilesetFilename_;
69 int tilesetColumns_; 69 int tilesetColumns_;
70 std::vector<Prototype> prototypes_; 70 std::vector<Prototype> prototypes_;
71 std::map<std::string, vec2i> warpPoints_; 71 std::map<std::string, vec2i> warpPoints_;
diff --git a/src/renderer.cpp b/src/renderer.cpp index 87bbbcd..e9db413 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp
@@ -35,6 +35,16 @@ Renderer::Renderer() {
35} 35}
36 36
37texture_ptr Renderer::renderMapLayer(const Map& map, int layer) { 37texture_ptr Renderer::renderMapLayer(const Map& map, int layer) {
38 if (cachedTilesetName_ != map.getTilesetFilename()) {
39 surface_ptr pfs(IMG_Load(map.getTilesetFilename().c_str()));
40 if (!pfs) {
41 throw img_error();
42 }
43
44 tilesetTex_ = texture_ptr(SDL_CreateTextureFromSurface(ren_.get(), pfs.get()));
45 cachedTilesetName_ = map.getTilesetFilename();
46 }
47
38 vec2i mapBounds = map.getMapSize() * map.getTileSize(); 48 vec2i mapBounds = map.getMapSize() * map.getTileSize();
39 49
40 texture_ptr canvas( 50 texture_ptr canvas(
@@ -77,7 +87,7 @@ texture_ptr Renderer::renderMapLayer(const Map& map, int layer) {
77 } else if (tile.flipVertical) { 87 } else if (tile.flipVertical) {
78 flip = SDL_FLIP_VERTICAL; 88 flip = SDL_FLIP_VERTICAL;
79 } 89 }
80 SDL_RenderCopyEx(ren_.get(), textures_[map.getTilesetTextureId()].get(), &srcRect, &destRect, 0, nullptr, flip); 90 SDL_RenderCopyEx(ren_.get(), tilesetTex_.get(), &srcRect, &destRect, 0, nullptr, flip);
81 } 91 }
82 } 92 }
83 93
@@ -85,10 +95,9 @@ texture_ptr Renderer::renderMapLayer(const Map& map, int layer) {
85} 95}
86 96
87void Renderer::render(Game& game) { 97void Renderer::render(Game& game) {
88 if (!renLay1_) { 98 if (cachedMapName_ != game.getMap().getName()) {
99 cachedMapName_ = game.getMap().getName();
89 renLay1_ = renderMapLayer(game.getMap(), 0); 100 renLay1_ = renderMapLayer(game.getMap(), 0);
90 }
91 if (!renLay0_) {
92 renLay0_ = renderMapLayer(game.getMap(), 1); 101 renLay0_ = renderMapLayer(game.getMap(), 1);
93 } 102 }
94 103
@@ -118,7 +127,7 @@ void Renderer::render(Game& game) {
118 const SpriteFrame& frame = sprite.frames.at(sprite.animations.at(sprite.animationId).at(sprite.animationFrame)); 127 const SpriteFrame& frame = sprite.frames.at(sprite.animations.at(sprite.animationId).at(sprite.animationFrame));
119 const SDL_Rect& src = frame.srcRect; 128 const SDL_Rect& src = frame.srcRect;
120 SDL_Rect dest { sprite.loc.x() - frame.center.x(), sprite.loc.y() - frame.center.y(), frame.size.w(), frame.size.h() }; 129 SDL_Rect dest { sprite.loc.x() - frame.center.x(), sprite.loc.y() - frame.center.y(), frame.size.w(), frame.size.h() };
121 SDL_RenderCopy(ren_.get(), textures_.at(sprite.textureId).get(), &src, &dest); 130 SDL_RenderCopy(ren_.get(), textures_.at(loadImageFromFile(sprite.spritesheet)).get(), &src, &dest);
122 } 131 }
123 } 132 }
124 133
diff --git a/src/renderer.h b/src/renderer.h index 2d7f93b..6d512c2 100644 --- a/src/renderer.h +++ b/src/renderer.h
@@ -136,6 +136,9 @@ private:
136 // Map rendering 136 // Map rendering
137 texture_ptr renderMapLayer(const Map& map, int layer); 137 texture_ptr renderMapLayer(const Map& map, int layer);
138 138
139 std::string cachedMapName_;
140 std::string cachedTilesetName_;
141 texture_ptr tilesetTex_;
139 texture_ptr renLay0_; 142 texture_ptr renLay0_;
140 texture_ptr renLay1_; 143 texture_ptr renLay1_;
141 144
diff --git a/src/script_system.cpp b/src/script_system.cpp index e2b117a..6e38905 100644 --- a/src/script_system.cpp +++ b/src/script_system.cpp
@@ -50,6 +50,12 @@ ScriptSystem::ScriptSystem(Game& game) : game_(game) {
50 return game_.getSpriteByAlias(alias); 50 return game_.getSpriteByAlias(alias);
51 }); 51 });
52 52
53 engine_.set_function(
54 "loadMap",
55 [&] (std::string filename, std::string warpPoint) {
56 game_.loadMap(filename, warpPoint);
57 });
58
53 engine_.script_file("../res/scripts/common.lua"); 59 engine_.script_file("../res/scripts/common.lua");
54} 60}
55 61
diff --git a/src/sprite.h b/src/sprite.h index 4a65763..283fb65 100644 --- a/src/sprite.h +++ b/src/sprite.h
@@ -42,7 +42,7 @@ public:
42 42
43 // Animation 43 // Animation
44 bool isAnimated = false; 44 bool isAnimated = false;
45 int textureId; 45 std::string spritesheet;
46 Direction dir = Direction::down; 46 Direction dir = Direction::down;
47 std::string animationName = "still"; 47 std::string animationName = "still";
48 int animationId = 0; 48 int animationId = 0;
diff --git a/src/system.h b/src/system.h index 218dc60..93b903e 100644 --- a/src/system.h +++ b/src/system.h
@@ -15,6 +15,8 @@ class System {
15public: 15public:
16 16
17 virtual void tick(double dt) {} 17 virtual void tick(double dt) {}
18
19 virtual void clearSpriteCache() {}
18}; 20};
19 21
20#endif /* end of include guard: SYSTEM_H_6B40E1B9 */ 22#endif /* end of include guard: SYSTEM_H_6B40E1B9 */
diff --git a/src/transform_system.cpp b/src/transform_system.cpp index 2ec133e..8a09c20 100644 --- a/src/transform_system.cpp +++ b/src/transform_system.cpp
@@ -209,3 +209,11 @@ void TransformSystem::removeCollidable(int spriteId) {
209 upCollidables_.erase({ colDR.y(), spriteId }); 209 upCollidables_.erase({ colDR.y(), spriteId });
210 downCollidables_.erase({ colUL.y(), spriteId }); 210 downCollidables_.erase({ colUL.y(), spriteId });
211} 211}
212
213void TransformSystem::clearSpriteCache() {
214 spritesByY_.clear();
215 leftCollidables_.clear();
216 rightCollidables_.clear();
217 upCollidables_.clear();
218 downCollidables_.clear();
219}
diff --git a/src/transform_system.h b/src/transform_system.h index 10e33db..46b6877 100644 --- a/src/transform_system.h +++ b/src/transform_system.h
@@ -43,6 +43,8 @@ public:
43 43
44 CollisionResult checkCollision(int spriteId, vec2i newLoc, Direction dir); 44 CollisionResult checkCollision(int spriteId, vec2i newLoc, Direction dir);
45 45
46 void clearSpriteCache() override;
47
46private: 48private:
47 49
48 Game& game_; 50 Game& game_;