summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components.cpp68
-rw-r--r--src/components.h6
-rw-r--r--src/entity.h3
-rw-r--r--src/game.cpp38
-rw-r--r--src/game.h3
-rw-r--r--src/renderer.cpp5
-rw-r--r--src/renderer.h2
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
126void PlayerSpriteComponent::render(Game&, Entity& entity, Texture& buffer) 126void 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
145void PlayerSpriteComponent::receive(Game&, Entity&, const Message& msg) 157void 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
161void 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
226void PlayerPhysicsComponent::tick(Game& game, Entity& entity) 244void 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
305MapCollisionComponent::MapCollisionComponent(const Map& map) 329MapCollisionComponent::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
43class PlayerPhysicsComponent : public Component { 43class 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
59class MapRenderComponent : public Component { 60class 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
122void Game::loadGame(const Map& curMap) 135void 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
161void 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
10const int TILE_WIDTH = 8; 11const int TILE_WIDTH = 8;
11const int TILE_HEIGHT = 8; 12const 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
616void Texture::blit(const Texture& srctex, Rectangle srcrect, Rectangle dstrect) 616void 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