summary refs log tree commit diff stats
path: root/src/game.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game.cpp')
-rw-r--r--src/game.cpp220
1 files changed, 71 insertions, 149 deletions
diff --git a/src/game.cpp b/src/game.cpp index 673c804..39bb3f1 100644 --- a/src/game.cpp +++ b/src/game.cpp
@@ -1,178 +1,100 @@
1#include "game.h" 1#include "game.h"
2#include <cstdlib> 2#include "components/animatable.h"
3#include "components/transformable.h"
4#include "components/controllable.h"
5#include "components/ponderable.h"
6#include "components/orientable.h"
7#include "systems/controlling.h"
8#include "systems/pondering.h"
9#include "systems/animating.h"
10#include "systems/mapping.h"
11#include "systems/orienting.h"
12#include "animation.h"
3#include "renderer.h" 13#include "renderer.h"
4#include "muxer.h"
5#include "map.h"
6#include "components/user_movement.h"
7#include "components/player_physics.h"
8#include "components/player_sprite.h"
9#include "components/map_render.h"
10#include "components/map_collision.h"
11#include "consts.h" 14#include "consts.h"
12 15
13Game::Game(const char* mapfile) : world(mapfile)
14{
15 // Set up entities
16 player = std::make_shared<Entity>();
17 player->position = world.getStartingPosition();
18 player->size = std::make_pair(10.0,12.0);
19
20 auto player_input = std::make_shared<UserMovementComponent>();
21 player->addComponent(player_input);
22
23 auto player_physics = std::make_shared<PlayerPhysicsComponent>();
24 player->addComponent(player_physics);
25
26 auto player_anim = std::make_shared<PlayerSpriteComponent>();
27 player->addComponent(player_anim);
28
29 const Map& startingMap = world.getStartingMap();
30 save = {&startingMap, player->position};
31
32 loadMap(startingMap, player->position);
33}
34
35void key_callback(GLFWwindow* window, int key, int, int action, int) 16void key_callback(GLFWwindow* window, int key, int, int action, int)
36{ 17{
37 Game* game = (Game*) glfwGetWindowUserPointer(window); 18 Game& game = *((Game*) glfwGetWindowUserPointer(window));
38 19
39 if ((key == GLFW_KEY_ESCAPE) && (action == GLFW_PRESS)) 20 if ((action == GLFW_PRESS) && (key == GLFW_KEY_ESCAPE))
40 {
41 game->shouldQuit = true;
42 }
43
44 for (auto entity : game->entities)
45 { 21 {
46 entity->input(*game, key, action); 22 game.shouldQuit_ = true;
23
24 return;
47 } 25 }
26
27 game.systemManager_.input(key, action);
48} 28}
49 29
50void Game::execute(GLFWwindow* window) 30Game::Game(
31 GLFWwindow* window) :
32 window_(window),
33 world_("res/maps.xml")
51{ 34{
35 systemManager_.emplaceSystem<ControllingSystem>(*this);
36 systemManager_.emplaceSystem<OrientingSystem>(*this);
37 systemManager_.emplaceSystem<PonderingSystem>(*this);
38 systemManager_.emplaceSystem<MappingSystem>(*this);
39 systemManager_.emplaceSystem<AnimatingSystem>(*this);
40
41 int player = entityManager_.emplaceEntity();
42
43 AnimationSet playerGraphics {"res/Starla2.bmp", 10, 12, 6};
44 playerGraphics.emplaceAnimation("stillLeft", 3, 1, 1);
45 playerGraphics.emplaceAnimation("stillRight", 0, 1, 1);
46 playerGraphics.emplaceAnimation("walkingLeft", 4, 2, 10);
47 playerGraphics.emplaceAnimation("walkingRight", 1, 2, 10);
48
49 entityManager_.emplaceComponent<AnimatableComponent>(
50 player,
51 std::move(playerGraphics),
52 "stillLeft");
53
54 entityManager_.emplaceComponent<TransformableComponent>(
55 player,
56 203, 44, 10, 12);
57
58 systemManager_.getSystem<PonderingSystem>().initializeBody(
59 player,
60 PonderableComponent::Type::freefalling);
61
62 entityManager_.emplaceComponent<ControllableComponent>(player);
63 entityManager_.emplaceComponent<OrientableComponent>(player);
64
65 systemManager_.getSystem<MappingSystem>().loadMap(world_.getStartingMapId());
66
52 glfwSwapInterval(1); 67 glfwSwapInterval(1);
53 glfwSetWindowUserPointer(window, this); 68 glfwSetWindowUserPointer(window_, this);
54 glfwSetKeyCallback(window, key_callback); 69 glfwSetKeyCallback(window_, key_callback);
55 70}
56 Texture buffer(GAME_WIDTH, GAME_HEIGHT);
57 71
72void Game::execute()
73{
58 double lastTime = glfwGetTime(); 74 double lastTime = glfwGetTime();
59 const double dt = 0.01; 75 const double dt = 0.01;
60 double accumulator = 0.0; 76 double accumulator = 0.0;
61 77 Texture texture(GAME_WIDTH, GAME_HEIGHT);
62 while (!(shouldQuit || glfwWindowShouldClose(window))) 78
79 while (!(shouldQuit_ || glfwWindowShouldClose(window_)))
63 { 80 {
64 double currentTime = glfwGetTime(); 81 double currentTime = glfwGetTime();
65 double frameTime = currentTime - lastTime; 82 double frameTime = currentTime - lastTime;
66 lastTime = currentTime; 83 lastTime = currentTime;
67 84
68 // Should we load a new world?
69 if (newWorld)
70 {
71 newWorld = false;
72 entities.clear();
73 entities = std::move(nextEntities);
74
75 player->position = nextPosition;
76 }
77
78 // Handle input
79 glfwPollEvents(); 85 glfwPollEvents();
80 86
81 // Tick!
82 accumulator += frameTime; 87 accumulator += frameTime;
83 while (accumulator >= dt) 88 while (accumulator >= dt)
84 { 89 {
85 for (auto entity : entities) 90 systemManager_.tick(dt);
86 { 91
87 entity->tick(*this, dt);
88 }
89
90 accumulator -= dt; 92 accumulator -= dt;
91 } 93 }
92
93 // Do any scheduled tasks
94 for (auto& task : scheduled)
95 {
96 task.first -= frameTime;
97
98 if (task.first <= 0)
99 {
100 task.second();
101 }
102 }
103
104 scheduled.remove_if([] (std::pair<double, std::function<void ()>> value) { return value.first <= 0; });
105
106 // Do rendering
107 buffer.fill(buffer.entirety(), 0, 0, 0);
108 for (auto entity : entities)
109 {
110 entity->render(*this, buffer);
111 }
112
113 buffer.renderScreen();
114 }
115}
116
117void Game::loadMap(const Map& map, std::pair<double, double> position)
118{
119 auto mapEn = std::make_shared<Entity>();
120
121 auto map_render = std::make_shared<MapRenderComponent>(map);
122 mapEn->addComponent(map_render);
123
124 auto map_collision = std::make_shared<MapCollisionComponent>(map);
125 mapEn->addComponent(map_collision);
126
127 // Map in the back, player on top, rest of entities in between
128 nextEntities.clear();
129 nextEntities.push_back(mapEn);
130 map.createEntities(nextEntities);
131 nextEntities.push_back(player);
132
133 newWorld = true;
134
135 currentMap = &map;
136 nextPosition = position;
137}
138 94
139void Game::detectCollision(Entity& collider, std::pair<double, double> old_position) 95 // Render
140{ 96 texture.fill(texture.entirety(), 0, 0, 0);
141 for (auto entity : entities) 97 systemManager_.render(texture);
142 { 98 texture.renderScreen();
143 entity->detectCollision(*this, collider, old_position);
144 } 99 }
145} 100}
146
147void Game::saveGame()
148{
149 save = {currentMap, player->position};
150}
151
152void Game::schedule(double time, std::function<void ()> callback)
153{
154 scheduled.emplace_front(time, std::move(callback));
155}
156
157void Game::playerDie()
158{
159 player->send(*this, Message::Type::die);
160
161 playSound("res/Hit_Hurt5.wav", 0.25);
162
163 schedule(0.75, [&] () {
164 if (*currentMap != *save.map)
165 {
166 loadMap(*save.map, save.position);
167 } else {
168 player->position = save.position;
169 }
170
171 player->send(*this, Message::Type::stopDying);
172 });
173}
174
175const World& Game::getWorld() const
176{
177 return world;
178}