2016-03-28 13:05:18 +00:00
|
|
|
#include "game.hpp"
|
2016-03-20 13:32:34 +00:00
|
|
|
#include "constants.hpp"
|
2016-03-04 15:29:31 +00:00
|
|
|
|
2016-04-05 23:13:00 +00:00
|
|
|
Game::Game(Manager& manager) : Level(manager),
|
2016-04-06 13:21:46 +00:00
|
|
|
widget_timer(manager, false),
|
2016-04-05 23:13:00 +00:00
|
|
|
next_frame_time(manager.getCurrentTime()),
|
2016-04-06 11:25:33 +00:00
|
|
|
test_mode(false), return_view(nullptr) {}
|
2016-04-03 20:08:11 +00:00
|
|
|
|
2016-04-03 19:05:27 +00:00
|
|
|
Game::~Game() {}
|
2016-03-28 17:57:55 +00:00
|
|
|
|
2016-04-05 18:07:58 +00:00
|
|
|
void Game::load(std::ifstream& file) {
|
|
|
|
Level::load(file);
|
|
|
|
manager.setTitle(getName());
|
|
|
|
}
|
|
|
|
|
2016-04-07 22:19:01 +00:00
|
|
|
bool Game::frame() {
|
|
|
|
// si le dessin de la frame a été interrompu par
|
|
|
|
// le traitement événementiel, on arrête
|
|
|
|
if (Level::frame()) {
|
|
|
|
return true;
|
2016-04-05 23:13:00 +00:00
|
|
|
}
|
|
|
|
|
2016-04-07 22:19:01 +00:00
|
|
|
sf::Time current_time = manager.getCurrentTime();
|
|
|
|
|
2016-04-03 18:19:48 +00:00
|
|
|
if (current_time >= next_frame_time) {
|
|
|
|
// si nous sommes en retard ou dans les temps
|
|
|
|
// on replanifie la prochaine frame
|
|
|
|
next_frame_time += Constants::PHYSICS_TIME;
|
|
|
|
|
|
|
|
// on met à jour la physique d'un cran temporel
|
2016-03-30 12:03:52 +00:00
|
|
|
update();
|
2016-03-04 15:29:31 +00:00
|
|
|
|
2016-04-03 18:19:48 +00:00
|
|
|
// si on a encore suffisamment de temps, on dessine
|
|
|
|
if (current_time < next_frame_time) {
|
|
|
|
draw();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// si nous sommes en avance, on endort le processus
|
|
|
|
// le temps nécessaire pour revenir dans les temps
|
|
|
|
sf::sleep(next_frame_time - current_time);
|
|
|
|
}
|
2016-04-07 22:19:01 +00:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Game::processEvent(const sf::Event& event) {
|
|
|
|
// appui sur espace en mode test : retour à l'éditeur
|
|
|
|
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space && test_mode) {
|
|
|
|
test_mode = false;
|
|
|
|
manager.setView(return_view);
|
|
|
|
|
|
|
|
// demande l'interruption du dessin de la
|
|
|
|
// frame car l'objet risque d'être détruit
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2016-03-09 18:35:40 +00:00
|
|
|
}
|
|
|
|
|
2016-04-06 13:21:46 +00:00
|
|
|
void Game::draw() {
|
|
|
|
Level::draw();
|
|
|
|
|
|
|
|
sf::View window_view = manager.getWindowView();
|
|
|
|
|
|
|
|
// dessin du widget
|
|
|
|
widget_timer.setTimeLeft(getTotalTime());
|
|
|
|
widget_timer.draw(sf::Vector2f(window_view.getSize().x / 2 - 50, 0));
|
|
|
|
}
|
|
|
|
|
2016-03-30 12:03:52 +00:00
|
|
|
void Game::update() {
|
2016-03-28 00:03:56 +00:00
|
|
|
std::vector<CollisionData> colliding;
|
|
|
|
|
|
|
|
// détection des objets en collision
|
2016-04-03 19:05:27 +00:00
|
|
|
for (unsigned int i = 0; i < getObjects().size(); i++) {
|
|
|
|
ObjectPtr objA = getObjects()[i];
|
2016-03-13 18:07:35 +00:00
|
|
|
|
2016-04-03 19:05:27 +00:00
|
|
|
for (unsigned int j = i + 1; j < getObjects().size(); j++) {
|
|
|
|
ObjectPtr objB = getObjects()[j];
|
2016-03-28 00:03:56 +00:00
|
|
|
CollisionData data(*objA, *objB);
|
|
|
|
|
|
|
|
if (objA->detectCollision(*objB, data)) {
|
|
|
|
colliding.push_back(data);
|
|
|
|
}
|
2016-03-13 18:07:35 +00:00
|
|
|
}
|
|
|
|
}
|
2016-03-27 21:43:05 +00:00
|
|
|
|
|
|
|
// intégration des forces dans la vitesse (première moitié)
|
2016-04-03 19:05:27 +00:00
|
|
|
for (unsigned int i = 0; i < getObjects().size(); i++) {
|
|
|
|
getObjects()[i]->updateVelocity(manager, getObjects(), Constants::PHYSICS_TIME.asSeconds() / 2);
|
2016-03-27 21:43:05 +00:00
|
|
|
}
|
|
|
|
|
2016-03-28 00:03:56 +00:00
|
|
|
// résolution des collisions détectées
|
|
|
|
for (unsigned int i = 0; i < colliding.size(); i++) {
|
|
|
|
CollisionData& collided = colliding[i];
|
|
|
|
collided.objA.solveCollision(collided.objB, collided.normal);
|
|
|
|
}
|
|
|
|
|
2016-03-27 21:43:05 +00:00
|
|
|
// intégration de la vitesse dans la position
|
2016-04-03 19:05:27 +00:00
|
|
|
for (unsigned int i = 0; i < getObjects().size(); i++) {
|
|
|
|
getObjects()[i]->updatePosition(Constants::PHYSICS_TIME.asSeconds());
|
2016-03-27 21:43:05 +00:00
|
|
|
}
|
|
|
|
|
2016-03-28 00:03:56 +00:00
|
|
|
// application de la correction positionnelle
|
|
|
|
for (unsigned int i = 0; i < colliding.size(); i++) {
|
|
|
|
CollisionData& collided = colliding[i];
|
|
|
|
collided.objA.positionalCorrection(
|
|
|
|
collided.objB, collided.normal, collided.depth
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-03-27 21:43:05 +00:00
|
|
|
// intégration des forces dans la vitesse (seconde moitié)
|
2016-04-03 19:05:27 +00:00
|
|
|
for (unsigned int i = 0; i < getObjects().size(); i++) {
|
|
|
|
getObjects()[i]->updateVelocity(manager, getObjects(), Constants::PHYSICS_TIME.asSeconds() / 2);
|
2016-03-04 15:29:31 +00:00
|
|
|
}
|
|
|
|
}
|
2016-04-05 23:13:00 +00:00
|
|
|
|
|
|
|
void Game::setTestMode(std::shared_ptr<View> set_return_view) {
|
|
|
|
return_view = set_return_view;
|
|
|
|
test_mode = true;
|
|
|
|
}
|