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.cpp200
1 files changed, 50 insertions, 150 deletions
diff --git a/src/game.cpp b/src/game.cpp index 673c804..eb57bc6 100644 --- a/src/game.cpp +++ b/src/game.cpp
@@ -1,178 +1,78 @@
1#include "game.h" 1#include "game.h"
2#include <cstdlib> 2#include "systems/controlling.h"
3#include "renderer.h" 3#include "systems/pondering.h"
4#include "muxer.h" 4#include "systems/animating.h"
5#include "map.h" 5#include "systems/mapping.h"
6#include "components/user_movement.h" 6#include "systems/orienting.h"
7#include "components/player_physics.h" 7#include "systems/playing.h"
8#include "components/player_sprite.h" 8#include "systems/scheduling.h"
9#include "components/map_render.h" 9#include "systems/realizing.h"
10#include "components/map_collision.h" 10#include "systems/scripting.h"
11#include "consts.h" 11#include "consts.h"
12 12
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) 13void key_callback(GLFWwindow* window, int key, int, int action, int)
36{ 14{
37 Game* game = (Game*) glfwGetWindowUserPointer(window); 15 Game& game = *static_cast<Game*>(glfwGetWindowUserPointer(window));
38 16
39 if ((key == GLFW_KEY_ESCAPE) && (action == GLFW_PRESS)) 17 if ((action == GLFW_PRESS) && (key == GLFW_KEY_ESCAPE))
40 {
41 game->shouldQuit = true;
42 }
43
44 for (auto entity : game->entities)
45 { 18 {
46 entity->input(*game, key, action); 19 game.shouldQuit_ = true;
20
21 return;
47 } 22 }
23
24 game.systemManager_.input(key, action);
48} 25}
49 26
50void Game::execute(GLFWwindow* window) 27Game::Game(std::mt19937& rng) : rng_(rng)
51{ 28{
29 systemManager_.emplaceSystem<PlayingSystem>(*this);
30 systemManager_.emplaceSystem<SchedulingSystem>(*this);
31 systemManager_.emplaceSystem<ControllingSystem>(*this);
32 systemManager_.emplaceSystem<ScriptingSystem>(*this);
33 systemManager_.emplaceSystem<OrientingSystem>(*this);
34 systemManager_.emplaceSystem<PonderingSystem>(*this);
35 systemManager_.emplaceSystem<MappingSystem>(*this);
36 systemManager_.emplaceSystem<AnimatingSystem>(*this);
37
38 systemManager_.emplaceSystem<RealizingSystem>(*this,
39 "res/maps.xml",
40 "res/entities.xml");
41
42 systemManager_.getSystem<PlayingSystem>().initPlayer();
43
52 glfwSwapInterval(1); 44 glfwSwapInterval(1);
53 glfwSetWindowUserPointer(window, this); 45 glfwSetWindowUserPointer(renderer_.getWindow().getHandle(), this);
54 glfwSetKeyCallback(window, key_callback); 46 glfwSetKeyCallback(renderer_.getWindow().getHandle(), key_callback);
55 47}
56 Texture buffer(GAME_WIDTH, GAME_HEIGHT);
57 48
49void Game::execute()
50{
58 double lastTime = glfwGetTime(); 51 double lastTime = glfwGetTime();
59 const double dt = 0.01; 52 const double dt = 0.01;
60 double accumulator = 0.0; 53 double accumulator = 0.0;
61 54 Texture texture(GAME_WIDTH, GAME_HEIGHT);
62 while (!(shouldQuit || glfwWindowShouldClose(window))) 55
56 while (!(shouldQuit_ ||
57 glfwWindowShouldClose(renderer_.getWindow().getHandle())))
63 { 58 {
64 double currentTime = glfwGetTime(); 59 double currentTime = glfwGetTime();
65 double frameTime = currentTime - lastTime; 60 double frameTime = currentTime - lastTime;
66 lastTime = currentTime; 61 lastTime = currentTime;
67 62
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(); 63 glfwPollEvents();
80 64
81 // Tick!
82 accumulator += frameTime; 65 accumulator += frameTime;
83 while (accumulator >= dt) 66 while (accumulator >= dt)
84 { 67 {
85 for (auto entity : entities) 68 systemManager_.tick(dt);
86 { 69
87 entity->tick(*this, dt);
88 }
89
90 accumulator -= dt; 70 accumulator -= dt;
91 } 71 }
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 72
113 buffer.renderScreen(); 73 // Render
74 renderer_.fill(texture, texture.entirety(), 0, 0, 0);
75 systemManager_.render(texture);
76 renderer_.renderScreen(texture);
114 } 77 }
115} 78}
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
139void Game::detectCollision(Entity& collider, std::pair<double, double> old_position)
140{
141 for (auto entity : entities)
142 {
143 entity->detectCollision(*this, collider, old_position);
144 }
145}
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}