summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/direction.h10
-rw-r--r--src/map.cpp38
-rw-r--r--src/map.h3
-rw-r--r--src/party.cpp121
-rw-r--r--src/party.h2
-rw-r--r--src/vector.h8
6 files changed, 144 insertions, 38 deletions
diff --git a/src/direction.h b/src/direction.h index ebc0e46..a83a6f8 100644 --- a/src/direction.h +++ b/src/direction.h
@@ -41,4 +41,14 @@ inline vec2i unitVecInDirection(Direction dir) {
41 } 41 }
42} 42}
43 43
44inline bool dirHasDir(Direction value, Direction inner) {
45 switch (inner) {
46 case Direction::up: return value == Direction::up_left || value == Direction::up || value == Direction::up_right;
47 case Direction::down: return value == Direction::down_left || value == Direction::down || value == Direction::down_right;
48 case Direction::left: return value == Direction::up_left || value == Direction::left || value == Direction::down_left;
49 case Direction::right: return value == Direction::up_right || value == Direction::right || value == Direction::down_right;
50 default: return value == inner;
51 }
52}
53
44#endif /* end of include guard: DIRECTION_H_AB66A90E */ 54#endif /* end of include guard: DIRECTION_H_AB66A90E */
diff --git a/src/map.cpp b/src/map.cpp index a60cbba..7d9800d 100644 --- a/src/map.cpp +++ b/src/map.cpp
@@ -1,6 +1,7 @@
1#include "map.h" 1#include "map.h"
2#include <tmxlite/Map.hpp> 2#include <tmxlite/Map.hpp>
3#include <tmxlite/Layer.hpp> 3#include <tmxlite/Layer.hpp>
4#include <tmxlite/Property.hpp>
4#include <tmxlite/TileLayer.hpp> 5#include <tmxlite/TileLayer.hpp>
5#include <tmxlite/Tileset.hpp> 6#include <tmxlite/Tileset.hpp>
6#include "renderer.h" 7#include "renderer.h"
@@ -21,11 +22,10 @@ Map::Map(std::string_view filename, Renderer& renderer) {
21 22
22 int firstGID = 0; 23 int firstGID = 0;
23 // There should only be one tileset. 24 // There should only be one tileset.
24 for (const tmx::Tileset& tileset : mapfile.getTilesets()) { 25 const tmx::Tileset& tileset = mapfile.getTilesets()[0];
25 firstGID = tileset.getFirstGID(); 26 firstGID = tileset.getFirstGID();
26 tilesetTextureId_ = renderer.loadImageFromFile(tileset.getImagePath()); 27 tilesetTextureId_ = renderer.loadImageFromFile(tileset.getImagePath());
27 tilesetColumns_ = tileset.getColumnCount(); 28 tilesetColumns_ = tileset.getColumnCount();
28 }
29 29
30 for (const auto& layer : mapfile.getLayers()) { 30 for (const auto& layer : mapfile.getLayers()) {
31 if (layer->getType() == tmx::Layer::Type::Tile) { 31 if (layer->getType() == tmx::Layer::Type::Tile) {
@@ -34,13 +34,33 @@ Map::Map(std::string_view filename, Renderer& renderer) {
34 std::vector<Tile> tilesToStore; 34 std::vector<Tile> tilesToStore;
35 35
36 for (const auto& maptile : tileLayer.getTiles()) { 36 for (const auto& maptile : tileLayer.getTiles()) {
37 tilesToStore.push_back(Tile { 37 Tile tile;
38 .id = maptile.ID - firstGID, 38 tile.id = maptile.ID - firstGID;
39 .flipHorizontal = (maptile.flipFlags & tmx::TileLayer::Horizontal) != 0, 39 tile.flipHorizontal = (maptile.flipFlags & tmx::TileLayer::Horizontal) != 0;
40 .flipVertical = (maptile.flipFlags & tmx::TileLayer::Vertical) != 0 }); 40 tile.flipVertical = (maptile.flipFlags & tmx::TileLayer::Vertical) != 0;
41
42 for (const tmx::Property& property : tileset.getTile(maptile.ID)->properties) {
43 if (property.getName() == "solid" && property.getBoolValue()) {
44 tile.blocked = true;
45 }
46 }
47
48 tilesToStore.push_back(std::move(tile));
41 } 49 }
42 50
43 layers_.push_back(std::move(tilesToStore)); 51 layers_.push_back(std::move(tilesToStore));
44 } 52 }
45 } 53 }
46} 54}
55
56bool Map::isBlocked(int x, int y) const {
57 int i = x + y * mapSize_.w();
58
59 for (const std::vector<Tile>& layer : layers_) {
60 if (layer.at(i).blocked) {
61 return true;
62 }
63 }
64
65 return false;
66}
diff --git a/src/map.h b/src/map.h index 1031996..2f8ec1a 100644 --- a/src/map.h +++ b/src/map.h
@@ -12,6 +12,7 @@ struct Tile {
12 unsigned int id = 0; 12 unsigned int id = 0;
13 bool flipHorizontal = false; 13 bool flipHorizontal = false;
14 bool flipVertical = false; 14 bool flipVertical = false;
15 bool blocked = false;
15}; 16};
16 17
17class Map { 18class Map {
@@ -29,6 +30,8 @@ public:
29 30
30 int getTilesetColumns() const { return tilesetColumns_; } 31 int getTilesetColumns() const { return tilesetColumns_; }
31 32
33 bool isBlocked(int x, int y) const;
34
32private: 35private:
33 36
34 vec2i mapSize_; 37 vec2i mapSize_;
diff --git a/src/party.cpp b/src/party.cpp index 2af252f..307bca8 100644 --- a/src/party.cpp +++ b/src/party.cpp
@@ -1,5 +1,6 @@
1#include "party.h" 1#include "party.h"
2#include "consts.h" 2#include "consts.h"
3#include <iostream>
3 4
4void Party::addMember(Game& game, int spriteId) { 5void Party::addMember(Game& game, int spriteId) {
5 int index = members_.size(); 6 int index = members_.size();
@@ -93,41 +94,84 @@ void Party::move(Game& game, const Input& keystate) {
93 94
94 pLoc += (unitVecInDirection(dir) * speed); 95 pLoc += (unitVecInDirection(dir) * speed);
95 96
96 game.moveSprite(members_[0].spriteId, pLoc); 97 // Check collision.
98 const Map& map = game.getMap();
99 bool blocked = false;
100
101 const vec2i UL_COL_BOX = { 8, 8 };
102 const vec2i DR_COL_BOX = { 4, 0 };
103 vec2i oldColPosUL = (p1.loc() - UL_COL_BOX) / map.getTileSize();
104 vec2i newColPosUL = (pLoc - UL_COL_BOX) / map.getTileSize();
105 vec2i oldColPosDR = (p1.loc() + DR_COL_BOX) / map.getTileSize();
106 vec2i newColPosDR = (pLoc + DR_COL_BOX) / map.getTileSize();
107
108 if (dirHasDir(dir, Direction::right) &&
109 newColPosDR.x() > oldColPosDR.x()) {
110 for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) {
111 if (map.isBlocked(newColPosDR.x(), y)) {
112 blocked = true;
113 pLoc.x() = p1.loc().x();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
114 break;
115 }
116 }
117 }
97 118
98 for (int i = 1; i < members_.size(); i++) { 119 if (dirHasDir(dir, Direction::left) &&
99 const Sprite& pNext = game.getSprite(members_[i].spriteId); 120 newColPosUL.x() < oldColPosUL.x()) {
100 const Movement& posdir = members_[i].movement.front(); 121 for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) {
101 game.moveSprite(members_[i].spriteId, posdir.pos); 122 if (map.isBlocked(newColPosUL.x(), y)) {
102 game.setSpriteDirection(members_[i].spriteId, posdir.dir); 123 blocked = true;
124 pLoc.x() = p1.loc().x();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
125 break;
126 }
127 }
128 }
103 129
104 members_[i].movement.pop_front(); 130 if (dirHasDir(dir, Direction::down) &&
105 members_[i].movement.push_back({.pos = pLoc, .dir = dir}); 131 newColPosDR.y() > oldColPosDR.y()) {
132 for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) {
133 if (map.isBlocked(x, newColPosDR.y())) {
134 blocked = true;
135 pLoc.y() = p1.loc().y();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
136 break;
137 }
138 }
106 } 139 }
107}
108 140
109void Party::beginCrouch(Game& game) { 141 if (dirHasDir(dir, Direction::up) &&
110 if (state_ == State::Running) { 142 newColPosUL.y() < oldColPosUL.y()) {
111 state_ = State::Normal; 143 for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) {
144 if (map.isBlocked(x, newColPosUL.y())) {
145 blocked = true;
146 pLoc.y() = p1.loc().y();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
147 break;
148 }
149 }
150 }
151
152 if (blocked && state_ == State::Running) {
153 stopRunning(game);
154 }
155
156 // Move everything
157 if (pLoc != p1.loc()) {
158 game.moveSprite(members_[0].spriteId, pLoc);
112 159
113 // Double the movement buffer for the followers.
114 for (int i = 1; i < members_.size(); i++) { 160 for (int i = 1; i < members_.size(); i++) {
115 std::deque<Movement> newMove; 161 const Sprite& pNext = game.getSprite(members_[i].spriteId);
116 vec2i lastPos = game.getSprite(members_[i].spriteId).loc(); 162 const Movement& posdir = members_[i].movement.front();
117 163 game.moveSprite(members_[i].spriteId, posdir.pos);
118 while (!members_[i].movement.empty()) { 164 game.setSpriteDirection(members_[i].spriteId, posdir.dir);
119 Movement m1 = members_[i].movement.front();
120 Movement m2 = m1;
121 m1.pos = (m1.pos + lastPos) / 2;
122 lastPos = m2.pos;
123
124 newMove.push_back(m1);
125 newMove.push_back(m2);
126 members_[i].movement.pop_front();
127 }
128 165
129 members_[i].movement = std::move(newMove); 166 members_[i].movement.pop_front();
167 members_[i].movement.push_back({.pos = pLoc, .dir = dir});
130 } 168 }
169 }
170}
171
172void Party::beginCrouch(Game& game) {
173 if (state_ == State::Running) {
174 stopRunning(game);
131 } else { 175 } else {
132 state_ = State::Crouching; 176 state_ = State::Crouching;
133 177
@@ -159,3 +203,26 @@ void Party::endCrouch(Game& game) {
159 } 203 }
160 } 204 }
161} 205}
206
207void Party::stopRunning(Game& game) {
208 state_ = State::Normal;
209
210 // Double the movement buffer for the followers.
211 for (int i = 1; i < members_.size(); i++) {
212 std::deque<Movement> newMove;
213 vec2i lastPos = game.getSprite(members_[i].spriteId).loc();
214
215 while (!members_[i].movement.empty()) {
216 Movement m1 = members_[i].movement.front();
217 Movement m2 = m1;
218 m1.pos = (m1.pos + lastPos) / 2;
219 lastPos = m2.pos;
220
221 newMove.push_back(m1);
222 newMove.push_back(m2);
223 members_[i].movement.pop_front();
224 }
225
226 members_[i].movement = std::move(newMove);
227 }
228}
diff --git a/src/party.h b/src/party.h index 06f8639..2864073 100644 --- a/src/party.h +++ b/src/party.h
@@ -18,6 +18,8 @@ public:
18 18
19private: 19private:
20 20
21 void stopRunning(Game& game);
22
21 enum class State { 23 enum class State {
22 Normal, 24 Normal,
23 Crouching, 25 Crouching,
diff --git a/src/vector.h b/src/vector.h index 8019edf..9f6d54f 100644 --- a/src/vector.h +++ b/src/vector.h
@@ -97,12 +97,16 @@ public:
97 return vec2(x() * other.x(), y() * other.y()); 97 return vec2(x() * other.x(), y() * other.y());
98 } 98 }
99 99
100 vec2 operator/(const vec2& other) const {
101 return vec2(x() / other.x(), y() / other.y());
102 }
103
100 bool operator==(const vec2& other) const { 104 bool operator==(const vec2& other) const {
101 return std::tie(x(), other.x()) == std::tie(y(), other.y()); 105 return (x() == other.x()) && (y() == other.y());
102 } 106 }
103 107
104 bool operator!=(const vec2& other) const { 108 bool operator!=(const vec2& other) const {
105 return std::tie(x(), other.x()) != std::tie(y(), other.y()); 109 return (x() != other.x()) || (y() != other.y());
106 } 110 }
107 111
108}; 112};