skizzle/src/game.cpp

139 lines
4.1 KiB
C++
Raw Normal View History

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
#include <cmath>
#include <queue>
2016-03-04 15:29:31 +00:00
2016-03-28 13:05:18 +00:00
Game::Game() : window(
sf::VideoMode(704, 480), "Projet CMI", sf::Style::Default,
sf::ContextSettings(0, 0, 2)
2016-03-28 13:05:18 +00:00
), view(sf::FloatRect(0, 0, 704, 480)) {
2016-03-04 15:29:31 +00:00
window.setVerticalSyncEnabled(true);
2016-03-20 13:28:13 +00:00
// mise en place de la caméra
2016-03-20 21:19:53 +00:00
view.setSize(704, 480);
2016-03-20 13:28:13 +00:00
window.setView(view);
}
2016-03-04 15:29:31 +00:00
2016-03-28 13:05:18 +00:00
void Game::start() {
2016-03-20 13:32:34 +00:00
float accumulator = 0;
if (!music.openFromFile("./res/music_lvl1.wav"))
{
// erreur
}
music.play();
music.setVolume(15);
music.setLoop(true);
2016-03-20 13:32:34 +00:00
2016-03-04 15:29:31 +00:00
// boucle d'événements sur la fenêtre
while (window.isOpen()) {
sf::Event event;
// traitement des évènements reçus
while (window.pollEvent(event)) {
// fermeture de la fenêtre
if (event.type == sf::Event::Closed) {
window.close();
}
// suivi de l'enfoncement et du relâchement des touches
2016-03-04 15:29:31 +00:00
if (event.type == sf::Event::KeyPressed) {
state.keys[event.key.code] = true;
2016-03-04 15:29:31 +00:00
}
if (event.type == sf::Event::KeyReleased) {
state.keys[event.key.code] = false;
2016-03-04 15:29:31 +00:00
}
2016-03-25 19:56:04 +00:00
// lorsque la fenêtre est redimensionnée par l'utilisateur,
// mise à jour de la caméra en fonction de la taille de la fenêtre
if (event.type == sf::Event::Resized) {
sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
window.setView(sf::View(visibleArea));
}
2016-03-04 15:29:31 +00:00
}
2016-03-20 13:28:13 +00:00
float frame = clock.restart().asSeconds();
accumulator += frame;
// tant qu'il reste du temps à passer,
// effectuer la simulation physique étape par étape
while (accumulator >= Constants::PHYSICS_TIME) {
accumulator -= Constants::PHYSICS_TIME;
update();
}
2016-03-04 15:29:31 +00:00
draw();
}
}
2016-03-28 13:05:18 +00:00
void Game::addObject(Object& object) {
state.objects.push_back(&object);
}
2016-03-28 13:05:18 +00:00
void Game::update() {
std::vector<CollisionData> colliding;
// détection des objets en collision
for (unsigned int i = 0; i < state.objects.size(); i++) {
Object* objA = state.objects[i];
for (unsigned int j = i + 1; j < state.objects.size(); j++) {
Object* objB = state.objects[j];
CollisionData data(*objA, *objB);
if (objA->detectCollision(*objB, data)) {
colliding.push_back(data);
}
}
}
// intégration des forces dans la vitesse (première moitié)
for (unsigned int i = 0; i < state.objects.size(); i++) {
state.objects[i]->updateVelocity(state, Constants::PHYSICS_TIME / 2);
}
// 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);
}
// intégration de la vitesse dans la position
for (unsigned int i = 0; i < state.objects.size(); i++) {
state.objects[i]->updatePosition(state, Constants::PHYSICS_TIME);
}
// 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
);
}
// intégration des forces dans la vitesse (seconde moitié)
for (unsigned int i = 0; i < state.objects.size(); i++) {
state.objects[i]->updateVelocity(state, Constants::PHYSICS_TIME / 2);
}
2016-03-04 15:29:31 +00:00
}
2016-03-28 13:05:18 +00:00
void Game::draw() {
// efface la scène précédente et dessine la couche de fond
2016-03-04 15:29:31 +00:00
window.clear(sf::Color(66, 165, 245));
// chargement de la file d'affichage des objets
std::priority_queue<Object*, std::vector<Object*>, ObjectCompare> display_queue;
for (unsigned int i = 0; i < state.objects.size(); i++) {
display_queue.push(state.objects[i]);
2016-03-04 15:29:31 +00:00
}
// dessin des objets de la file d'affichage couche par couche
while (!display_queue.empty()) {
display_queue.top()->draw(window, resources);
display_queue.pop();
2016-03-04 15:29:31 +00:00
}
2016-03-10 18:18:50 +00:00
window.display();
2016-03-04 15:29:31 +00:00
}