Centralisation de l'état dans un gestionnaire principal
Démarrage de l'abstraction nécessaire à l'utilisation de plusieurs vues
This commit is contained in:
parent
c505437e01
commit
dde1280573
|
@ -3,11 +3,10 @@
|
|||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "object.hpp"
|
||||
#include "engine_state.hpp"
|
||||
|
||||
class Block : public Object {
|
||||
private:
|
||||
sf::Sprite sprite;
|
||||
mutable sf::Sprite sprite;
|
||||
|
||||
public:
|
||||
Block(float x, float y);
|
||||
|
@ -15,18 +14,18 @@ public:
|
|||
/**
|
||||
* Dessin du bloc dans la fenêtre donnée
|
||||
*/
|
||||
virtual void draw(sf::RenderWindow& window, ResourceManager& resources);
|
||||
virtual void draw(Manager& manager);
|
||||
|
||||
/**
|
||||
* Récupère la boîte englobante de l'objet
|
||||
*/
|
||||
std::unique_ptr<sf::FloatRect> getAABB();
|
||||
virtual std::unique_ptr<sf::FloatRect> getAABB() const;
|
||||
|
||||
/**
|
||||
* Récupère l'identifiant de type de cet objet
|
||||
*/
|
||||
static constexpr unsigned int TYPE_ID = 1;
|
||||
unsigned int getTypeId();
|
||||
virtual unsigned int getTypeId() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
#ifndef __PTF_ENGINE_STATE_HPP__
|
||||
#define __PTF_ENGINE_STATE_HPP__
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
// pré-déclaration de Object pour éviter les erreurs
|
||||
// de compilation Object est définie dans object.hpp
|
||||
class Object;
|
||||
|
||||
/**
|
||||
* Structure qui retient l'état actuel du moteur
|
||||
* Cette structure est passée aux objets pour qu'ils se
|
||||
* mettent à jour en fonction de cet état
|
||||
*/
|
||||
struct EngineState {
|
||||
std::vector<Object*> objects;
|
||||
std::array<bool, sf::Keyboard::KeyCount> keys;
|
||||
|
||||
EngineState() {
|
||||
// aucune touche n'est enfoncée au démarrage
|
||||
keys.fill(false);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,44 +1,43 @@
|
|||
#ifndef __PTF_GAME_HPP__
|
||||
#define __PTF_GAME_HPP__
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/Audio.hpp>
|
||||
#include "view.hpp"
|
||||
#include "object.hpp"
|
||||
#include "engine_state.hpp"
|
||||
#include "manager.hpp"
|
||||
#include "resource_manager.hpp"
|
||||
|
||||
/**
|
||||
* La classe Game gère l'affichage et les objets
|
||||
* d'une partie de jeu
|
||||
*/
|
||||
class Game {
|
||||
class Game : public View {
|
||||
private:
|
||||
sf::Clock clock;
|
||||
sf::RenderWindow window;
|
||||
sf::View view;
|
||||
sf::Music music;
|
||||
|
||||
EngineState state;
|
||||
ResourceManager resources;
|
||||
float accumulator;
|
||||
std::vector<Object*> objects;
|
||||
|
||||
/**
|
||||
* Met à jour les objets du jeu pour
|
||||
* qu'ils s'adaptent au nouvel état
|
||||
*/
|
||||
void update();
|
||||
void update(const Manager& manager);
|
||||
|
||||
/**
|
||||
* Dessine la scène du jeu couche par couche
|
||||
*/
|
||||
void draw();
|
||||
void draw(Manager& manager);
|
||||
|
||||
public:
|
||||
Game();
|
||||
|
||||
/**
|
||||
* Démarre la boucle principale du jeu
|
||||
* Demande le passage à la frame suivante sur
|
||||
* cette vue
|
||||
*/
|
||||
void start();
|
||||
void frame(Manager& manager);
|
||||
|
||||
/**
|
||||
* Ajoute un nouvel objet à la liste des objets du jeu
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef __PTF_MANAGER_HPP__
|
||||
#define __PTF_MANAGER_HPP__
|
||||
|
||||
#include "resource_manager.hpp"
|
||||
#include "view.hpp"
|
||||
|
||||
/**
|
||||
* Gestionnaire principal de toutes les vues et
|
||||
* ressources du jeu
|
||||
*/
|
||||
class Manager {
|
||||
private:
|
||||
sf::RenderWindow window;
|
||||
sf::Clock clock;
|
||||
|
||||
float elapsed_time;
|
||||
ResourceManager resource_manager;
|
||||
std::array<bool, sf::Keyboard::KeyCount> keys;
|
||||
|
||||
public:
|
||||
// FIXME: devrait être privé
|
||||
View* view;
|
||||
|
||||
Manager();
|
||||
|
||||
/**
|
||||
* Démarre la boucle principale du jeu
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* Renvoie la fenêtre actuellement utilisée pour le dessin
|
||||
*/
|
||||
sf::RenderWindow& getWindow();
|
||||
|
||||
/**
|
||||
* Renvoie le temps écoulé entre la frame précédente
|
||||
* et la frame actuelle
|
||||
*/
|
||||
float getElapsedTime() const;
|
||||
|
||||
/**
|
||||
* Renvoie le gestionnaire de ressources
|
||||
*/
|
||||
ResourceManager& getResourceManager();
|
||||
|
||||
/**
|
||||
* Renvoie un booléen attestant de l'appui sur la
|
||||
* touche donnée ou non
|
||||
*/
|
||||
bool isKeyPressed(sf::Keyboard::Key key) const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -3,13 +3,10 @@
|
|||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <memory>
|
||||
#include "engine_state.hpp"
|
||||
#include "collision_data.hpp"
|
||||
#include "manager.hpp"
|
||||
#include "resource_manager.hpp"
|
||||
|
||||
class Block;
|
||||
class Player;
|
||||
|
||||
class Object {
|
||||
private:
|
||||
sf::Vector2f acceleration;
|
||||
|
@ -20,7 +17,7 @@ private:
|
|||
sf::VertexArray velocity_line;
|
||||
|
||||
float mass;
|
||||
float inv_mass;
|
||||
mutable float inv_mass;
|
||||
float charge;
|
||||
float restitution;
|
||||
float static_friction;
|
||||
|
@ -31,7 +28,7 @@ protected:
|
|||
/**
|
||||
* Calcule les forces appliquées à l'objet
|
||||
*/
|
||||
virtual sf::Vector2f getForces(EngineState& state);
|
||||
virtual sf::Vector2f getForces(const Manager& manager, const std::vector<Object*>& objects) const;
|
||||
|
||||
public:
|
||||
Object(float x, float y);
|
||||
|
@ -39,32 +36,32 @@ public:
|
|||
/**
|
||||
* Dessine l'objet dans la fenêtre donnée
|
||||
*/
|
||||
virtual void draw(sf::RenderWindow& window, ResourceManager& resources);
|
||||
virtual void draw(Manager& manager);
|
||||
|
||||
/**
|
||||
* Met à jour la vitesse de l'objet selon les
|
||||
* forces qui lui sont appliquées
|
||||
*/
|
||||
void updateVelocity(EngineState& state, float delta);
|
||||
void updateVelocity(const Manager& manager, const std::vector<Object*>& objects, float delta);
|
||||
|
||||
/**
|
||||
* Met à jour la position de l'objet selon sa
|
||||
* vitesse actuelle
|
||||
*/
|
||||
void updatePosition(EngineState& state, float delta);
|
||||
void updatePosition(float delta);
|
||||
|
||||
/**
|
||||
* Détecte s'il y a collision entre cet objet
|
||||
* et l'objet passé en paramètre
|
||||
*/
|
||||
bool detectCollision(Object& obj, CollisionData& data);
|
||||
bool detectCollision(const Object& obj, CollisionData& data) const;
|
||||
|
||||
/**
|
||||
* Résolution de la collision entre cet objet
|
||||
* et l'objet passé en paramètre selon la normale
|
||||
* donnée
|
||||
*/
|
||||
void solveCollision(Object& obj, sf::Vector2f normal);
|
||||
void solveCollision(Object& obj, const sf::Vector2f& normal);
|
||||
|
||||
/**
|
||||
* Application de la correction positionnelle sur
|
||||
|
@ -74,27 +71,27 @@ public:
|
|||
* les objets peuvent accumuler une erreur de positionnement
|
||||
* qui les fait "plonger" les uns dans les autres
|
||||
*/
|
||||
void positionalCorrection(Object& obj, sf::Vector2f normal, float depth);
|
||||
void positionalCorrection(Object& obj, const sf::Vector2f& normal, float depth);
|
||||
|
||||
/**
|
||||
* Récupère la boîte englobante de l'objet
|
||||
*/
|
||||
virtual std::unique_ptr<sf::FloatRect> getAABB() = 0;
|
||||
virtual std::unique_ptr<sf::FloatRect> getAABB() const = 0;
|
||||
|
||||
/**
|
||||
* Récupère l'identifiant de type de cet objet
|
||||
*/
|
||||
virtual unsigned int getTypeId() = 0;
|
||||
virtual unsigned int getTypeId() const = 0;
|
||||
|
||||
/**
|
||||
* Récupère l'accélération de l'objet
|
||||
*/
|
||||
sf::Vector2f getAcceleration();
|
||||
sf::Vector2f getAcceleration() const;
|
||||
|
||||
/**
|
||||
* Récupère la vitesse de l'objet
|
||||
*/
|
||||
sf::Vector2f getVelocity();
|
||||
sf::Vector2f getVelocity() const;
|
||||
|
||||
/**
|
||||
* Modifie la vitesse de l'objet
|
||||
|
@ -105,7 +102,7 @@ public:
|
|||
/**
|
||||
* Récupère la position de l'objet
|
||||
*/
|
||||
sf::Vector2f getPosition();
|
||||
sf::Vector2f getPosition() const;
|
||||
|
||||
/**
|
||||
* Modifie la position de l'objet
|
||||
|
@ -116,12 +113,12 @@ public:
|
|||
/**
|
||||
* Récupère la masse de l'objet
|
||||
*/
|
||||
float getMass();
|
||||
float getMass() const;
|
||||
|
||||
/**
|
||||
* Récupère l'inverse de la masse de l'objet (en cache)
|
||||
*/
|
||||
float getMassInvert();
|
||||
float getMassInvert() const;
|
||||
|
||||
/**
|
||||
* Modifie la masse de l'objet
|
||||
|
@ -131,7 +128,7 @@ public:
|
|||
/**
|
||||
* Récupère la charge de l'objet
|
||||
*/
|
||||
float getCharge();
|
||||
float getCharge() const;
|
||||
|
||||
/**
|
||||
* Modifie la charge de l'objet
|
||||
|
@ -141,7 +138,7 @@ public:
|
|||
/**
|
||||
* Récupère le coefficient de restitution de l'objet
|
||||
*/
|
||||
float getRestitution();
|
||||
float getRestitution() const;
|
||||
|
||||
/**
|
||||
* Modifie le coefficient de restitution de l'objet
|
||||
|
@ -151,7 +148,7 @@ public:
|
|||
/**
|
||||
* Récupère le coefficient de frottement dynamique de l'objet
|
||||
*/
|
||||
float getStaticFriction();
|
||||
float getStaticFriction() const;
|
||||
|
||||
/**
|
||||
* Modifie le coefficient de frottement dynamique de l'objet
|
||||
|
@ -161,7 +158,7 @@ public:
|
|||
/**
|
||||
* Récupère le coefficient de frottement dynamique de l'objet
|
||||
*/
|
||||
float getDynamicFriction();
|
||||
float getDynamicFriction() const;
|
||||
|
||||
/**
|
||||
* Modifie le coefficient de frottement dynamique de l'objet
|
||||
|
@ -171,12 +168,12 @@ public:
|
|||
/**
|
||||
* Récupère la couche d'affichage de l'objet
|
||||
*/
|
||||
unsigned int getLayer();
|
||||
int getLayer() const;
|
||||
|
||||
/**
|
||||
* Modifie la couche d'affichage de l'objet
|
||||
*/
|
||||
void setLayer(unsigned int set_layer);
|
||||
void setLayer(int set_layer);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -185,7 +182,7 @@ public:
|
|||
* qui doit être dessinée avant celle du second
|
||||
*/
|
||||
struct ObjectCompare {
|
||||
bool operator()(Object* const &t1, Object* const &t2);
|
||||
bool operator()(Object* const &t1, Object* const &t2) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,18 +3,17 @@
|
|||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "object.hpp"
|
||||
#include "engine_state.hpp"
|
||||
|
||||
class Player : public Object {
|
||||
private:
|
||||
sf::Sprite sprite;
|
||||
mutable sf::Sprite sprite;
|
||||
unsigned int player_number;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Calcule les forces appliquées à l'objet
|
||||
*/
|
||||
virtual sf::Vector2f getForces(EngineState& state);
|
||||
virtual sf::Vector2f getForces(const Manager& manager, const std::vector<Object*>& objects) const;
|
||||
|
||||
public:
|
||||
Player(float x, float y);
|
||||
|
@ -22,28 +21,28 @@ public:
|
|||
/**
|
||||
* Dessine la balle dans la fenêtre donnée
|
||||
*/
|
||||
virtual void draw(sf::RenderWindow& window, ResourceManager& resources);
|
||||
virtual void draw(Manager& manager);
|
||||
|
||||
/**
|
||||
* Récupère la boîte englobante de l'objet
|
||||
*/
|
||||
std::unique_ptr<sf::FloatRect> getAABB();
|
||||
virtual std::unique_ptr<sf::FloatRect> getAABB() const;
|
||||
|
||||
/**
|
||||
* Récupère l'identifiant de type de cet objet
|
||||
*/
|
||||
static constexpr unsigned int TYPE_ID = 0;
|
||||
unsigned int getTypeId();
|
||||
virtual unsigned int getTypeId() const;
|
||||
|
||||
/**
|
||||
* Renvoie le rayon de la balle
|
||||
*/
|
||||
float getRadius();
|
||||
float getRadius() const;
|
||||
|
||||
/**
|
||||
* Renvoie le numéro du joueur
|
||||
*/
|
||||
unsigned int getPlayerNumber();
|
||||
unsigned int getPlayerNumber() const;
|
||||
|
||||
/**
|
||||
* Modifie le numéro du joueur
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef __PTF_VIEW_HPP__
|
||||
#define __PTF_VIEW_HPP__
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
class Manager;
|
||||
class Object;
|
||||
|
||||
/**
|
||||
* Classe abstraite pour les vues
|
||||
*/
|
||||
class View {
|
||||
public:
|
||||
/**
|
||||
* Demande le passage à la frame suivante sur
|
||||
* cette vue
|
||||
*/
|
||||
virtual void frame(Manager& manager) = 0;
|
||||
|
||||
virtual void addObject(Object& object) = 0;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -12,11 +12,13 @@ Block::Block(float x, float y) : Object(x, y) {
|
|||
sprite.setOrigin(sf::Vector2f(Constants::GRID / 2, Constants::GRID / 2));
|
||||
}
|
||||
|
||||
void Block::draw(sf::RenderWindow& window, ResourceManager& resources) {
|
||||
Object::draw(window, resources);
|
||||
void Block::draw(Manager& manager) {
|
||||
Object::draw(manager);
|
||||
|
||||
// utilisation de la texture
|
||||
sprite.setTexture(resources.getTexture("block.png"));
|
||||
sprite.setTexture(
|
||||
manager.getResourceManager().getTexture("block.png")
|
||||
);
|
||||
|
||||
// coloration du bloc en fonction de sa charge
|
||||
if (getCharge() > 0) {
|
||||
|
@ -28,10 +30,10 @@ void Block::draw(sf::RenderWindow& window, ResourceManager& resources) {
|
|||
}
|
||||
|
||||
sprite.setPosition(getPosition());
|
||||
window.draw(sprite);
|
||||
manager.getWindow().draw(sprite);
|
||||
}
|
||||
|
||||
std::unique_ptr<sf::FloatRect> Block::getAABB() {
|
||||
std::unique_ptr<sf::FloatRect> Block::getAABB() const {
|
||||
return std::unique_ptr<sf::FloatRect>(new sf::FloatRect(
|
||||
getPosition().x - Constants::GRID / 2,
|
||||
getPosition().y - Constants::GRID / 2,
|
||||
|
@ -39,6 +41,6 @@ std::unique_ptr<sf::FloatRect> Block::getAABB() {
|
|||
));
|
||||
}
|
||||
|
||||
unsigned int Block::getTypeId() {
|
||||
unsigned int Block::getTypeId() const {
|
||||
return Block::TYPE_ID;
|
||||
}
|
||||
|
|
96
src/game.cpp
96
src/game.cpp
|
@ -3,82 +3,42 @@
|
|||
#include <cmath>
|
||||
#include <queue>
|
||||
|
||||
Game::Game() : window(
|
||||
sf::VideoMode(704, 480), "Projet CMI", sf::Style::Default,
|
||||
sf::ContextSettings(0, 0, 2)
|
||||
), view(sf::FloatRect(0, 0, 704, 480)) {
|
||||
window.setVerticalSyncEnabled(true);
|
||||
|
||||
// mise en place de la caméra
|
||||
view.setSize(704, 480);
|
||||
window.setView(view);
|
||||
}
|
||||
|
||||
void Game::start() {
|
||||
float accumulator = 0;
|
||||
if (!music.openFromFile("./res/music_lvl1.wav"))
|
||||
{
|
||||
Game::Game() : accumulator(0.f) {
|
||||
if (!music.openFromFile("./res/music_lvl1.wav")) {
|
||||
// erreur
|
||||
}
|
||||
|
||||
music.play();
|
||||
music.setVolume(15);
|
||||
music.setLoop(true);
|
||||
}
|
||||
|
||||
// boucle d'événements sur la fenêtre
|
||||
while (window.isOpen()) {
|
||||
sf::Event event;
|
||||
void Game::addObject(Object& object) {
|
||||
objects.push_back(&object);
|
||||
}
|
||||
|
||||
// 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
|
||||
if (event.type == sf::Event::KeyPressed) {
|
||||
state.keys[event.key.code] = true;
|
||||
}
|
||||
|
||||
if (event.type == sf::Event::KeyReleased) {
|
||||
state.keys[event.key.code] = false;
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
float frame = clock.restart().asSeconds();
|
||||
accumulator += frame;
|
||||
void Game::frame(Manager& manager) {
|
||||
accumulator += manager.getElapsedTime();
|
||||
|
||||
// tant qu'il reste du temps à passer,
|
||||
// effectuer la simulation physique étape par étape
|
||||
while (accumulator >= Constants::PHYSICS_TIME) {
|
||||
accumulator -= Constants::PHYSICS_TIME;
|
||||
update();
|
||||
update(manager);
|
||||
}
|
||||
|
||||
draw();
|
||||
}
|
||||
draw(manager);
|
||||
}
|
||||
|
||||
void Game::addObject(Object& object) {
|
||||
state.objects.push_back(&object);
|
||||
}
|
||||
|
||||
void Game::update() {
|
||||
void Game::update(const Manager& manager) {
|
||||
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 i = 0; i < objects.size(); i++) {
|
||||
Object* objA = objects[i];
|
||||
|
||||
for (unsigned int j = i + 1; j < state.objects.size(); j++) {
|
||||
Object* objB = state.objects[j];
|
||||
for (unsigned int j = i + 1; j < objects.size(); j++) {
|
||||
Object* objB = objects[j];
|
||||
CollisionData data(*objA, *objB);
|
||||
|
||||
if (objA->detectCollision(*objB, data)) {
|
||||
|
@ -88,8 +48,8 @@ void Game::update() {
|
|||
}
|
||||
|
||||
// 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);
|
||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
||||
objects[i]->updateVelocity(manager, objects, Constants::PHYSICS_TIME / 2);
|
||||
}
|
||||
|
||||
// résolution des collisions détectées
|
||||
|
@ -99,8 +59,8 @@ void Game::update() {
|
|||
}
|
||||
|
||||
// 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);
|
||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
||||
objects[i]->updatePosition(Constants::PHYSICS_TIME);
|
||||
}
|
||||
|
||||
// application de la correction positionnelle
|
||||
|
@ -112,27 +72,27 @@ void Game::update() {
|
|||
}
|
||||
|
||||
// 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);
|
||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
||||
objects[i]->updateVelocity(manager, objects, Constants::PHYSICS_TIME / 2);
|
||||
}
|
||||
}
|
||||
|
||||
void Game::draw() {
|
||||
void Game::draw(Manager& manager) {
|
||||
// efface la scène précédente et dessine la couche de fond
|
||||
window.clear(sf::Color(66, 165, 245));
|
||||
manager.getWindow().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]);
|
||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
||||
display_queue.push(objects[i]);
|
||||
}
|
||||
|
||||
// dessin des objets de la file d'affichage couche par couche
|
||||
while (!display_queue.empty()) {
|
||||
display_queue.top()->draw(window, resources);
|
||||
display_queue.top()->draw(manager);
|
||||
display_queue.pop();
|
||||
}
|
||||
|
||||
window.display();
|
||||
manager.getWindow().display();
|
||||
}
|
||||
|
|
56
src/main.cpp
56
src/main.cpp
|
@ -1,12 +1,13 @@
|
|||
#include "player.hpp"
|
||||
#include "block.hpp"
|
||||
#include "manager.hpp"
|
||||
#include "game.hpp"
|
||||
#include "constants.hpp"
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
Game game;
|
||||
Manager manager;
|
||||
|
||||
Player player1(3.5f * Constants::GRID, 10 * Constants::GRID);
|
||||
player1.setPlayerNumber(1);
|
||||
|
@ -40,33 +41,36 @@ int main() {
|
|||
block22.setCharge(1.f);
|
||||
block22.setMass(2);
|
||||
|
||||
game.addObject(player1);
|
||||
game.addObject(player2);
|
||||
game.addObject(block01);
|
||||
game.addObject(block02);
|
||||
game.addObject(block03);
|
||||
game.addObject(block04);
|
||||
game.addObject(block05);
|
||||
game.addObject(block06);
|
||||
game.addObject(block07);
|
||||
game.addObject(block08);
|
||||
game.addObject(block09);
|
||||
game.addObject(block10);
|
||||
game.addObject(block11);
|
||||
game.addObject(block12);
|
||||
game.addObject(block13);
|
||||
game.addObject(block14);
|
||||
game.addObject(block15);
|
||||
game.addObject(block16);
|
||||
game.addObject(block17);
|
||||
game.addObject(block18);
|
||||
game.addObject(block19);
|
||||
game.addObject(block20);
|
||||
game.addObject(block21);
|
||||
game.addObject(block22);
|
||||
Game game_view;
|
||||
manager.view = &game_view;
|
||||
|
||||
manager.view->addObject(player1);
|
||||
manager.view->addObject(player2);
|
||||
manager.view->addObject(block01);
|
||||
manager.view->addObject(block02);
|
||||
manager.view->addObject(block03);
|
||||
manager.view->addObject(block04);
|
||||
manager.view->addObject(block05);
|
||||
manager.view->addObject(block06);
|
||||
manager.view->addObject(block07);
|
||||
manager.view->addObject(block08);
|
||||
manager.view->addObject(block09);
|
||||
manager.view->addObject(block10);
|
||||
manager.view->addObject(block11);
|
||||
manager.view->addObject(block12);
|
||||
manager.view->addObject(block13);
|
||||
manager.view->addObject(block14);
|
||||
manager.view->addObject(block15);
|
||||
manager.view->addObject(block16);
|
||||
manager.view->addObject(block17);
|
||||
manager.view->addObject(block18);
|
||||
manager.view->addObject(block19);
|
||||
manager.view->addObject(block20);
|
||||
manager.view->addObject(block21);
|
||||
manager.view->addObject(block22);
|
||||
|
||||
try {
|
||||
game.start();
|
||||
manager.start();
|
||||
} catch (const std::exception& exception) {
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Le programme a quitté après une erreur d'exécution." << std::endl;
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
#include "manager.hpp"
|
||||
|
||||
Manager::Manager() : window(
|
||||
sf::VideoMode(704, 480), "Projet CMI", sf::Style::Default,
|
||||
sf::ContextSettings(0, 0, 2)
|
||||
), elapsed_time(0.f), view(NULL) {
|
||||
keys.fill(false);
|
||||
}
|
||||
|
||||
void Manager::start() {
|
||||
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();
|
||||
return;
|
||||
}
|
||||
|
||||
// suivi de l'enfoncement et du relâchement des touches
|
||||
if (event.type == sf::Event::KeyPressed) {
|
||||
keys[event.key.code] = true;
|
||||
}
|
||||
|
||||
if (event.type == sf::Event::KeyReleased) {
|
||||
keys[event.key.code] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// demande à la vue de se mettre à jour sur
|
||||
// la prochaine frame
|
||||
if (view == NULL) {
|
||||
throw std::runtime_error("Aucune vue à afficher pour le jeu");
|
||||
}
|
||||
|
||||
elapsed_time = clock.restart().asSeconds();
|
||||
view->frame(*this);
|
||||
}
|
||||
}
|
||||
|
||||
sf::RenderWindow& Manager::getWindow() {
|
||||
return window;
|
||||
}
|
||||
|
||||
float Manager::getElapsedTime() const {
|
||||
return elapsed_time;
|
||||
}
|
||||
|
||||
ResourceManager& Manager::getResourceManager() {
|
||||
return resource_manager;
|
||||
}
|
||||
|
||||
bool Manager::isKeyPressed(sf::Keyboard::Key key) const {
|
||||
return keys[key];
|
||||
}
|
|
@ -15,7 +15,9 @@ Object::Object(float x, float y) :
|
|||
dynamic_friction(0.2f),
|
||||
layer(Constants::DEFAULT_LAYER) {}
|
||||
|
||||
sf::Vector2f Object::getForces(EngineState& state) {
|
||||
sf::Vector2f Object::getForces(
|
||||
const Manager& manager, const std::vector<Object*>& objects
|
||||
) const {
|
||||
sf::Vector2f forces(0, 0);
|
||||
|
||||
// force de gravité
|
||||
|
@ -23,8 +25,8 @@ sf::Vector2f Object::getForces(EngineState& state) {
|
|||
|
||||
// force d'attraction entre objets chargés
|
||||
if (getCharge() != 0) {
|
||||
for (unsigned int j = 0; j < state.objects.size(); j++) {
|
||||
Object *attractive = state.objects[j];
|
||||
for (unsigned int j = 0; j < objects.size(); j++) {
|
||||
Object *attractive = objects[j];
|
||||
|
||||
if (attractive == this || attractive->getCharge() == 0) {
|
||||
continue;
|
||||
|
@ -57,7 +59,7 @@ sf::Vector2f Object::getForces(EngineState& state) {
|
|||
return forces;
|
||||
}
|
||||
|
||||
void Object::draw(sf::RenderWindow& window, ResourceManager& resources) {
|
||||
void Object::draw(Manager& manager) {
|
||||
if (Constants::DEBUG_MODE) {
|
||||
velocity_line[0].position = position;
|
||||
velocity_line[0].color = sf::Color::Green;
|
||||
|
@ -69,21 +71,23 @@ void Object::draw(sf::RenderWindow& window, ResourceManager& resources) {
|
|||
acceleration_line[1].position = position + acceleration * 1.f;
|
||||
acceleration_line[1].color = sf::Color::Red;
|
||||
|
||||
window.draw(velocity_line);
|
||||
window.draw(acceleration_line);
|
||||
manager.getWindow().draw(velocity_line);
|
||||
manager.getWindow().draw(acceleration_line);
|
||||
}
|
||||
}
|
||||
|
||||
void Object::updateVelocity(EngineState& state, float delta) {
|
||||
acceleration = getForces(state) * getMassInvert();
|
||||
void Object::updateVelocity(
|
||||
const Manager& manager, const std::vector<Object*>& objects, float delta
|
||||
) {
|
||||
acceleration = getForces(manager, objects) * getMassInvert();
|
||||
velocity += acceleration * delta;
|
||||
}
|
||||
|
||||
void Object::updatePosition(EngineState& state, float delta) {
|
||||
void Object::updatePosition(float delta) {
|
||||
position += velocity * delta;
|
||||
}
|
||||
|
||||
bool Object::detectCollision(Object& obj, CollisionData& data) {
|
||||
bool Object::detectCollision(const Object& obj, CollisionData& data) const {
|
||||
// si les objets ne sont pas sur la même couche,
|
||||
// ils ne peuvent pas entrer en collision
|
||||
if (getLayer() != obj.getLayer()) {
|
||||
|
@ -103,7 +107,7 @@ bool Object::detectCollision(Object& obj, CollisionData& data) {
|
|||
](data);
|
||||
}
|
||||
|
||||
void Object::solveCollision(Object& obj, sf::Vector2f normal) {
|
||||
void Object::solveCollision(Object& obj, const sf::Vector2f& normal) {
|
||||
// si les deux objets sont de masse infinie, réinitialisation
|
||||
// des vitesses en tant que collision
|
||||
if (getMassInvert() == 0 && obj.getMassInvert() == 0) {
|
||||
|
@ -164,7 +168,7 @@ void Object::solveCollision(Object& obj, sf::Vector2f normal) {
|
|||
obj.setVelocity(obj.getVelocity() + obj.getMassInvert() * friction_impulse * tangent);
|
||||
}
|
||||
|
||||
void Object::positionalCorrection(Object& obj, sf::Vector2f normal, float depth) {
|
||||
void Object::positionalCorrection(Object& obj, const sf::Vector2f& normal, float depth) {
|
||||
// ne pas corriger les petites erreurs de position
|
||||
// pour éviter l'instabilité du moteur
|
||||
if (depth <= Constants::CORRECTION_THRESHOLD) {
|
||||
|
@ -178,11 +182,11 @@ void Object::positionalCorrection(Object& obj, sf::Vector2f normal, float depth)
|
|||
obj.setPosition(obj.getPosition() + obj.getMassInvert() * position_correction * normal);
|
||||
}
|
||||
|
||||
sf::Vector2f Object::getAcceleration() {
|
||||
sf::Vector2f Object::getAcceleration() const {
|
||||
return acceleration;
|
||||
}
|
||||
|
||||
sf::Vector2f Object::getVelocity() {
|
||||
sf::Vector2f Object::getVelocity() const {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
|
@ -190,7 +194,7 @@ void Object::setVelocity(sf::Vector2f set_velocity) {
|
|||
velocity = set_velocity;
|
||||
}
|
||||
|
||||
sf::Vector2f Object::getPosition() {
|
||||
sf::Vector2f Object::getPosition() const {
|
||||
return position;
|
||||
}
|
||||
|
||||
|
@ -198,11 +202,11 @@ void Object::setPosition(sf::Vector2f set_position) {
|
|||
position = set_position;
|
||||
}
|
||||
|
||||
float Object::getMass() {
|
||||
float Object::getMass() const {
|
||||
return mass;
|
||||
}
|
||||
|
||||
float Object::getMassInvert() {
|
||||
float Object::getMassInvert() const {
|
||||
if (inv_mass >= 0) {
|
||||
return inv_mass;
|
||||
}
|
||||
|
@ -221,7 +225,7 @@ void Object::setMass(float set_mass) {
|
|||
inv_mass = -1.f;
|
||||
}
|
||||
|
||||
float Object::getCharge() {
|
||||
float Object::getCharge() const {
|
||||
return charge;
|
||||
}
|
||||
|
||||
|
@ -229,7 +233,7 @@ void Object::setCharge(float set_charge) {
|
|||
charge = set_charge;
|
||||
}
|
||||
|
||||
float Object::getRestitution() {
|
||||
float Object::getRestitution() const {
|
||||
return restitution;
|
||||
}
|
||||
|
||||
|
@ -237,7 +241,7 @@ void Object::setRestitution(float set_restitution) {
|
|||
restitution = set_restitution;
|
||||
}
|
||||
|
||||
float Object::getStaticFriction() {
|
||||
float Object::getStaticFriction() const {
|
||||
return static_friction;
|
||||
}
|
||||
|
||||
|
@ -245,7 +249,7 @@ void Object::setStaticFriction(float set_static_friction) {
|
|||
static_friction = set_static_friction;
|
||||
}
|
||||
|
||||
float Object::getDynamicFriction() {
|
||||
float Object::getDynamicFriction() const {
|
||||
return dynamic_friction;
|
||||
}
|
||||
|
||||
|
@ -253,14 +257,14 @@ void Object::setDynamicFriction(float set_dynamic_friction) {
|
|||
dynamic_friction = set_dynamic_friction;
|
||||
}
|
||||
|
||||
unsigned int Object::getLayer() {
|
||||
int Object::getLayer() const {
|
||||
return layer;
|
||||
}
|
||||
|
||||
void Object::setLayer(unsigned int set_layer) {
|
||||
void Object::setLayer(int set_layer) {
|
||||
layer = set_layer;
|
||||
}
|
||||
|
||||
bool ObjectCompare::operator()(Object* const &t1, Object* const &t2) {
|
||||
bool ObjectCompare::operator()(Object* const &t1, Object* const &t2) const {
|
||||
return t1->getLayer() > t2->getLayer();
|
||||
}
|
||||
|
|
|
@ -9,26 +9,26 @@ Player::Player(float x, float y) : Object(x, y) {
|
|||
sprite.setOrigin(sf::Vector2f(getRadius(), getRadius()));
|
||||
}
|
||||
|
||||
sf::Vector2f Player::getForces(EngineState& state) {
|
||||
sf::Vector2f forces = Object::getForces(state);
|
||||
sf::Vector2f Player::getForces(const Manager& manager, const std::vector<Object*>& objects) const {
|
||||
sf::Vector2f forces = Object::getForces(manager, objects);
|
||||
|
||||
// déplacement de la balle après appui sur les touches de direction
|
||||
if (getPlayerNumber() == 1) {
|
||||
if (state.keys[sf::Keyboard::Left]) {
|
||||
if (manager.isKeyPressed(sf::Keyboard::Left)) {
|
||||
forces += sf::Vector2f(-Constants::MOVE, 0);
|
||||
}
|
||||
|
||||
if (state.keys[sf::Keyboard::Right]) {
|
||||
if (manager.isKeyPressed(sf::Keyboard::Right)) {
|
||||
forces += sf::Vector2f(Constants::MOVE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (getPlayerNumber() == 2) {
|
||||
if (state.keys[sf::Keyboard::Q]) {
|
||||
if (manager.isKeyPressed(sf::Keyboard::Q)) {
|
||||
forces += sf::Vector2f(-Constants::MOVE, 0);
|
||||
}
|
||||
|
||||
if (state.keys[sf::Keyboard::D]) {
|
||||
if (manager.isKeyPressed(sf::Keyboard::D)) {
|
||||
forces += sf::Vector2f(Constants::MOVE, 0);
|
||||
}
|
||||
}
|
||||
|
@ -36,19 +36,21 @@ sf::Vector2f Player::getForces(EngineState& state) {
|
|||
return forces;
|
||||
}
|
||||
|
||||
void Player::draw(sf::RenderWindow& window, ResourceManager& resources) {
|
||||
Object::draw(window, resources);
|
||||
void Player::draw(Manager& manager) {
|
||||
Object::draw(manager);
|
||||
|
||||
// utilisation de la texture
|
||||
sprite.setTexture(resources.getTexture("ball.png"));
|
||||
sprite.setTexture(
|
||||
manager.getResourceManager().getTexture("ball.png")
|
||||
);
|
||||
|
||||
// déplacement du sprite à la position de la balle
|
||||
sprite.rotate(getVelocity().x * .1f);
|
||||
sprite.rotate(getVelocity().x * Constants::PHYSICS_TIME * .5f);
|
||||
sprite.setPosition(getPosition());
|
||||
window.draw(sprite);
|
||||
manager.getWindow().draw(sprite);
|
||||
}
|
||||
|
||||
std::unique_ptr<sf::FloatRect> Player::getAABB() {
|
||||
std::unique_ptr<sf::FloatRect> Player::getAABB() const {
|
||||
return std::unique_ptr<sf::FloatRect>(new sf::FloatRect(
|
||||
getPosition().x - getRadius(),
|
||||
getPosition().y - getRadius(),
|
||||
|
@ -56,15 +58,15 @@ std::unique_ptr<sf::FloatRect> Player::getAABB() {
|
|||
));
|
||||
}
|
||||
|
||||
unsigned int Player::getTypeId() {
|
||||
unsigned int Player::getTypeId() const {
|
||||
return Player::TYPE_ID;
|
||||
}
|
||||
|
||||
float Player::getRadius() {
|
||||
float Player::getRadius() const {
|
||||
return 10 * getMass();
|
||||
}
|
||||
|
||||
unsigned int Player::getPlayerNumber() {
|
||||
unsigned int Player::getPlayerNumber() const {
|
||||
return player_number;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue