diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components.cpp | 68 | ||||
-rw-r--r-- | src/components.h | 6 | ||||
-rw-r--r-- | src/entity.h | 3 | ||||
-rw-r--r-- | src/game.cpp | 38 | ||||
-rw-r--r-- | src/game.h | 3 | ||||
-rw-r--r-- | src/renderer.cpp | 5 | ||||
-rw-r--r-- | src/renderer.h | 2 |
7 files changed, 99 insertions, 26 deletions
diff --git a/src/components.cpp b/src/components.cpp index 11350ea..e2eb2ed 100644 --- a/src/components.cpp +++ b/src/components.cpp | |||
@@ -125,25 +125,42 @@ void PhysicsBodyComponent::detectCollision(Game& game, Entity& entity, Entity& c | |||
125 | 125 | ||
126 | void PlayerSpriteComponent::render(Game&, Entity& entity, Texture& buffer) | 126 | void PlayerSpriteComponent::render(Game&, Entity& entity, Texture& buffer) |
127 | { | 127 | { |
128 | animFrame++; | ||
129 | |||
128 | int frame = 0; | 130 | int frame = 0; |
129 | if (isMoving) | 131 | if (isMoving) |
130 | { | 132 | { |
131 | frame += 2; | 133 | frame += 2; |
132 | 134 | ||
133 | if (animFrame < 10) | 135 | if (animFrame % 20 < 10) |
134 | { | 136 | { |
135 | frame += 2; | 137 | frame += 2; |
136 | } | 138 | } |
137 | } | 139 | } |
138 | if (facingLeft) frame++; | 140 | |
141 | if (facingLeft) | ||
142 | { | ||
143 | frame++; | ||
144 | } | ||
145 | |||
146 | double alpha = 1.0; | ||
147 | if (dying && (animFrame % 4 < 2)) | ||
148 | { | ||
149 | alpha = 0.0; | ||
150 | } | ||
139 | 151 | ||
140 | Rectangle src_rect {frame*10, 0, 10, 12}; | 152 | Rectangle src_rect {frame*10, 0, 10, 12}; |
141 | Rectangle dst_rect {(int) entity.position.first, (int) entity.position.second, entity.size.first, entity.size.second}; | 153 | Rectangle dst_rect {(int) entity.position.first, (int) entity.position.second, entity.size.first, entity.size.second}; |
142 | buffer.blit(sprite, src_rect, dst_rect); | 154 | buffer.blit(sprite, src_rect, dst_rect, alpha); |
143 | } | 155 | } |
144 | 156 | ||
145 | void PlayerSpriteComponent::receive(Game&, Entity&, const Message& msg) | 157 | void PlayerSpriteComponent::receive(Game&, Entity&, const Message& msg) |
146 | { | 158 | { |
159 | if (dying) | ||
160 | { | ||
161 | return; | ||
162 | } | ||
163 | |||
147 | if (msg.type == Message::Type::walkLeft) | 164 | if (msg.type == Message::Type::walkLeft) |
148 | { | 165 | { |
149 | facingLeft = true; | 166 | facingLeft = true; |
@@ -155,15 +172,13 @@ void PlayerSpriteComponent::receive(Game&, Entity&, const Message& msg) | |||
155 | } else if (msg.type == Message::Type::stopWalking) | 172 | } else if (msg.type == Message::Type::stopWalking) |
156 | { | 173 | { |
157 | isMoving = false; | 174 | isMoving = false; |
175 | } else if (msg.type == Message::Type::die) | ||
176 | { | ||
177 | dying = true; | ||
178 | isMoving = false; | ||
158 | } | 179 | } |
159 | } | 180 | } |
160 | 181 | ||
161 | void PlayerSpriteComponent::tick(Game&, Entity&) | ||
162 | { | ||
163 | animFrame++; | ||
164 | animFrame %= 20; | ||
165 | } | ||
166 | |||
167 | // Player physics | 182 | // Player physics |
168 | 183 | ||
169 | #define JUMP_VELOCITY(h, l) (-2 * (h) / (l)) | 184 | #define JUMP_VELOCITY(h, l) (-2 * (h) / (l)) |
@@ -220,11 +235,20 @@ void PlayerPhysicsComponent::receive(Game&, Entity& entity, const Message& msg) | |||
220 | entity.position.second = msg.dropAxis - entity.size.second; | 235 | entity.position.second = msg.dropAxis - entity.size.second; |
221 | velocity.second = 0; | 236 | velocity.second = 0; |
222 | } | 237 | } |
238 | } else if (msg.type == Message::Type::die) | ||
239 | { | ||
240 | frozen = true; | ||
223 | } | 241 | } |
224 | } | 242 | } |
225 | 243 | ||
226 | void PlayerPhysicsComponent::tick(Game& game, Entity& entity) | 244 | void PlayerPhysicsComponent::tick(Game& game, Entity& entity) |
227 | { | 245 | { |
246 | // If frozen, do nothing | ||
247 | if (frozen) | ||
248 | { | ||
249 | return; | ||
250 | } | ||
251 | |||
228 | // Continue walking even if blocked earlier | 252 | // Continue walking even if blocked earlier |
229 | if (velocity.first == 0) | 253 | if (velocity.first == 0) |
230 | { | 254 | { |
@@ -302,13 +326,10 @@ void MapRenderComponent::render(Game&, Entity&, Texture& buffer) | |||
302 | 326 | ||
303 | // Map collision | 327 | // Map collision |
304 | 328 | ||
305 | MapCollisionComponent::MapCollisionComponent(const Map& map) | 329 | MapCollisionComponent::MapCollisionComponent(const Map& map) : map(map) |
306 | { | 330 | { |
307 | leftMap = map.getLeftMap(); | 331 | addCollision(-6, 0, GAME_WIDTH, Direction::left, (map.getLeftMap() == nullptr) ? 1 : 2); |
308 | rightMap = map.getRightMap(); | 332 | addCollision(GAME_WIDTH+6, 0, GAME_WIDTH, Direction::right, (map.getRightMap() == nullptr) ? 3 : 2); |
309 | |||
310 | addCollision(-6, 0, GAME_WIDTH, Direction::left, (leftMap == nullptr) ? 1 : 2); | ||
311 | addCollision(GAME_WIDTH+6, 0, GAME_WIDTH, Direction::right, (rightMap == nullptr) ? 3 : 2); | ||
312 | 333 | ||
313 | for (int i=0; i<MAP_WIDTH*(MAP_HEIGHT-1); i++) | 334 | for (int i=0; i<MAP_WIDTH*(MAP_HEIGHT-1); i++) |
314 | { | 335 | { |
@@ -316,7 +337,7 @@ MapCollisionComponent::MapCollisionComponent(const Map& map) | |||
316 | int y = i / MAP_WIDTH; | 337 | int y = i / MAP_WIDTH; |
317 | int tile = map.mapdata()[i]; | 338 | int tile = map.mapdata()[i]; |
318 | 339 | ||
319 | if ((tile > 0) && (!((tile >= 5) && (tile <= 7)))) | 340 | if ((tile > 0) && (tile < 28) && (!((tile >= 5) && (tile <= 7)))) |
320 | { | 341 | { |
321 | addCollision(x*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, Direction::right, 0); | 342 | addCollision(x*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, Direction::right, 0); |
322 | addCollision((x+1)*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, Direction::left, 0); | 343 | addCollision((x+1)*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, Direction::left, 0); |
@@ -325,6 +346,9 @@ MapCollisionComponent::MapCollisionComponent(const Map& map) | |||
325 | } else if ((tile >= 5) && (tile <= 7)) | 346 | } else if ((tile >= 5) && (tile <= 7)) |
326 | { | 347 | { |
327 | addCollision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, Direction::down, 4); | 348 | addCollision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, Direction::down, 4); |
349 | } else if (tile == 42) | ||
350 | { | ||
351 | addCollision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, Direction::down, 5); | ||
328 | } | 352 | } |
329 | } | 353 | } |
330 | } | 354 | } |
@@ -518,11 +542,11 @@ bool MapCollisionComponent::processCollision(Game& game, Entity& collider, Colli | |||
518 | if (dir == Direction::left) | 542 | if (dir == Direction::left) |
519 | { | 543 | { |
520 | collider.position.first = GAME_WIDTH-collider.size.first/2; | 544 | collider.position.first = GAME_WIDTH-collider.size.first/2; |
521 | game.loadMap(*leftMap); | 545 | game.loadMap(*(map.getLeftMap())); |
522 | } else if (dir == Direction::right) | 546 | } else if (dir == Direction::right) |
523 | { | 547 | { |
524 | collider.position.first = -collider.size.first/2; | 548 | collider.position.first = -collider.size.first/2; |
525 | game.loadMap(*rightMap); | 549 | game.loadMap(*(map.getRightMap())); |
526 | } | 550 | } |
527 | 551 | ||
528 | return true; | 552 | return true; |
@@ -541,6 +565,14 @@ bool MapCollisionComponent::processCollision(Game& game, Entity& collider, Colli | |||
541 | msg.dropAxis = collision.axis; | 565 | msg.dropAxis = collision.axis; |
542 | 566 | ||
543 | collider.send(game, msg); | 567 | collider.send(game, msg); |
568 | } else if (collision.type == 5) | ||
569 | { | ||
570 | Message msg(Message::Type::die); | ||
571 | collider.send(game, msg); | ||
572 | |||
573 | game.schedule(FRAMES_PER_SECOND * 0.75, [&] () { | ||
574 | game.loadGame(map); | ||
575 | }); | ||
544 | } | 576 | } |
545 | 577 | ||
546 | return false; | 578 | return false; |
diff --git a/src/components.h b/src/components.h index 2585d73..f182590 100644 --- a/src/components.h +++ b/src/components.h | |||
@@ -31,13 +31,13 @@ class PlayerSpriteComponent : public Component { | |||
31 | public: | 31 | public: |
32 | void render(Game& game, Entity& entity, Texture& buffer); | 32 | void render(Game& game, Entity& entity, Texture& buffer); |
33 | void receive(Game& game, Entity& entity, const Message& msg); | 33 | void receive(Game& game, Entity& entity, const Message& msg); |
34 | void tick(Game& game, Entity& entity); | ||
35 | 34 | ||
36 | private: | 35 | private: |
37 | Texture sprite{"../res/Starla.png"}; | 36 | Texture sprite{"../res/Starla.png"}; |
38 | int animFrame = 0; | 37 | int animFrame = 0; |
39 | bool facingLeft = false; | 38 | bool facingLeft = false; |
40 | bool isMoving = false; | 39 | bool isMoving = false; |
40 | bool dying = false; | ||
41 | }; | 41 | }; |
42 | 42 | ||
43 | class PlayerPhysicsComponent : public Component { | 43 | class PlayerPhysicsComponent : public Component { |
@@ -54,6 +54,7 @@ class PlayerPhysicsComponent : public Component { | |||
54 | double jump_gravity_short; | 54 | double jump_gravity_short; |
55 | int direction = 0; | 55 | int direction = 0; |
56 | bool canDrop = false; | 56 | bool canDrop = false; |
57 | bool frozen = false; | ||
57 | }; | 58 | }; |
58 | 59 | ||
59 | class MapRenderComponent : public Component { | 60 | class MapRenderComponent : public Component { |
@@ -89,8 +90,7 @@ class MapCollisionComponent : public Component { | |||
89 | std::list<Collision> right_collisions; | 90 | std::list<Collision> right_collisions; |
90 | std::list<Collision> up_collisions; | 91 | std::list<Collision> up_collisions; |
91 | std::list<Collision> down_collisions; | 92 | std::list<Collision> down_collisions; |
92 | const Map* leftMap; | 93 | const Map& map; |
93 | const Map* rightMap; | ||
94 | }; | 94 | }; |
95 | 95 | ||
96 | #endif | 96 | #endif |
diff --git a/src/entity.h b/src/entity.h index 266fe11..772c98b 100644 --- a/src/entity.h +++ b/src/entity.h | |||
@@ -21,7 +21,8 @@ class Message { | |||
21 | stopJump, | 21 | stopJump, |
22 | drop, | 22 | drop, |
23 | canDrop, | 23 | canDrop, |
24 | cantDrop | 24 | cantDrop, |
25 | die | ||
25 | }; | 26 | }; |
26 | 27 | ||
27 | Message(Type type) : type(type) {} | 28 | Message(Type type) : type(type) {} |
diff --git a/src/game.cpp b/src/game.cpp index e392923..043c82b 100644 --- a/src/game.cpp +++ b/src/game.cpp | |||
@@ -77,6 +77,19 @@ void Game::execute(GLFWwindow* window) | |||
77 | { | 77 | { |
78 | entity->tick(*this); | 78 | entity->tick(*this); |
79 | } | 79 | } |
80 | |||
81 | // Do any scheduled tasks | ||
82 | for (auto& task : scheduled) | ||
83 | { | ||
84 | task.first--; | ||
85 | |||
86 | if (task.first == 0) | ||
87 | { | ||
88 | task.second(); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | scheduled.remove_if([] (std::pair<int, std::function<void ()>> value) { return value.first == 0; }); | ||
80 | 93 | ||
81 | // Do rendering | 94 | // Do rendering |
82 | buffer.fill(buffer.entirety(), 0, 0, 0); | 95 | buffer.fill(buffer.entirety(), 0, 0, 0); |
@@ -121,10 +134,31 @@ void Game::saveGame(const Map& map, std::pair<double, double> position) | |||
121 | 134 | ||
122 | void Game::loadGame(const Map& curMap) | 135 | void Game::loadGame(const Map& curMap) |
123 | { | 136 | { |
124 | if (&curMap != save.map) | 137 | if (&curMap == save.map) |
125 | { | 138 | { |
126 | loadMap(*(save.map)); | 139 | entities.remove(player); |
127 | } | 140 | } |
128 | 141 | ||
142 | player = std::make_shared<Entity>(); | ||
129 | player->position = save.position; | 143 | player->position = save.position; |
144 | player->size = std::make_pair(10.0,12.0); | ||
145 | |||
146 | auto player_input = std::make_shared<UserMovementComponent>(); | ||
147 | player->addComponent(player_input); | ||
148 | |||
149 | auto player_physics = std::make_shared<PlayerPhysicsComponent>(); | ||
150 | player->addComponent(player_physics); | ||
151 | |||
152 | auto player_anim = std::make_shared<PlayerSpriteComponent>(); | ||
153 | player->addComponent(player_anim); | ||
154 | |||
155 | if (&curMap != save.map) | ||
156 | { | ||
157 | loadMap(*(save.map)); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | void Game::schedule(int frames, std::function<void ()>&& callback) | ||
162 | { | ||
163 | scheduled.emplace(begin(scheduled), frames, callback); | ||
130 | } | 164 | } |
diff --git a/src/game.h b/src/game.h index 69b8df7..cea154a 100644 --- a/src/game.h +++ b/src/game.h | |||
@@ -6,6 +6,7 @@ class Game; | |||
6 | #include "map.h" | 6 | #include "map.h" |
7 | #include <memory> | 7 | #include <memory> |
8 | #include "entity.h" | 8 | #include "entity.h" |
9 | #include <functional> | ||
9 | 10 | ||
10 | const int TILE_WIDTH = 8; | 11 | const int TILE_WIDTH = 8; |
11 | const int TILE_HEIGHT = 8; | 12 | const int TILE_HEIGHT = 8; |
@@ -30,6 +31,7 @@ class Game { | |||
30 | void detectCollision(Entity& collider, std::pair<double, double> old_position); | 31 | void detectCollision(Entity& collider, std::pair<double, double> old_position); |
31 | void saveGame(const Map& map, std::pair<double, double> position); | 32 | void saveGame(const Map& map, std::pair<double, double> position); |
32 | void loadGame(const Map& curMap); | 33 | void loadGame(const Map& curMap); |
34 | void schedule(int frames, std::function<void ()>&& callback); | ||
33 | 35 | ||
34 | bool shouldQuit = false; | 36 | bool shouldQuit = false; |
35 | private: | 37 | private: |
@@ -42,6 +44,7 @@ class Game { | |||
42 | Map m{"../maps/embarass.txt"}; | 44 | Map m{"../maps/embarass.txt"}; |
43 | Map m2{"../maps/second.txt"}; | 45 | Map m2{"../maps/second.txt"}; |
44 | Savefile save; | 46 | Savefile save; |
47 | std::list<std::pair<int, std::function<void ()>>> scheduled; | ||
45 | }; | 48 | }; |
46 | 49 | ||
47 | #endif | 50 | #endif |
diff --git a/src/renderer.cpp b/src/renderer.cpp index f01d72a..64c9fd0 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp | |||
@@ -613,7 +613,7 @@ void Texture::fill(Rectangle dstrect, int r, int g, int b) | |||
613 | glDeleteBuffers(1, &vertexbuffer); | 613 | glDeleteBuffers(1, &vertexbuffer); |
614 | } | 614 | } |
615 | 615 | ||
616 | void Texture::blit(const Texture& srctex, Rectangle srcrect, Rectangle dstrect) | 616 | void Texture::blit(const Texture& srctex, Rectangle srcrect, Rectangle dstrect, double alpha) |
617 | { | 617 | { |
618 | if (!rendererInitialized) | 618 | if (!rendererInitialized) |
619 | { | 619 | { |
@@ -621,6 +621,8 @@ void Texture::blit(const Texture& srctex, Rectangle srcrect, Rectangle dstrect) | |||
621 | exit(-1); | 621 | exit(-1); |
622 | } | 622 | } |
623 | 623 | ||
624 | alpha = glm::clamp(alpha, 0.0, 1.0); | ||
625 | |||
624 | // Target the framebuffer | 626 | // Target the framebuffer |
625 | glBindFramebuffer(GL_FRAMEBUFFER, generic_framebuffer); | 627 | glBindFramebuffer(GL_FRAMEBUFFER, generic_framebuffer); |
626 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texID, 0); | 628 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texID, 0); |
@@ -670,6 +672,7 @@ void Texture::blit(const Texture& srctex, Rectangle srcrect, Rectangle dstrect) | |||
670 | glActiveTexture(GL_TEXTURE0); | 672 | glActiveTexture(GL_TEXTURE0); |
671 | glBindTexture(GL_TEXTURE_2D, srctex.texID); | 673 | glBindTexture(GL_TEXTURE_2D, srctex.texID); |
672 | glUniform1i(glGetUniformLocation(blitShader, "srctex"), 0); | 674 | glUniform1i(glGetUniformLocation(blitShader, "srctex"), 0); |
675 | glUniform1f(glGetUniformLocation(blitShader, "alpha"), alpha); | ||
673 | 676 | ||
674 | // Blit! | 677 | // Blit! |
675 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 678 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
diff --git a/src/renderer.h b/src/renderer.h index 377b9ee..90ec101 100644 --- a/src/renderer.h +++ b/src/renderer.h | |||
@@ -21,7 +21,7 @@ class Texture { | |||
21 | Texture& operator= (Texture tex); | 21 | Texture& operator= (Texture tex); |
22 | friend void swap(Texture& tex1, Texture& tex2); | 22 | friend void swap(Texture& tex1, Texture& tex2); |
23 | void fill(Rectangle loc, int r, int g, int b); | 23 | void fill(Rectangle loc, int r, int g, int b); |
24 | void blit(const Texture& src, Rectangle srcrect, Rectangle dstrect); | 24 | void blit(const Texture& src, Rectangle srcrect, Rectangle dstrect, double alpha = 1.0); |
25 | void renderScreen() const; | 25 | void renderScreen() const; |
26 | Rectangle entirety() const; | 26 | Rectangle entirety() const; |
27 | 27 | ||