summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2021-02-03 02:03:59 -0500
committerKelly Rauchenberger <fefferburbia@gmail.com>2021-02-03 02:03:59 -0500
commit8d7ef2b2ae3ddff204f5934fe67c535d7f1345e9 (patch)
tree7bcc12dd2efab7e24867895c5ef3fbb3e7d0e36d
parentbe09120d1d044b476ef8b516efbdb526f20d9e2d (diff)
downloadtanetane-8d7ef2b2ae3ddff204f5934fe67c535d7f1345e9.tar.gz
tanetane-8d7ef2b2ae3ddff204f5934fe67c535d7f1345e9.tar.bz2
tanetane-8d7ef2b2ae3ddff204f5934fe67c535d7f1345e9.zip
Converted Party into CharacterSystem
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/animation_system.cpp8
-rw-r--r--src/character_system.cpp229
-rw-r--r--src/character_system.h32
-rw-r--r--src/main.cpp18
-rw-r--r--src/party.cpp231
-rw-r--r--src/party.h46
-rw-r--r--src/sprite.h17
-rw-r--r--src/system.h3
9 files changed, 294 insertions, 292 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f7b6790..65abfe1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -35,12 +35,12 @@ add_executable(tanetane
35 src/main.cpp 35 src/main.cpp
36 src/renderer.cpp 36 src/renderer.cpp
37 src/mixer.cpp 37 src/mixer.cpp
38 src/party.cpp
39 src/game.cpp 38 src/game.cpp
40 src/map.cpp 39 src/map.cpp
41 src/transform_system.cpp 40 src/transform_system.cpp
42 src/camera_system.cpp 41 src/camera_system.cpp
43 src/animation_system.cpp 42 src/animation_system.cpp
43 src/character_system.cpp
44) 44)
45 45
46set_property(TARGET tanetane PROPERTY CXX_STANDARD 17) 46set_property(TARGET tanetane PROPERTY CXX_STANDARD 17)
diff --git a/src/animation_system.cpp b/src/animation_system.cpp index 3320e1d..cf34066 100644 --- a/src/animation_system.cpp +++ b/src/animation_system.cpp
@@ -91,9 +91,11 @@ void AnimationSystem::tick(double dt) {
91 animTimer_.accumulate(dt); 91 animTimer_.accumulate(dt);
92 while (animTimer_.step()) { 92 while (animTimer_.step()) {
93 for (Sprite& sprite : game_.getSprites() | game_.spriteView()) { 93 for (Sprite& sprite : game_.getSprites() | game_.spriteView()) {
94 sprite.animationFrame++; 94 if (sprite.isAnimated) {
95 if (sprite.animationFrame >= sprite.animations[sprite.animationId].size()) { 95 sprite.animationFrame++;
96 sprite.animationFrame = 0; 96 if (sprite.animationFrame >= sprite.animations[sprite.animationId].size()) {
97 sprite.animationFrame = 0;
98 }
97 } 99 }
98 } 100 }
99 } 101 }
diff --git a/src/character_system.cpp b/src/character_system.cpp new file mode 100644 index 0000000..64e2f3b --- /dev/null +++ b/src/character_system.cpp
@@ -0,0 +1,229 @@
1#include "character_system.h"
2#include "consts.h"
3#include "mixer.h"
4#include "sprite.h"
5#include "game.h"
6#include "transform_system.h"
7#include "animation_system.h"
8
9void CharacterSystem::addSpriteToParty(int leaderId, int followerId) {
10 Sprite& leader = game_.getSprite(leaderId);
11 Sprite& follower = game_.getSprite(followerId);
12
13 int index = leader.followers.size() + 1;
14 follower.trail = std::deque<Movement>(PARTY_FRAME_DELAY * index, {.pos = follower.loc, .dir = follower.dir});
15
16 leader.followers.push_back(followerId);
17
18 game_.getSystem<AnimationSystem>().setSpriteAnimation(followerId, "still");
19}
20
21void CharacterSystem::moveSprite(int spriteId, Mixer& mixer, const Input& keystate) {
22 Sprite& sprite = game_.getSprite(spriteId);
23 Direction dir = sprite.dir;
24
25 if (!keystate.up && !keystate.down && !keystate.left && !keystate.right) {
26 if (sprite.characterState != CharacterState::Running) {
27 if (sprite.characterState == CharacterState::Normal) {
28 game_.getSystem<AnimationSystem>().setSpriteAnimation(spriteId, "still");
29 for (int followerId : sprite.followers) {
30 game_.getSystem<AnimationSystem>().setSpriteAnimation(followerId, "still");
31 }
32 }
33
34 return;
35 }
36 } else {
37 if (keystate.up)
38 {
39 dir = Direction::up;
40 } else if (keystate.down)
41 {
42 dir = Direction::down;
43 }
44
45 if (keystate.left)
46 {
47 if (dir == Direction::up) {
48 dir = Direction::up_left;
49 } else if (dir == Direction::down) {
50 dir = Direction::down_left;
51 } else {
52 dir = Direction::left;
53 }
54 } else if (keystate.right)
55 {
56 if (dir == Direction::up) {
57 dir = Direction::up_right;
58 } else if (dir == Direction::down) {
59 dir = Direction::down_right;
60 } else {
61 dir = Direction::right;
62 }
63 }
64 }
65
66 vec2i pLoc = sprite.loc;
67 game_.getSystem<AnimationSystem>().setSpriteDirection(spriteId, dir);
68
69 if (sprite.characterState == CharacterState::Crouching) {
70 for (int followerId : sprite.followers) {
71 game_.getSystem<AnimationSystem>().setSpriteDirection(followerId, dir);
72 }
73
74 return;
75 }
76
77 int speed = MOVEMENT_SPEED;
78 if (sprite.characterState == CharacterState::Running) {
79 speed *= 2;
80 } else {
81 game_.getSystem<AnimationSystem>().setSpriteAnimation(spriteId, "walk");
82 for (int followerId : sprite.followers) {
83 game_.getSystem<AnimationSystem>().setSpriteAnimation(followerId, "walk");
84 }
85 }
86
87 pLoc += (unitVecInDirection(dir) * speed);
88
89 // Check collision.
90 const Map& map = game_.getMap();
91 bool blocked = false;
92
93 const vec2i UL_COL_BOX = { 8, 8 };
94 const vec2i DR_COL_BOX = { 4, 0 };
95 vec2i oldColPosUL = (sprite.loc - UL_COL_BOX) / map.getTileSize();
96 vec2i newColPosUL = (pLoc - UL_COL_BOX) / map.getTileSize();
97 vec2i oldColPosDR = (sprite.loc + DR_COL_BOX) / map.getTileSize();
98 vec2i newColPosDR = (pLoc + DR_COL_BOX) / map.getTileSize();
99
100 if (dirHasDir(dir, Direction::right) &&
101 newColPosDR.x() > oldColPosDR.x()) {
102 for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) {
103 if (map.isBlocked(newColPosDR.x(), y)) {
104 blocked = true;
105 pLoc.x() = sprite.loc.x();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
106 break;
107 }
108 }
109 }
110
111 if (dirHasDir(dir, Direction::left) &&
112 newColPosUL.x() < oldColPosUL.x()) {
113 for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) {
114 if (map.isBlocked(newColPosUL.x(), y)) {
115 blocked = true;
116 pLoc.x() = sprite.loc.x();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
117 break;
118 }
119 }
120 }
121
122 if (dirHasDir(dir, Direction::down) &&
123 newColPosDR.y() > oldColPosDR.y()) {
124 for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) {
125 if (map.isBlocked(x, newColPosDR.y())) {
126 blocked = true;
127 pLoc.y() = sprite.loc.y();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
128 break;
129 }
130 }
131 }
132
133 if (dirHasDir(dir, Direction::up) &&
134 newColPosUL.y() < oldColPosUL.y()) {
135 for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) {
136 if (map.isBlocked(x, newColPosUL.y())) {
137 blocked = true;
138 pLoc.y() = sprite.loc.y();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
139 break;
140 }
141 }
142 }
143
144 if (blocked && sprite.characterState == CharacterState::Running) {
145 stopRunning(spriteId);
146 mixer.playSound("../res/bump.wav");
147 }
148
149 // Move everything
150 if (pLoc != sprite.loc) {
151 game_.getSystem<TransformSystem>().moveSprite(spriteId, pLoc);
152
153 for (int followerId : sprite.followers) {
154 Sprite& pNext = game_.getSprite(followerId);
155 const Movement& posdir = pNext.trail.front();
156 game_.getSystem<TransformSystem>().moveSprite(followerId, posdir.pos);
157 game_.getSystem<AnimationSystem>().setSpriteDirection(followerId, posdir.dir);
158
159 pNext.trail.pop_front();
160 pNext.trail.push_back({.pos = pLoc, .dir = dir});
161 }
162 }
163}
164
165void CharacterSystem::beginCrouch(int spriteId) {
166 Sprite& sprite = game_.getSprite(spriteId);
167
168 if (sprite.characterState == CharacterState::Running) {
169 stopRunning(spriteId);
170 } else {
171 sprite.characterState = CharacterState::Crouching;
172
173 game_.getSystem<AnimationSystem>().setSpriteAnimation(spriteId, "crouch");
174 for (int followerId : sprite.followers) {
175 game_.getSystem<AnimationSystem>().setSpriteAnimation(followerId, "crouch");
176 }
177 }
178}
179
180void CharacterSystem::endCrouch(int spriteId) {
181 Sprite& sprite = game_.getSprite(spriteId);
182
183 if (sprite.characterState == CharacterState::Crouching) {
184 sprite.characterState = CharacterState::Running;
185
186 game_.getSystem<AnimationSystem>().setSpriteAnimation(spriteId, "run");
187 for (int followerId : sprite.followers) {
188 game_.getSystem<AnimationSystem>().setSpriteAnimation(followerId, "run");
189
190 // Halve the movement buffer for the followers.
191 Sprite& follower = game_.getSprite(followerId);
192 std::deque<Movement> newMove;
193
194 while (!follower.trail.empty()) {
195 newMove.push_back(follower.trail.front());
196 follower.trail.pop_front();
197 follower.trail.pop_front();
198 }
199
200 follower.trail = std::move(newMove);
201 }
202 }
203}
204
205void CharacterSystem::stopRunning(int spriteId) {
206 Sprite& sprite = game_.getSprite(spriteId);
207 sprite.characterState = CharacterState::Normal;
208
209 // Double the movement buffer for the followers.
210 for (int followerId : sprite.followers) {
211 Sprite& follower = game_.getSprite(followerId);
212
213 std::deque<Movement> newMove;
214 vec2i lastPos = follower.loc;
215
216 while (!follower.trail.empty()) {
217 Movement m1 = follower.trail.front();
218 Movement m2 = m1;
219 m1.pos = (m1.pos + lastPos) / 2;
220 lastPos = m2.pos;
221
222 newMove.push_back(m1);
223 newMove.push_back(m2);
224 follower.trail.pop_front();
225 }
226
227 follower.trail = std::move(newMove);
228 }
229}
diff --git a/src/character_system.h b/src/character_system.h new file mode 100644 index 0000000..ff5db02 --- /dev/null +++ b/src/character_system.h
@@ -0,0 +1,32 @@
1#ifndef PARTY_H_826F91BA
2#define PARTY_H_826F91BA
3
4#include "system.h"
5
6class Mixer;
7class Game;
8class Input;
9
10class CharacterSystem : public System {
11public:
12
13 static constexpr SystemKey Key = SystemKey::Character;
14
15 CharacterSystem(Game& game) : game_(game) {}
16
17 void addSpriteToParty(int leaderId, int followerId);
18
19 void moveSprite(int spriteId, Mixer& mixer, const Input& keystate);
20
21 void beginCrouch(int spriteId);
22
23 void endCrouch(int spriteId);
24
25private:
26
27 void stopRunning(int spriteId);
28
29 Game& game_;
30};
31
32#endif /* end of include guard: PARTY_H_826F91BA */
diff --git a/src/main.cpp b/src/main.cpp index ea27511..3ac4d09 100644 --- a/src/main.cpp +++ b/src/main.cpp
@@ -2,19 +2,20 @@
2#include <memory> 2#include <memory>
3#include "renderer.h" 3#include "renderer.h"
4#include "game.h" 4#include "game.h"
5#include "party.h"
6#include "timer.h" 5#include "timer.h"
7#include "map.h" 6#include "map.h"
8#include "mixer.h" 7#include "mixer.h"
9#include "transform_system.h" 8#include "transform_system.h"
10#include "camera_system.h" 9#include "camera_system.h"
11#include "animation_system.h" 10#include "animation_system.h"
11#include "character_system.h"
12 12
13void loop(Renderer& renderer, Mixer& mixer) { 13void loop(Renderer& renderer, Mixer& mixer) {
14 Game game; 14 Game game;
15 game.emplaceSystem<TransformSystem>(); 15 game.emplaceSystem<TransformSystem>();
16 game.emplaceSystem<CameraSystem>(); 16 game.emplaceSystem<CameraSystem>();
17 game.emplaceSystem<AnimationSystem>(); 17 game.emplaceSystem<AnimationSystem>();
18 game.emplaceSystem<CharacterSystem>();
18 19
19 Input keystate; 20 Input keystate;
20 21
@@ -28,20 +29,17 @@ void loop(Renderer& renderer, Mixer& mixer) {
28 int kumaSprite = game.emplaceSprite(); 29 int kumaSprite = game.emplaceSprite();
29 game.getSystem<TransformSystem>().initSprite(kumaSprite, {32, 32}); 30 game.getSystem<TransformSystem>().initSprite(kumaSprite, {32, 32});
30 game.getSystem<AnimationSystem>().initSprite(kumaSprite, "../res/kuma_anim.txt", renderer); 31 game.getSystem<AnimationSystem>().initSprite(kumaSprite, "../res/kuma_anim.txt", renderer);
32 game.getSystem<CharacterSystem>().addSpriteToParty(lucasSprite, kumaSprite);
31 33
32 int dusterSprite = game.emplaceSprite(); 34 int dusterSprite = game.emplaceSprite();
33 game.getSystem<TransformSystem>().initSprite(dusterSprite, {32, 32}); 35 game.getSystem<TransformSystem>().initSprite(dusterSprite, {32, 32});
34 game.getSystem<AnimationSystem>().initSprite(dusterSprite, "../res/duster_anim.txt", renderer); 36 game.getSystem<AnimationSystem>().initSprite(dusterSprite, "../res/duster_anim.txt", renderer);
37 game.getSystem<CharacterSystem>().addSpriteToParty(lucasSprite, dusterSprite);
35 38
36 int boneySprite = game.emplaceSprite(); 39 int boneySprite = game.emplaceSprite();
37 game.getSystem<TransformSystem>().initSprite(boneySprite, {32, 32}); 40 game.getSystem<TransformSystem>().initSprite(boneySprite, {32, 32});
38 game.getSystem<AnimationSystem>().initSprite(boneySprite, "../res/boney_anim.txt", renderer); 41 game.getSystem<AnimationSystem>().initSprite(boneySprite, "../res/boney_anim.txt", renderer);
39 42 game.getSystem<CharacterSystem>().addSpriteToParty(lucasSprite, boneySprite);
40 Party party;
41 party.addMember(game, lucasSprite);
42 party.addMember(game, kumaSprite);
43 party.addMember(game, dusterSprite);
44 party.addMember(game, boneySprite);
45 43
46 game.getSystem<CameraSystem>().setFollowingSprite(lucasSprite); 44 game.getSystem<CameraSystem>().setFollowingSprite(lucasSprite);
47 game.getSystem<CameraSystem>().unlockCamera(); 45 game.getSystem<CameraSystem>().unlockCamera();
@@ -62,9 +60,9 @@ void loop(Renderer& renderer, Mixer& mixer) {
62 if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)) { 60 if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)) {
63 return; 61 return;
64 } else if (e.type == SDL_KEYDOWN && (e.key.keysym.sym == SDLK_LSHIFT || e.key.keysym.sym == SDLK_RSHIFT)) { 62 } else if (e.type == SDL_KEYDOWN && (e.key.keysym.sym == SDLK_LSHIFT || e.key.keysym.sym == SDLK_RSHIFT)) {
65 party.beginCrouch(game); 63 game.getSystem<CharacterSystem>().beginCrouch(lucasSprite);
66 } else if (e.type == SDL_KEYUP && (e.key.keysym.sym == SDLK_LSHIFT || e.key.keysym.sym == SDLK_RSHIFT)) { 64 } else if (e.type == SDL_KEYUP && (e.key.keysym.sym == SDLK_LSHIFT || e.key.keysym.sym == SDLK_RSHIFT)) {
67 party.endCrouch(game); 65 game.getSystem<CharacterSystem>().endCrouch(lucasSprite);
68 } 66 }
69 } 67 }
70 68
@@ -76,7 +74,7 @@ void loop(Renderer& renderer, Mixer& mixer) {
76 74
77 inputTimer.accumulate(frameTime); 75 inputTimer.accumulate(frameTime);
78 while (inputTimer.step()) { 76 while (inputTimer.step()) {
79 party.move(game, mixer, keystate); 77 game.getSystem<CharacterSystem>().moveSprite(lucasSprite, mixer, keystate);
80 } 78 }
81 79
82 for (System& system : game.systems()) { 80 for (System& system : game.systems()) {
diff --git a/src/party.cpp b/src/party.cpp deleted file mode 100644 index 8b0c34e..0000000 --- a/src/party.cpp +++ /dev/null
@@ -1,231 +0,0 @@
1#include "party.h"
2#include "consts.h"
3#include "mixer.h"
4#include "transform_system.h"
5#include "animation_system.h"
6
7void Party::addMember(Game& game, int spriteId) {
8 int index = members_.size();
9
10 PartyMember newMember;
11 newMember.spriteId = spriteId;
12
13 if (index > 0) {
14 const Sprite& sprite = game.getSprite(spriteId);
15
16 newMember.movement = std::deque<Movement>(PARTY_FRAME_DELAY * index, {.pos = sprite.loc, .dir = sprite.dir});
17 }
18
19 members_.push_back(std::move(newMember));
20
21 game.getSystem<AnimationSystem>().setSpriteAnimation(spriteId, "still");
22}
23
24void Party::move(Game& game, Mixer& mixer, const Input& keystate) {
25 if (members_.empty()) {
26 return;
27 }
28
29 Direction dir = Direction::left;
30
31 if (!keystate.up && !keystate.down && !keystate.left && !keystate.right) {
32 if (state_ == State::Running) {
33 dir = lastDir_;
34 } else {
35 if (state_ == State::Normal) {
36 for (int i = 0; i < members_.size(); i++) {
37 game.getSystem<AnimationSystem>().setSpriteAnimation(members_[i].spriteId, "still");
38 }
39 }
40
41 return;
42 }
43 } else {
44 if (keystate.up)
45 {
46 dir = Direction::up;
47 } else if (keystate.down)
48 {
49 dir = Direction::down;
50 }
51
52 if (keystate.left)
53 {
54 if (dir == Direction::up) {
55 dir = Direction::up_left;
56 } else if (dir == Direction::down) {
57 dir = Direction::down_left;
58 } else {
59 dir = Direction::left;
60 }
61 } else if (keystate.right)
62 {
63 if (dir == Direction::up) {
64 dir = Direction::up_right;
65 } else if (dir == Direction::down) {
66 dir = Direction::down_right;
67 } else {
68 dir = Direction::right;
69 }
70 }
71 }
72
73 lastDir_ = dir;
74
75 const Sprite& p1 = game.getSprite(members_[0].spriteId);
76 vec2i pLoc = p1.loc;
77
78 if (state_ == State::Crouching) {
79 for (int i = 0; i < members_.size(); i++) {
80 game.getSystem<AnimationSystem>().setSpriteDirection(members_[i].spriteId, dir);
81 }
82
83 return;
84 } else {
85 game.getSystem<AnimationSystem>().setSpriteDirection(members_[0].spriteId, dir);
86 }
87
88 int speed = MOVEMENT_SPEED;
89 if (state_ == State::Running) {
90 speed *= 2;
91 } else {
92 for (int i = 0; i < members_.size(); i++) {
93 game.getSystem<AnimationSystem>().setSpriteAnimation(members_[i].spriteId, "walk");
94 }
95 }
96
97 pLoc += (unitVecInDirection(dir) * speed);
98
99 // Check collision.
100 const Map& map = game.getMap();
101 bool blocked = false;
102
103 const vec2i UL_COL_BOX = { 8, 8 };
104 const vec2i DR_COL_BOX = { 4, 0 };
105 vec2i oldColPosUL = (p1.loc - UL_COL_BOX) / map.getTileSize();
106 vec2i newColPosUL = (pLoc - UL_COL_BOX) / map.getTileSize();
107 vec2i oldColPosDR = (p1.loc + DR_COL_BOX) / map.getTileSize();
108 vec2i newColPosDR = (pLoc + DR_COL_BOX) / map.getTileSize();
109
110 if (dirHasDir(dir, Direction::right) &&
111 newColPosDR.x() > oldColPosDR.x()) {
112 for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) {
113 if (map.isBlocked(newColPosDR.x(), y)) {
114 blocked = true;
115 pLoc.x() = p1.loc.x();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
116 break;
117 }
118 }
119 }
120
121 if (dirHasDir(dir, Direction::left) &&
122 newColPosUL.x() < oldColPosUL.x()) {
123 for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) {
124 if (map.isBlocked(newColPosUL.x(), y)) {
125 blocked = true;
126 pLoc.x() = p1.loc.x();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
127 break;
128 }
129 }
130 }
131
132 if (dirHasDir(dir, Direction::down) &&
133 newColPosDR.y() > oldColPosDR.y()) {
134 for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) {
135 if (map.isBlocked(x, newColPosDR.y())) {
136 blocked = true;
137 pLoc.y() = p1.loc.y();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
138 break;
139 }
140 }
141 }
142
143 if (dirHasDir(dir, Direction::up) &&
144 newColPosUL.y() < oldColPosUL.y()) {
145 for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) {
146 if (map.isBlocked(x, newColPosUL.y())) {
147 blocked = true;
148 pLoc.y() = p1.loc.y();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1;
149 break;
150 }
151 }
152 }
153
154 if (blocked && state_ == State::Running) {
155 stopRunning(game);
156 mixer.playSound("../res/bump.wav");
157 }
158
159 // Move everything
160 if (pLoc != p1.loc) {
161 game.getSystem<TransformSystem>().moveSprite(members_[0].spriteId, pLoc);
162
163 for (int i = 1; i < members_.size(); i++) {
164 const Sprite& pNext = game.getSprite(members_[i].spriteId);
165 const Movement& posdir = members_[i].movement.front();
166 game.getSystem<TransformSystem>().moveSprite(members_[i].spriteId, posdir.pos);
167 game.getSystem<AnimationSystem>().setSpriteDirection(members_[i].spriteId, posdir.dir);
168
169 members_[i].movement.pop_front();
170 members_[i].movement.push_back({.pos = pLoc, .dir = dir});
171 }
172 }
173}
174
175void Party::beginCrouch(Game& game) {
176 if (state_ == State::Running) {
177 stopRunning(game);
178 } else {
179 state_ = State::Crouching;
180
181 for (int i = 0; i < members_.size(); i++) {
182 game.getSystem<AnimationSystem>().setSpriteAnimation(members_[i].spriteId, "crouch");
183 }
184 }
185}
186
187void Party::endCrouch(Game& game) {
188 if (state_ == State::Crouching) {
189 state_ = State::Running;
190
191 for (int i = 0; i < members_.size(); i++) {
192 game.getSystem<AnimationSystem>().setSpriteAnimation(members_[i].spriteId, "run");
193
194 // Halve the movement buffer for the followers.
195 if (i > 0) {
196 std::deque<Movement> newMove;
197
198 while (!members_[i].movement.empty()) {
199 newMove.push_back(members_[i].movement.front());
200 members_[i].movement.pop_front();
201 members_[i].movement.pop_front();
202 }
203
204 members_[i].movement = std::move(newMove);
205 }
206 }
207 }
208}
209
210void Party::stopRunning(Game& game) {
211 state_ = State::Normal;
212
213 // Double the movement buffer for the followers.
214 for (int i = 1; i < members_.size(); i++) {
215 std::deque<Movement> newMove;
216 vec2i lastPos = game.getSprite(members_[i].spriteId).loc;
217
218 while (!members_[i].movement.empty()) {
219 Movement m1 = members_[i].movement.front();
220 Movement m2 = m1;
221 m1.pos = (m1.pos + lastPos) / 2;
222 lastPos = m2.pos;
223
224 newMove.push_back(m1);
225 newMove.push_back(m2);
226 members_[i].movement.pop_front();
227 }
228
229 members_[i].movement = std::move(newMove);
230 }
231}
diff --git a/src/party.h b/src/party.h deleted file mode 100644 index 59330c8..0000000 --- a/src/party.h +++ /dev/null
@@ -1,46 +0,0 @@
1#ifndef PARTY_H_826F91BA
2#define PARTY_H_826F91BA
3
4#include <deque>
5#include <vector>
6#include "game.h"
7
8class Mixer;
9
10class Party {
11public:
12
13 void addMember(Game& game, int spriteId);
14
15 void move(Game& game, Mixer& mixer, const Input& keystate);
16
17 void beginCrouch(Game& game);
18
19 void endCrouch(Game& game);
20
21private:
22
23 void stopRunning(Game& game);
24
25 enum class State {
26 Normal,
27 Crouching,
28 Running
29 };
30
31 struct Movement {
32 vec2i pos;
33 Direction dir;
34 };
35
36 struct PartyMember {
37 int spriteId;
38 std::deque<Movement> movement;
39 };
40
41 std::vector<PartyMember> members_;
42 State state_ = State::Normal;
43 Direction lastDir_;
44};
45
46#endif /* end of include guard: PARTY_H_826F91BA */
diff --git a/src/sprite.h b/src/sprite.h index e842192..65a7a66 100644 --- a/src/sprite.h +++ b/src/sprite.h
@@ -1,6 +1,7 @@
1#ifndef SPRITE_H_70503825 1#ifndef SPRITE_H_70503825
2#define SPRITE_H_70503825 2#define SPRITE_H_70503825
3 3
4#include <deque>
4#include <map> 5#include <map>
5#include <string_view> 6#include <string_view>
6#include <vector> 7#include <vector>
@@ -14,6 +15,17 @@ struct SpriteFrame {
14 vec2i size; 15 vec2i size;
15}; 16};
16 17
18enum class CharacterState {
19 Normal,
20 Crouching,
21 Running
22};
23
24struct Movement {
25 vec2i pos;
26 Direction dir;
27};
28
17class Sprite { 29class Sprite {
18public: 30public:
19 31
@@ -30,6 +42,11 @@ public:
30 std::vector<SpriteFrame> frames; 42 std::vector<SpriteFrame> frames;
31 std::vector<std::vector<int>> animations; 43 std::vector<std::vector<int>> animations;
32 std::map<std::string, std::map<Direction, int>> nameDirToAnim; 44 std::map<std::string, std::map<Direction, int>> nameDirToAnim;
45
46 // Character
47 std::vector<int> followers;
48 std::deque<Movement> trail;
49 CharacterState characterState = CharacterState::Normal;
33}; 50};
34 51
35#endif /* end of include guard: SPRITE_H_70503825 */ 52#endif /* end of include guard: SPRITE_H_70503825 */
diff --git a/src/system.h b/src/system.h index c601bc7..6f09d61 100644 --- a/src/system.h +++ b/src/system.h
@@ -4,7 +4,8 @@
4enum class SystemKey { 4enum class SystemKey {
5 Transform, 5 Transform,
6 Camera, 6 Camera,
7 Animation 7 Animation,
8 Character
8}; 9};
9 10
10class System { 11class System {