summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2018-05-08 21:09:36 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2018-05-09 17:59:13 -0400
commit5c82f052c26303318e81ddd76475c1d188cc74f4 (patch)
tree3204ef94f2861224a380aa566728c02b4acd1fd9 /src
parent96e6f3231aed9919d660a06944f1d96dc8241f8e (diff)
downloadtherapy-5c82f052c26303318e81ddd76475c1d188cc74f4.tar.gz
therapy-5c82f052c26303318e81ddd76475c1d188cc74f4.tar.bz2
therapy-5c82f052c26303318e81ddd76475c1d188cc74f4.zip
Simplified positions/sizes with vectors
Positions and sizes are now stored as vectors (of doubles and ints, respectively). This allows for at least minor code simplification in many places, and cleans up the CollisionParams code in PonderingSystem quite a bit.
Diffstat (limited to 'src')
-rw-r--r--src/components/automatable.h4
-rw-r--r--src/components/playable.h4
-rw-r--r--src/components/ponderable.h10
-rw-r--r--src/components/realizable.h4
-rw-r--r--src/components/transformable.h13
-rw-r--r--src/systems/animating.cpp8
-rw-r--r--src/systems/automating.cpp3
-rw-r--r--src/systems/orienting.cpp14
-rw-r--r--src/systems/playing.cpp19
-rw-r--r--src/systems/playing.h4
-rw-r--r--src/systems/pondering.cpp294
-rw-r--r--src/systems/pondering.h34
-rw-r--r--src/systems/realizing.cpp38
-rw-r--r--src/vector.h111
14 files changed, 285 insertions, 275 deletions
diff --git a/src/components/automatable.h b/src/components/automatable.h index b37945f..c1fd1a3 100644 --- a/src/components/automatable.h +++ b/src/components/automatable.h
@@ -4,6 +4,7 @@
4#include "component.h" 4#include "component.h"
5#include <vector> 5#include <vector>
6#include <random> 6#include <random>
7#include "vector.h"
7 8
8class AutomatableComponent : public Component { 9class AutomatableComponent : public Component {
9public: 10public:
@@ -18,8 +19,7 @@ public:
18 * The horizontal and vertical speed, in pixels/sec, that the entity should 19 * The horizontal and vertical speed, in pixels/sec, that the entity should
19 * move at. 20 * move at.
20 */ 21 */
21 double speedX; 22 vec2d speed;
22 double speedY;
23 23
24 /** 24 /**
25 * The duration of the action in seconds. 25 * The duration of the action in seconds.
diff --git a/src/components/playable.h b/src/components/playable.h index 94d4326..b8af0f2 100644 --- a/src/components/playable.h +++ b/src/components/playable.h
@@ -3,6 +3,7 @@
3 3
4#include "component.h" 4#include "component.h"
5#include "entity_manager.h" 5#include "entity_manager.h"
6#include "vector.h"
6 7
7class PlayableComponent : public Component { 8class PlayableComponent : public Component {
8public: 9public:
@@ -24,8 +25,7 @@ public:
24 * @managed_by PlayingSystem 25 * @managed_by PlayingSystem
25 */ 26 */
26 size_t checkpointMapId; 27 size_t checkpointMapId;
27 double checkpointX; 28 vec2d checkpointPos;
28 double checkpointY;
29 29
30}; 30};
31 31
diff --git a/src/components/ponderable.h b/src/components/ponderable.h index eff20e9..c0312b4 100644 --- a/src/components/ponderable.h +++ b/src/components/ponderable.h
@@ -4,6 +4,7 @@
4#include <set> 4#include <set>
5#include "component.h" 5#include "component.h"
6#include "entity_manager.h" 6#include "entity_manager.h"
7#include "vector.h"
7 8
8class PonderableComponent : public Component { 9class PonderableComponent : public Component {
9public: 10public:
@@ -45,14 +46,12 @@ public:
45 /** 46 /**
46 * The velocity of the body. 47 * The velocity of the body.
47 */ 48 */
48 double velX = 0.0; 49 vec2d vel = { 0.0, 0.0 };
49 double velY = 0.0;
50 50
51 /** 51 /**
52 * The acceleration of the body. 52 * The acceleration of the body.
53 */ 53 */
54 double accelX = 0.0; 54 vec2d accel = { 0.0, 0.0 };
55 double accelY = 0.0;
56 55
57 /** 56 /**
58 * The type of physical body that the entity is meant to assume. The body will 57 * The type of physical body that the entity is meant to assume. The body will
@@ -89,8 +88,7 @@ public:
89 * 88 *
90 * @managed_by PonderingSystem 89 * @managed_by PonderingSystem
91 */ 90 */
92 double relX; 91 vec2d rel = { 0.0, 0.0 };
93 double relY;
94 92
95 /** 93 /**
96 * The bodies that are being ferried by this body. 94 * The bodies that are being ferried by this body.
diff --git a/src/components/realizable.h b/src/components/realizable.h index 0858e7a..b749aeb 100644 --- a/src/components/realizable.h +++ b/src/components/realizable.h
@@ -5,6 +5,7 @@
5#include <set> 5#include <set>
6#include <map> 6#include <map>
7#include "entity_manager.h" 7#include "entity_manager.h"
8#include "vector.h"
8 9
9class RealizableComponent : public Component { 10class RealizableComponent : public Component {
10public: 11public:
@@ -31,8 +32,7 @@ public:
31 * @managed_by RealizingSystem 32 * @managed_by RealizingSystem
32 */ 33 */
33 int startingMapId; 34 int startingMapId;
34 int startingX; 35 vec2i startingPos;
35 int startingY;
36 36
37 /** 37 /**
38 * The set of map entities loaded by this entity. It is only intended for 38 * The set of map entities loaded by this entity. It is only intended for
diff --git a/src/components/transformable.h b/src/components/transformable.h index 6f3c2ef..bb21996 100644 --- a/src/components/transformable.h +++ b/src/components/transformable.h
@@ -2,6 +2,7 @@
2#define LOCATABLE_H_39E526CA 2#define LOCATABLE_H_39E526CA
3 3
4#include "component.h" 4#include "component.h"
5#include "vector.h"
5 6
6class TransformableComponent : public Component { 7class TransformableComponent : public Component {
7public: 8public:
@@ -15,24 +16,20 @@ public:
15 * so, use PonderingSystem::unferry on the body to ensure that it is not 16 * so, use PonderingSystem::unferry on the body to ensure that it is not
16 * ferried. 17 * ferried.
17 */ 18 */
18 double x; 19 vec2d pos;
19 double y;
20 20
21 /** 21 /**
22 * The size of the entity. 22 * The size of the entity.
23 */ 23 */
24 int w; 24 vec2i size;
25 int h;
26 25
27 /** 26 /**
28 * For prototypes, the original coordinates and size of the entity. 27 * For prototypes, the original coordinates and size of the entity.
29 * 28 *
30 * @managed_by RealizingSystem 29 * @managed_by RealizingSystem
31 */ 30 */
32 double origX; 31 vec2d origPos;
33 double origY; 32 vec2i origSize;
34 int origW;
35 int origH;
36}; 33};
37 34
38#endif /* end of include guard: LOCATABLE_H_39E526CA */ 35#endif /* end of include guard: LOCATABLE_H_39E526CA */
diff --git a/src/systems/animating.cpp b/src/systems/animating.cpp index 8543ba2..50a32fc 100644 --- a/src/systems/animating.cpp +++ b/src/systems/animating.cpp
@@ -64,10 +64,10 @@ void AnimatingSystem::render(Texture& texture)
64 } 64 }
65 65
66 Rectangle dstrect { 66 Rectangle dstrect {
67 static_cast<int>(transform.x), 67 static_cast<int>(transform.pos.x()),
68 static_cast<int>(transform.y), 68 static_cast<int>(transform.pos.y()),
69 transform.w, 69 transform.size.w(),
70 transform.h}; 70 transform.size.h()};
71 71
72 const AnimationSet& aset = sprite.animationSet; 72 const AnimationSet& aset = sprite.animationSet;
73 game_.getRenderer().blit( 73 game_.getRenderer().blit(
diff --git a/src/systems/automating.cpp b/src/systems/automating.cpp index 0d85957..61b97d9 100644 --- a/src/systems/automating.cpp +++ b/src/systems/automating.cpp
@@ -54,8 +54,7 @@ void AutomatingSystem::tick(double dt)
54 auto& ponderable = game_.getEntityManager(). 54 auto& ponderable = game_.getEntityManager().
55 getComponent<PonderableComponent>(entity); 55 getComponent<PonderableComponent>(entity);
56 56
57 ponderable.velX = curAction.speedX; 57 ponderable.vel = curAction.speed;
58 ponderable.velY = curAction.speedY;
59 58
60 automatable.remaining -= dt; 59 automatable.remaining -= dt;
61 } 60 }
diff --git a/src/systems/orienting.cpp b/src/systems/orienting.cpp index 206ebf6..d73ddd2 100644 --- a/src/systems/orienting.cpp +++ b/src/systems/orienting.cpp
@@ -24,27 +24,27 @@ void OrientingSystem::tick(double)
24 { 24 {
25 case OrientableComponent::WalkState::still: 25 case OrientableComponent::WalkState::still:
26 { 26 {
27 ponderable.velX = 0.0; 27 ponderable.vel.x() = 0.0;
28 28
29 break; 29 break;
30 } 30 }
31 31
32 case OrientableComponent::WalkState::left: 32 case OrientableComponent::WalkState::left:
33 { 33 {
34 ponderable.velX = -WALK_SPEED; 34 ponderable.vel.x() = -WALK_SPEED;
35 35
36 break; 36 break;
37 } 37 }
38 38
39 case OrientableComponent::WalkState::right: 39 case OrientableComponent::WalkState::right:
40 { 40 {
41 ponderable.velX = WALK_SPEED; 41 ponderable.vel.x() = WALK_SPEED;
42 42
43 break; 43 break;
44 } 44 }
45 } 45 }
46 46
47 if (orientable.isJumping() && (ponderable.velY > 0)) 47 if (orientable.isJumping() && (ponderable.vel.y() > 0))
48 { 48 {
49 orientable.setJumping(false); 49 orientable.setJumping(false);
50 } 50 }
@@ -122,8 +122,8 @@ void OrientingSystem::jump(id_type entity)
122 122
123 playSound("res/Randomize87.wav", 0.25); 123 playSound("res/Randomize87.wav", 0.25);
124 124
125 ponderable.velY = JUMP_VELOCITY; 125 ponderable.vel.y() = JUMP_VELOCITY;
126 ponderable.accelY = JUMP_GRAVITY; 126 ponderable.accel.y() = JUMP_GRAVITY;
127 127
128 auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>(); 128 auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>();
129 if (orientable.isFacingRight()) 129 if (orientable.isFacingRight())
@@ -147,7 +147,7 @@ void OrientingSystem::stopJumping(id_type entity)
147 auto& ponderable = game_.getEntityManager(). 147 auto& ponderable = game_.getEntityManager().
148 getComponent<PonderableComponent>(entity); 148 getComponent<PonderableComponent>(entity);
149 149
150 ponderable.accelY = NORMAL_GRAVITY; 150 ponderable.accel.y() = NORMAL_GRAVITY;
151 } 151 }
152} 152}
153 153
diff --git a/src/systems/playing.cpp b/src/systems/playing.cpp index acec4e7..dabc9a5 100644 --- a/src/systems/playing.cpp +++ b/src/systems/playing.cpp
@@ -42,10 +42,9 @@ void PlayingSystem::initPlayer()
42 auto& transformable = game_.getEntityManager(). 42 auto& transformable = game_.getEntityManager().
43 emplaceComponent<TransformableComponent>(player); 43 emplaceComponent<TransformableComponent>(player);
44 44
45 transformable.x = realizable.startingX; 45 transformable.pos = realizable.startingPos;
46 transformable.y = realizable.startingY; 46 transformable.size.w() = 10;
47 transformable.w = 10; 47 transformable.size.h() = 12;
48 transformable.h = 12;
49 48
50 game_.getSystemManager().getSystem<PonderingSystem>().initializeBody( 49 game_.getSystemManager().getSystem<PonderingSystem>().initializeBody(
51 player, 50 player,
@@ -59,8 +58,7 @@ void PlayingSystem::initPlayer()
59 58
60 playable.mapId = realizable.activeMap; 59 playable.mapId = realizable.activeMap;
61 playable.checkpointMapId = realizable.startingMapId; 60 playable.checkpointMapId = realizable.startingMapId;
62 playable.checkpointX = realizable.startingX; 61 playable.checkpointPos = realizable.startingPos;
63 playable.checkpointY = realizable.startingY;
64 62
65 realizing.enterActiveMap(player); 63 realizing.enterActiveMap(player);
66 64
@@ -70,8 +68,7 @@ void PlayingSystem::initPlayer()
70void PlayingSystem::changeMap( 68void PlayingSystem::changeMap(
71 id_type player, 69 id_type player,
72 size_t mapId, 70 size_t mapId,
73 double x, 71 vec2d warpPos)
74 double y)
75{ 72{
76 auto& playable = game_.getEntityManager(). 73 auto& playable = game_.getEntityManager().
77 getComponent<PlayableComponent>(player); 74 getComponent<PlayableComponent>(player);
@@ -103,8 +100,7 @@ void PlayingSystem::changeMap(
103 100
104 pondering.unferry(player); 101 pondering.unferry(player);
105 102
106 transformable.x = x; 103 transformable.pos = warpPos;
107 transformable.y = y;
108 104
109 if (realizable.activePlayer == player) 105 if (realizable.activePlayer == player)
110 { 106 {
@@ -139,8 +135,7 @@ void PlayingSystem::die(id_type player)
139 changeMap( 135 changeMap(
140 player, 136 player,
141 playable.checkpointMapId, 137 playable.checkpointMapId,
142 playable.checkpointX, 138 playable.checkpointPos);
143 playable.checkpointY);
144 139
145 animatable.frozen = false; 140 animatable.frozen = false;
146 animatable.flickering = false; 141 animatable.flickering = false;
diff --git a/src/systems/playing.h b/src/systems/playing.h index 9ba403b..31f79ab 100644 --- a/src/systems/playing.h +++ b/src/systems/playing.h
@@ -2,6 +2,7 @@
2#define PLAYING_H_70A54F7D 2#define PLAYING_H_70A54F7D
3 3
4#include "system.h" 4#include "system.h"
5#include "vector.h"
5 6
6class PlayingSystem : public System { 7class PlayingSystem : public System {
7public: 8public:
@@ -15,8 +16,7 @@ public:
15 void changeMap( 16 void changeMap(
16 id_type player, 17 id_type player,
17 size_t mapId, 18 size_t mapId,
18 double x, 19 vec2d warpPos);
19 double y);
20 20
21 void die(id_type player); 21 void die(id_type player);
22 22
diff --git a/src/systems/pondering.cpp b/src/systems/pondering.cpp index 7b3ab2d..ec83270 100644 --- a/src/systems/pondering.cpp +++ b/src/systems/pondering.cpp
@@ -47,7 +47,7 @@ void PonderingSystem::initializeBody(
47 47
48 if (type == PonderableComponent::Type::freefalling) 48 if (type == PonderableComponent::Type::freefalling)
49 { 49 {
50 ponderable.accelY = NORMAL_GRAVITY; 50 ponderable.accel.y() = NORMAL_GRAVITY;
51 } 51 }
52} 52}
53 53
@@ -56,10 +56,10 @@ void PonderingSystem::initPrototype(id_type prototype)
56 auto& ponderable = game_.getEntityManager(). 56 auto& ponderable = game_.getEntityManager().
57 getComponent<PonderableComponent>(prototype); 57 getComponent<PonderableComponent>(prototype);
58 58
59 ponderable.velX = 0.0; 59 ponderable.vel.x() = 0.0;
60 ponderable.velY = 0.0; 60 ponderable.vel.y() = 0.0;
61 ponderable.accelX = 0.0; 61 ponderable.accel.x() = 0.0;
62 ponderable.accelY = 0.0; 62 ponderable.accel.y() = 0.0;
63 ponderable.grounded = false; 63 ponderable.grounded = false;
64 ponderable.frozen = false; 64 ponderable.frozen = false;
65 ponderable.collidable = true; 65 ponderable.collidable = true;
@@ -102,19 +102,17 @@ void PonderingSystem::tickBody(
102 // Accelerate 102 // Accelerate
103 if (!ponderable.frozen) 103 if (!ponderable.frozen)
104 { 104 {
105 ponderable.velX += ponderable.accelX * dt; 105 ponderable.vel += ponderable.accel * dt;
106 ponderable.velY += ponderable.accelY * dt;
107 106
108 if ((ponderable.type == PonderableComponent::Type::freefalling) 107 if ((ponderable.type == PonderableComponent::Type::freefalling)
109 && (ponderable.velY > TERMINAL_VELOCITY)) 108 && (ponderable.vel.y() > TERMINAL_VELOCITY))
110 { 109 {
111 ponderable.velY = TERMINAL_VELOCITY; 110 ponderable.vel.y() = TERMINAL_VELOCITY;
112 } 111 }
113 } 112 }
114 113
115 // Move 114 // Move
116 double newX = transformable.x; 115 vec2d newPos = transformable.pos;
117 double newY = transformable.y;
118 116
119 if (!ponderable.frozen) 117 if (!ponderable.frozen)
120 { 118 {
@@ -123,19 +121,13 @@ void PonderingSystem::tickBody(
123 auto& ferryTrans = game_.getEntityManager(). 121 auto& ferryTrans = game_.getEntityManager().
124 getComponent<TransformableComponent>(ponderable.ferry); 122 getComponent<TransformableComponent>(ponderable.ferry);
125 123
126 newX = ferryTrans.x + ponderable.relX; 124 newPos = ferryTrans.pos + ponderable.rel;
127 newY = ferryTrans.y + ponderable.relY;
128 } 125 }
129 126
130 newX += ponderable.velX * dt; 127 newPos += ponderable.vel * dt;
131 newY += ponderable.velY * dt;
132 } 128 }
133 129
134 CollisionResult result = 130 CollisionResult result = moveBody(entity, newPos);
135 moveBody(
136 entity,
137 newX,
138 newY);
139 131
140 // Perform cleanup for orientable entites 132 // Perform cleanup for orientable entites
141 bool groundedChanged = (ponderable.grounded != result.grounded); 133 bool groundedChanged = (ponderable.grounded != result.grounded);
@@ -194,8 +186,7 @@ void PonderingSystem::tickBody(
194 auto& ferryTrans = game_.getEntityManager(). 186 auto& ferryTrans = game_.getEntityManager().
195 getComponent<TransformableComponent>(ponderable.ferry); 187 getComponent<TransformableComponent>(ponderable.ferry);
196 188
197 ponderable.relX = transformable.x - ferryTrans.x; 189 ponderable.rel = transformable.pos - ferryTrans.pos;
198 ponderable.relY = transformable.y - ferryTrans.y;
199 } 190 }
200 191
201 // Handle ferry passengers 192 // Handle ferry passengers
@@ -212,35 +203,34 @@ void PonderingSystem::tickBody(
212 // Move to an adjacent map, if necessary 203 // Move to an adjacent map, if necessary
213 if (result.adjacentlyWarping) 204 if (result.adjacentlyWarping)
214 { 205 {
215 double warpX = result.newX; 206 vec2d warpPos = result.pos;
216 double warpY = result.newY;
217 207
218 switch (result.adjWarpDir) 208 switch (result.adjWarpDir)
219 { 209 {
220 case Direction::left: 210 case Direction::left:
221 { 211 {
222 warpX = GAME_WIDTH + WALL_GAP - transformable.w; 212 warpPos.x() = GAME_WIDTH + WALL_GAP - transformable.size.w();
223 213
224 break; 214 break;
225 } 215 }
226 216
227 case Direction::right: 217 case Direction::right:
228 { 218 {
229 warpX = -WALL_GAP; 219 warpPos.x() = -WALL_GAP;
230 220
231 break; 221 break;
232 } 222 }
233 223
234 case Direction::up: 224 case Direction::up:
235 { 225 {
236 warpY = MAP_HEIGHT * TILE_HEIGHT - transformable.h; 226 warpPos.y() = MAP_HEIGHT * TILE_HEIGHT - transformable.size.h();
237 227
238 break; 228 break;
239 } 229 }
240 230
241 case Direction::down: 231 case Direction::down:
242 { 232 {
243 warpY = -WALL_GAP; 233 warpPos.y() = -WALL_GAP;
244 234
245 break; 235 break;
246 } 236 }
@@ -250,15 +240,13 @@ void PonderingSystem::tickBody(
250 changeMap( 240 changeMap(
251 entity, 241 entity,
252 result.adjWarpMapId, 242 result.adjWarpMapId,
253 warpX, 243 warpPos);
254 warpY);
255 } 244 }
256} 245}
257 246
258CollisionResult PonderingSystem::moveBody( 247PonderingSystem::CollisionResult PonderingSystem::moveBody(
259 id_type entity, 248 id_type entity,
260 double x, 249 vec2d newPos)
261 double y)
262{ 250{
263 auto& ponderable = game_.getEntityManager(). 251 auto& ponderable = game_.getEntityManager().
264 getComponent<PonderableComponent>(entity); 252 getComponent<PonderableComponent>(entity);
@@ -266,26 +254,29 @@ CollisionResult PonderingSystem::moveBody(
266 auto& transformable = game_.getEntityManager(). 254 auto& transformable = game_.getEntityManager().
267 getComponent<TransformableComponent>(entity); 255 getComponent<TransformableComponent>(entity);
268 256
269 const double oldX = transformable.x;
270 const double oldY = transformable.y;
271 const double oldRight = oldX + transformable.w;
272 const double oldBottom = oldY + transformable.h;
273
274 CollisionResult result; 257 CollisionResult result;
275 258
276 if (ponderable.collidable) 259 if (ponderable.collidable)
277 { 260 {
278 result = detectCollisions(entity, x, y); 261 result = detectCollisions(entity, newPos);
279 } else { 262 } else {
280 result.newX = x; 263 result.pos = newPos;
281 result.newY = y;
282 } 264 }
283 265
284 // Move 266 // Move
285 if (!ponderable.frozen) 267 if (!ponderable.frozen)
286 { 268 {
287 transformable.x = result.newX; 269 transformable.pos = result.pos;
288 transformable.y = result.newY; 270
271 if (result.blockedHoriz)
272 {
273 ponderable.vel.x() = 0.0;
274 }
275
276 if (result.blockedVert)
277 {
278 ponderable.vel.y() = 0.0;
279 }
289 } 280 }
290 281
291 return result; 282 return result;
@@ -311,21 +302,14 @@ namespace CollisionParams {
311 return (colliderAxis > entityAxis); 302 return (colliderAxis > entityAxis);
312 } 303 }
313 304
314 inline static double OldAxis(const TransformableComponent& transformable) 305 inline static double EntityAxis(const vec2d& pos, const vec2i& size)
315 { 306 {
316 return HorizVert::AxisOldLower(transformable); 307 return HorizVert::AxisLower(pos);
317 } 308 }
318 309
319 inline static double NewAxis( 310 inline static double ObjectAxis(const vec2d& pos, const vec2i& size)
320 const CollisionResult& result,
321 const TransformableComponent&)
322 { 311 {
323 return HorizVert::AxisNewLower(result); 312 return HorizVert::AxisUpper(pos, size);
324 }
325
326 inline static double ObjectAxis(const TransformableComponent& transformable)
327 {
328 return HorizVert::AxisOldUpper(transformable);
329 } 313 }
330 314
331 inline static bool Closer(double left, double right) 315 inline static bool Closer(double left, double right)
@@ -352,21 +336,14 @@ namespace CollisionParams {
352 return (colliderAxis < entityAxis); 336 return (colliderAxis < entityAxis);
353 } 337 }
354 338
355 inline static double OldAxis(const TransformableComponent& transformable) 339 inline static double EntityAxis(const vec2d& pos, const vec2i& size)
356 { 340 {
357 return HorizVert::AxisOldUpper(transformable); 341 return HorizVert::AxisUpper(pos, size);
358 } 342 }
359 343
360 inline static double NewAxis( 344 inline static double ObjectAxis(const vec2d& pos, const vec2i& size)
361 const CollisionResult& result,
362 const TransformableComponent& transformable)
363 { 345 {
364 return HorizVert::AxisNewUpper(result, transformable); 346 return HorizVert::AxisLower(pos);
365 }
366
367 inline static double ObjectAxis(const TransformableComponent& transformable)
368 {
369 return HorizVert::AxisOldLower(transformable);
370 } 347 }
371 348
372 inline static bool Closer(double left, double right) 349 inline static bool Closer(double left, double right)
@@ -375,121 +352,62 @@ namespace CollisionParams {
375 } 352 }
376 }; 353 };
377 354
378 class Horizontal { 355 template <size_t Axis, size_t NonAxis>
356 class HorizVert {
379 public: 357 public:
380 358
381 inline static double AxisOldLower( 359 inline static double AxisLower(const vec2d& pos)
382 const TransformableComponent& transformable)
383 { 360 {
384 return transformable.x; 361 return pos.coords[Axis];
385 } 362 }
386 363
387 inline static double AxisOldUpper( 364 inline static double AxisUpper(const vec2d& pos, const vec2i& size)
388 const TransformableComponent& transformable)
389 { 365 {
390 return transformable.x + transformable.w; 366 return pos.coords[Axis] + size.coords[Axis];
391 } 367 }
392 368
393 inline static double AxisNewLower(const CollisionResult& result) 369 inline static double NonAxisLower(const vec2d& pos)
394 { 370 {
395 return result.newX; 371 return pos.coords[NonAxis];
396 } 372 }
397 373
398 inline static double AxisNewUpper( 374 inline static double NonAxisUpper(const vec2d& pos, const vec2i& size)
399 const CollisionResult& result,
400 const TransformableComponent& transformable)
401 { 375 {
402 return result.newX + transformable.w; 376 return pos.coords[NonAxis] + size.coords[NonAxis];
403 } 377 }
404 378
405 inline static double NonAxisOldLower(
406 const TransformableComponent& transformable)
407 {
408 return transformable.y;
409 }
410
411 inline static double NonAxisOldUpper(
412 const TransformableComponent& transformable)
413 {
414 return transformable.y + transformable.h;
415 }
416
417 inline static double NonAxisNewLower(
418 const CollisionResult& result,
419 const TransformableComponent& transformable)
420 {
421 return result.newY;
422 }
423
424 inline static double NonAxisNewUpper(
425 const CollisionResult& result,
426 const TransformableComponent& transformable)
427 {
428 return result.newY + transformable.h;
429 }
430 }; 379 };
431 380
432 class Vertical { 381 using Horizontal = HorizVert<0, 1>;
433 public: 382 using Vertical = HorizVert<1, 0>;
434
435 inline static double AxisOldLower(
436 const TransformableComponent& transformable)
437 {
438 return transformable.y;
439 }
440
441 inline static double AxisOldUpper(
442 const TransformableComponent& transformable)
443 {
444 return transformable.y + transformable.h;
445 }
446 383
447 inline static double AxisNewLower(const CollisionResult& result) 384 template <Direction dir, typename AscDesc>
448 { 385 class DetectCollisions : public AscDesc {
449 return result.newY; 386 public:
450 }
451 387
452 inline static double AxisNewUpper( 388 static const Direction Dir = dir;
453 const CollisionResult& result,
454 const TransformableComponent& transformable)
455 {
456 return result.newY + transformable.h;
457 }
458 389
459 inline static double NonAxisOldLower( 390 inline static double EntityAxis(const vec2d& pos, const vec2i& size)
460 const TransformableComponent& transformable)
461 { 391 {
462 return transformable.x; 392 return AscDesc::EntityAxis(pos, size);
463 } 393 }
464 394
465 inline static double NonAxisOldUpper( 395 inline static double ObjectAxis(const vec2d& pos, const vec2i& size)
466 const TransformableComponent& transformable)
467 { 396 {
468 return transformable.x + transformable.w; 397 return AscDesc::ObjectAxis(pos, size);
469 } 398 }
470 399
471 inline static double NonAxisNewLower( 400 inline static double EntityAxis(const TransformableComponent& transformable)
472 const CollisionResult& result,
473 const TransformableComponent& transformable)
474 { 401 {
475 return result.newX; 402 return AscDesc::EntityAxis(transformable.pos, transformable.size);
476 } 403 }
477 404
478 inline static double NonAxisNewUpper( 405 inline static double ObjectAxis(const TransformableComponent& transformable)
479 const CollisionResult& result,
480 const TransformableComponent& transformable)
481 { 406 {
482 return result.newX + transformable.w; 407 return AscDesc::ObjectAxis(transformable.pos, transformable.size);
483 } 408 }
484 }; 409 };
485 410
486 template <Direction dir, typename AscDesc>
487 class DetectCollisions : public AscDesc {
488 public:
489
490 static const Direction Dir = dir;
491 };
492
493 class Left : public DetectCollisions<Direction::left, Desc<Horizontal>> { 411 class Left : public DetectCollisions<Direction::left, Desc<Horizontal>> {
494 public: 412 public:
495 413
@@ -531,23 +449,22 @@ namespace CollisionParams {
531 }; 449 };
532}; 450};
533 451
534CollisionResult PonderingSystem::detectCollisions( 452PonderingSystem::CollisionResult PonderingSystem::detectCollisions(
535 id_type entity, 453 id_type entity,
536 double x, 454 vec2d newPos)
537 double y)
538{ 455{
539 auto& transformable = game_.getEntityManager(). 456 auto& transformable = game_.getEntityManager().
540 getComponent<TransformableComponent>(entity); 457 getComponent<TransformableComponent>(entity);
541 458
542 CollisionResult result; 459 CollisionResult result;
543 result.newX = x; 460 result.pos.x() = newPos.x();
544 result.newY = transformable.y; 461 result.pos.y() = transformable.pos.y();
545 462
546 // Find horizontal collisions. 463 // Find horizontal collisions.
547 if (result.newX < transformable.x) 464 if (result.pos.x() < transformable.pos.x())
548 { 465 {
549 detectCollisionsInDirection<CollisionParams::Left>(entity, result); 466 detectCollisionsInDirection<CollisionParams::Left>(entity, result);
550 } else if (result.newX > transformable.x) 467 } else if (result.pos.x() > transformable.pos.x())
551 { 468 {
552 detectCollisionsInDirection<CollisionParams::Right>(entity, result); 469 detectCollisionsInDirection<CollisionParams::Right>(entity, result);
553 } 470 }
@@ -555,13 +472,13 @@ CollisionResult PonderingSystem::detectCollisions(
555 // Find vertical collisions 472 // Find vertical collisions
556 if (!result.stopProcessing) 473 if (!result.stopProcessing)
557 { 474 {
558 result.newY = y; 475 result.pos.y() = newPos.y();
559 result.touchedWall = false; 476 result.touchedWall = false;
560 477
561 if (result.newY < transformable.y) 478 if (result.pos.y() < transformable.pos.y())
562 { 479 {
563 detectCollisionsInDirection<CollisionParams::Up>(entity, result); 480 detectCollisionsInDirection<CollisionParams::Up>(entity, result);
564 } else if (result.newY > transformable.y) 481 } else if (result.pos.y() > transformable.pos.y())
565 { 482 {
566 detectCollisionsInDirection<CollisionParams::Down>(entity, result); 483 detectCollisionsInDirection<CollisionParams::Down>(entity, result);
567 } 484 }
@@ -586,25 +503,25 @@ void PonderingSystem::detectCollisionsInDirection(
586 getComponent<MappableComponent>(mapEntity); 503 getComponent<MappableComponent>(mapEntity);
587 504
588 // Get old location. 505 // Get old location.
589 auto& transformable = game_.getEntityManager(). 506 auto& transform = game_.getEntityManager().
590 getComponent<TransformableComponent>(entity); 507 getComponent<TransformableComponent>(entity);
591 508
592 bool boundaryCollision = false; 509 bool boundaryCollision = false;
593 510
594 auto boundaries = Param::MapBoundaries(mappable); 511 auto boundaries = Param::MapBoundaries(mappable);
595 auto it = boundaries.lower_bound(Param::OldAxis(transformable)); 512 auto it = boundaries.lower_bound(Param::EntityAxis(transform));
596 513
597 // Find the axis distance of the closest environmental boundary. 514 // Find the axis distance of the closest environmental boundary.
598 for (; 515 for (;
599 (it != std::end(boundaries)) && 516 (it != std::end(boundaries)) &&
600 Param::AtLeastInAxisSweep( 517 Param::AtLeastInAxisSweep(
601 it->first, 518 it->first,
602 Param::NewAxis(result, transformable)); 519 Param::EntityAxis(result.pos, transform.size));
603 it++) 520 it++)
604 { 521 {
605 // Check that the boundary is in range for the other axis. 522 // Check that the boundary is in range for the other axis.
606 if ((Param::NonAxisNewUpper(result, transformable) > it->second.lower) && 523 if ((Param::NonAxisUpper(result.pos, transform.size) > it->second.lower) &&
607 (Param::NonAxisNewLower(result, transformable) < it->second.upper)) 524 (Param::NonAxisLower(result.pos) < it->second.upper))
608 { 525 {
609 // We have a collision! 526 // We have a collision!
610 boundaryCollision = true; 527 boundaryCollision = true;
@@ -644,16 +561,16 @@ void PonderingSystem::detectCollisionsInDirection(
644 // Check if the entity would move into the potential collider, 561 // Check if the entity would move into the potential collider,
645 if (Param::IsPastAxis( 562 if (Param::IsPastAxis(
646 Param::ObjectAxis(colliderTrans), 563 Param::ObjectAxis(colliderTrans),
647 Param::NewAxis(result, transformable)) && 564 Param::EntityAxis(result.pos, transform.size)) &&
648 // that it wasn't already colliding, 565 // that it wasn't already colliding,
649 !Param::IsPastAxis( 566 !Param::IsPastAxis(
650 Param::ObjectAxis(colliderTrans), 567 Param::ObjectAxis(colliderTrans),
651 Param::OldAxis(transformable)) && 568 Param::EntityAxis(transform)) &&
652 // that the position on the non-axis is in range, 569 // that the position on the non-axis is in range,
653 (Param::NonAxisOldUpper(colliderTrans) > 570 (Param::NonAxisUpper(colliderTrans.pos, colliderTrans.size) >
654 Param::NonAxisNewLower(result, transformable)) && 571 Param::NonAxisLower(result.pos)) &&
655 (Param::NonAxisOldLower(colliderTrans) < 572 (Param::NonAxisLower(colliderTrans.pos) <
656 Param::NonAxisNewUpper(result, transformable)) && 573 Param::NonAxisUpper(result.pos, transform.size)) &&
657 // and that the collider is not farther away than the environmental 574 // and that the collider is not farther away than the environmental
658 // boundary. 575 // boundary.
659 (!boundaryCollision || 576 (!boundaryCollision ||
@@ -688,7 +605,7 @@ void PonderingSystem::detectCollisionsInDirection(
688 // Check if the entity would still move into the potential collider. 605 // Check if the entity would still move into the potential collider.
689 if (!Param::IsPastAxis( 606 if (!Param::IsPastAxis(
690 Param::ObjectAxis(colliderTrans), 607 Param::ObjectAxis(colliderTrans),
691 Param::NewAxis(result, transformable))) 608 Param::EntityAxis(result.pos, transform.size)))
692 { 609 {
693 break; 610 break;
694 } 611 }
@@ -702,8 +619,8 @@ void PonderingSystem::detectCollisionsInDirection(
702 Param::Dir, 619 Param::Dir,
703 colliderPonder.colliderType, 620 colliderPonder.colliderType,
704 Param::ObjectAxis(colliderTrans), 621 Param::ObjectAxis(colliderTrans),
705 Param::NonAxisOldLower(colliderTrans), 622 Param::NonAxisLower(colliderTrans.pos),
706 Param::NonAxisOldUpper(colliderTrans), 623 Param::NonAxisUpper(colliderTrans.pos, colliderTrans.size),
707 result); 624 result);
708 625
709 if (result.stopProcessing) 626 if (result.stopProcessing)
@@ -724,8 +641,8 @@ void PonderingSystem::detectCollisionsInDirection(
724 (it->first == boundaryAxis); 641 (it->first == boundaryAxis);
725 it++) 642 it++)
726 { 643 {
727 if ((Param::NonAxisNewUpper(result, transformable) > it->second.lower) && 644 if ((Param::NonAxisLower(result.pos) < it->second.upper) &&
728 (Param::NonAxisNewLower(result, transformable) < it->second.upper)) 645 (Param::NonAxisUpper(result.pos, transform.size) > it->second.lower))
729 { 646 {
730 processCollision( 647 processCollision(
731 entity, 648 entity,
@@ -756,9 +673,6 @@ void PonderingSystem::processCollision(
756 double upper, 673 double upper,
757 CollisionResult& result) 674 CollisionResult& result)
758{ 675{
759 auto& ponderable = game_.getEntityManager().
760 getComponent<PonderableComponent>(entity);
761
762 auto& transformable = game_.getEntityManager(). 676 auto& transformable = game_.getEntityManager().
763 getComponent<TransformableComponent>(entity); 677 getComponent<TransformableComponent>(entity);
764 678
@@ -823,29 +737,29 @@ void PonderingSystem::processCollision(
823 { 737 {
824 case Direction::left: 738 case Direction::left:
825 { 739 {
826 result.newX = GAME_WIDTH + WALL_GAP - transformable.w; 740 result.pos.x() = GAME_WIDTH + WALL_GAP - transformable.size.w();
827 741
828 break; 742 break;
829 } 743 }
830 744
831 case Direction::right: 745 case Direction::right:
832 { 746 {
833 result.newX = -WALL_GAP; 747 result.pos.x() = -WALL_GAP;
834 748
835 break; 749 break;
836 } 750 }
837 751
838 case Direction::up: 752 case Direction::up:
839 { 753 {
840 result.newY = 754 result.pos.y() =
841 MAP_HEIGHT * TILE_HEIGHT + WALL_GAP - transformable.h; 755 MAP_HEIGHT * TILE_HEIGHT + WALL_GAP - transformable.pos.h();
842 756
843 break; 757 break;
844 } 758 }
845 759
846 case Direction::down: 760 case Direction::down:
847 { 761 {
848 result.newY = -WALL_GAP; 762 result.pos.y() = -WALL_GAP;
849 763
850 break; 764 break;
851 } 765 }
@@ -905,33 +819,33 @@ void PonderingSystem::processCollision(
905 { 819 {
906 case Direction::left: 820 case Direction::left:
907 { 821 {
908 result.newX = axis; 822 result.pos.x() = axis;
909 ponderable.velX = 0.0; 823 result.blockedHoriz = true;
910 824
911 break; 825 break;
912 } 826 }
913 827
914 case Direction::right: 828 case Direction::right:
915 { 829 {
916 result.newX = axis - transformable.w; 830 result.pos.x() = axis - transformable.size.w();
917 ponderable.velX = 0.0; 831 result.blockedHoriz = true;
918 832
919 break; 833 break;
920 } 834 }
921 835
922 case Direction::up: 836 case Direction::up:
923 { 837 {
924 result.newY = axis; 838 result.pos.y() = axis;
925 ponderable.velY = 0.0; 839 result.blockedVert = true;
926 840
927 break; 841 break;
928 } 842 }
929 843
930 case Direction::down: 844 case Direction::down:
931 { 845 {
932 result.newY = axis - transformable.h; 846 result.pos.y() = axis - transformable.size.h();
847 result.blockedVert = true;
933 result.groundEntity = collider; 848 result.groundEntity = collider;
934 ponderable.velY = 0.0;
935 result.grounded = true; 849 result.grounded = true;
936 850
937 break; 851 break;
diff --git a/src/systems/pondering.h b/src/systems/pondering.h index abc6db2..273db67 100644 --- a/src/systems/pondering.h +++ b/src/systems/pondering.h
@@ -4,19 +4,7 @@
4#include "system.h" 4#include "system.h"
5#include "components/ponderable.h" 5#include "components/ponderable.h"
6#include "direction.h" 6#include "direction.h"
7 7#include "vector.h"
8struct CollisionResult
9{
10 double newX;
11 double newY;
12 bool stopProcessing = false;
13 bool touchedWall = false;
14 bool adjacentlyWarping = false;
15 Direction adjWarpDir;
16 size_t adjWarpMapId;
17 bool grounded = false;
18 EntityManager::id_type groundEntity;
19};
20 8
21class PonderingSystem : public System { 9class PonderingSystem : public System {
22public: 10public:
@@ -47,7 +35,19 @@ public:
47 35
48private: 36private:
49 37
50 38 struct CollisionResult
39 {
40 vec2d pos;
41 bool stopProcessing = false;
42 bool touchedWall = false;
43 bool blockedHoriz = false;
44 bool blockedVert = false;
45 bool adjacentlyWarping = false;
46 Direction adjWarpDir;
47 size_t adjWarpMapId;
48 bool grounded = false;
49 id_type groundEntity;
50 };
51 51
52 void tickBody( 52 void tickBody(
53 id_type entity, 53 id_type entity,
@@ -56,13 +56,11 @@ private:
56 56
57 CollisionResult moveBody( 57 CollisionResult moveBody(
58 id_type entity, 58 id_type entity,
59 double x, 59 vec2d newPos);
60 double y);
61 60
62 CollisionResult detectCollisions( 61 CollisionResult detectCollisions(
63 id_type entity, 62 id_type entity,
64 double x, 63 vec2d newPos);
65 double y);
66 64
67 template <typename Param> 65 template <typename Param>
68 void detectCollisionsInDirection( 66 void detectCollisionsInDirection(
diff --git a/src/systems/realizing.cpp b/src/systems/realizing.cpp index 8e670ac..f9285ad 100644 --- a/src/systems/realizing.cpp +++ b/src/systems/realizing.cpp
@@ -93,20 +93,20 @@ void parseAI(
93 93
94 if (direction == "left") 94 if (direction == "left")
95 { 95 {
96 action.speedX = -speed; 96 action.speed.x() = -speed;
97 action.speedY = 0; 97 action.speed.y() = 0;
98 } else if (direction == "right") 98 } else if (direction == "right")
99 { 99 {
100 action.speedX = speed; 100 action.speed.x() = speed;
101 action.speedY = 0; 101 action.speed.y() = 0;
102 } else if (direction == "up") 102 } else if (direction == "up")
103 { 103 {
104 action.speedX = 0; 104 action.speed.x() = 0;
105 action.speedY = -speed; 105 action.speed.y() = -speed;
106 } else if (direction == "down") 106 } else if (direction == "down")
107 { 107 {
108 action.speedX = 0; 108 action.speed.x() = 0;
109 action.speedY = speed; 109 action.speed.y() = speed;
110 } 110 }
111 111
112 action.dur = length / speed; 112 action.dur = length / speed;
@@ -186,11 +186,11 @@ EntityManager::id_type RealizingSystem::initSingleton(
186 } 186 }
187 187
188 key = getProp(top, "startx"); 188 key = getProp(top, "startx");
189 realizable.startingX = atoi(reinterpret_cast<char*>(key)); 189 realizable.startingPos.x() = atoi(reinterpret_cast<char*>(key));
190 xmlFree(key); 190 xmlFree(key);
191 191
192 key = getProp(top, "starty"); 192 key = getProp(top, "starty");
193 realizable.startingY = atoi(reinterpret_cast<char*>(key)); 193 realizable.startingPos.y() = atoi(reinterpret_cast<char*>(key));
194 xmlFree(key); 194 xmlFree(key);
195 195
196 key = getProp(top, "startmap"); 196 key = getProp(top, "startmap");
@@ -260,11 +260,11 @@ EntityManager::id_type RealizingSystem::initSingleton(
260 emplaceComponent<TransformableComponent>(mapObject); 260 emplaceComponent<TransformableComponent>(mapObject);
261 261
262 key = getProp(mapNode, "x"); 262 key = getProp(mapNode, "x");
263 transformable.origX = atoi(reinterpret_cast<char*>(key)); 263 transformable.origPos.x() = atoi(reinterpret_cast<char*>(key));
264 xmlFree(key); 264 xmlFree(key);
265 265
266 key = getProp(mapNode, "y"); 266 key = getProp(mapNode, "y");
267 transformable.origY = atoi(reinterpret_cast<char*>(key)); 267 transformable.origPos.y() = atoi(reinterpret_cast<char*>(key));
268 xmlFree(key); 268 xmlFree(key);
269 269
270 // Set the sprite and size using the prototype definition. 270 // Set the sprite and size using the prototype definition.
@@ -273,17 +273,17 @@ EntityManager::id_type RealizingSystem::initSingleton(
273 xmlFree(key); 273 xmlFree(key);
274 274
275 key = getProp(prototypeNode, "width"); 275 key = getProp(prototypeNode, "width");
276 transformable.origW = atoi(reinterpret_cast<char*>(key)); 276 transformable.origSize.w() = atoi(reinterpret_cast<char*>(key));
277 xmlFree(key); 277 xmlFree(key);
278 278
279 key = getProp(prototypeNode, "height"); 279 key = getProp(prototypeNode, "height");
280 transformable.origH = atoi(reinterpret_cast<char*>(key)); 280 transformable.origSize.h() = atoi(reinterpret_cast<char*>(key));
281 xmlFree(key); 281 xmlFree(key);
282 282
283 AnimationSet objectAnim( 283 AnimationSet objectAnim(
284 spritePath.c_str(), 284 spritePath.c_str(),
285 transformable.origW, 285 transformable.origSize.w(),
286 transformable.origH, 286 transformable.origSize.h(),
287 1); 287 1);
288 288
289 objectAnim.emplaceAnimation("static", 0, 1, 1); 289 objectAnim.emplaceAnimation("static", 0, 1, 1);
@@ -503,10 +503,8 @@ void RealizingSystem::loadMap(id_type mapEntity)
503 auto& transformable = game_.getEntityManager(). 503 auto& transformable = game_.getEntityManager().
504 getComponent<TransformableComponent>(prototype); 504 getComponent<TransformableComponent>(prototype);
505 505
506 transformable.x = transformable.origX; 506 transformable.pos = transformable.origPos;
507 transformable.y = transformable.origY; 507 transformable.size = transformable.origSize;
508 transformable.w = transformable.origW;
509 transformable.h = transformable.origH;
510 } 508 }
511 509
512 if (game_.getEntityManager().hasComponent<AnimatableComponent>(prototype)) 510 if (game_.getEntityManager().hasComponent<AnimatableComponent>(prototype))
diff --git a/src/vector.h b/src/vector.h new file mode 100644 index 0000000..3abd98a --- /dev/null +++ b/src/vector.h
@@ -0,0 +1,111 @@
1#ifndef COORDINATES_H_A45D34FB
2#define COORDINATES_H_A45D34FB
3
4template <typename T>
5class vec2 {
6public:
7
8 T coords[2];
9
10 vec2() = default;
11
12 vec2(double x, double y) : coords{x, y}
13 {
14 }
15
16 inline T& x()
17 {
18 return coords[0];
19 }
20
21 inline const T& x() const
22 {
23 return coords[0];
24 }
25
26 inline T& w()
27 {
28 return coords[0];
29 }
30
31 inline const T& w() const
32 {
33 return coords[0];
34 }
35
36 inline T& y()
37 {
38 return coords[1];
39 }
40
41 inline const T& y() const
42 {
43 return coords[1];
44 }
45
46 inline T& h()
47 {
48 return coords[1];
49 }
50
51 inline const T& h() const
52 {
53 return coords[1];
54 }
55
56 template <typename R>
57 operator vec2<R>() const
58 {
59 return vec2<R>(x(), y());
60 }
61
62 vec2 operator+(const vec2& other) const
63 {
64 return vec2(x() + other.x(), y() + other.y());
65 }
66
67 vec2& operator+=(const vec2& other)
68 {
69 x() += other.x();
70 y() += other.y();
71
72 return *this;
73 }
74
75 vec2 operator-(const vec2& other) const
76 {
77 return vec2(x() - other.x(), y() - other.y());
78 }
79
80 vec2 operator-=(const vec2& other)
81 {
82 x() -= other.x();
83 y() -= other.y();
84
85 return *this;
86 }
87
88 vec2 operator-() const
89 {
90 return vec2(-x(), -y());
91 }
92
93 vec2 operator*(double s) const
94 {
95 return vec2(x() * s, y() * s);
96 }
97
98 vec2& operator*=(double s)
99 {
100 x() *= s;
101 y() *= s;
102
103 return *this;
104 }
105
106};
107
108using vec2d = vec2<double>;
109using vec2i = vec2<int>;
110
111#endif /* end of include guard: COORDINATES_H_A45D34FB */