summary refs log tree commit diff stats
diff options
context:
space:
mode:
-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 */