Nettoyage du code (suppression #include inutiles, variables globales)
This commit is contained in:
parent
87dc7aa715
commit
ca3d36bea8
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"cmd": "cd {PROJECT_PATH} && cmake {PROJECT_PATH} && make",
|
|
||||||
"name": "cmake"
|
|
||||||
}
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
|
|
||||||
class Game;
|
class Game;
|
||||||
|
class ResourceManager;
|
||||||
class Level;
|
class Level;
|
||||||
|
|
||||||
class Block : public Object {
|
class Block : public Object {
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
#ifndef __SKIZZLE_CONSTANTS_HPP__
|
|
||||||
#define __SKIZZLE_CONSTANTS_HPP__
|
|
||||||
|
|
||||||
#include <SFML/System.hpp>
|
|
||||||
|
|
||||||
namespace Constants {
|
|
||||||
/**
|
|
||||||
* Constante d'attraction. Utilisée dans la formule
|
|
||||||
* pour le calcul de l'attraction coulombienne entre
|
|
||||||
* deux objets
|
|
||||||
*/
|
|
||||||
static const float ATTRACTION = 500000;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Correction positionnelle : pourcentage de correction
|
|
||||||
* et seuil de correction
|
|
||||||
*/
|
|
||||||
static const float CORRECTION_PERCENTAGE = .5f;
|
|
||||||
static const float CORRECTION_SLOP = .02f;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Taille de la grille des blocs en pixels
|
|
||||||
*/
|
|
||||||
static const float GRID = 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "block.hpp"
|
#include "block.hpp"
|
||||||
#include "game.hpp"
|
|
||||||
|
class Game;
|
||||||
|
|
||||||
class FinishBlock : public Block {
|
class FinishBlock : public Block {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define __PTF_GAME_HPP__
|
#define __PTF_GAME_HPP__
|
||||||
|
|
||||||
#include "level.hpp"
|
#include "level.hpp"
|
||||||
#include "editor.hpp"
|
#include "widget_timer.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La classe Game gère l'affichage et les objets
|
* La classe Game gère l'affichage et les objets
|
||||||
|
@ -25,7 +25,6 @@ private:
|
||||||
sf::Time next_frame_time;
|
sf::Time next_frame_time;
|
||||||
std::vector<Object::Ptr> pending_kill;
|
std::vector<Object::Ptr> pending_kill;
|
||||||
|
|
||||||
std::shared_ptr<Editor> return_state;
|
|
||||||
Mode mode;
|
Mode mode;
|
||||||
DeathCause death_cause;
|
DeathCause death_cause;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "block.hpp"
|
#include "block.hpp"
|
||||||
#include "game.hpp"
|
|
||||||
|
class Game;
|
||||||
|
enum class GravityDirection;
|
||||||
|
|
||||||
class GravityBlock : public Block {
|
class GravityBlock : public Block {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "block.hpp"
|
#include "block.hpp"
|
||||||
#include "game.hpp"
|
|
||||||
|
class Game;
|
||||||
|
|
||||||
class KillBlock : public Block {
|
class KillBlock : public Block {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
#include "state.hpp"
|
#include "state.hpp"
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
#include "manager.hpp"
|
|
||||||
#include "resource_manager.hpp"
|
class Manager;
|
||||||
|
|
||||||
// liste des directions de la gravité
|
// liste des directions de la gravité
|
||||||
enum class GravityDirection {NORTH, EAST, SOUTH, WEST};
|
enum class GravityDirection {NORTH, EAST, SOUTH, WEST};
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
#define __SKIZZLE_MANAGER_HPP__
|
#define __SKIZZLE_MANAGER_HPP__
|
||||||
|
|
||||||
#include "resource_manager.hpp"
|
#include "resource_manager.hpp"
|
||||||
#include "state.hpp"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
|
class State;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gestionnaire principal de tous les états, vues et
|
* Gestionnaire principal de tous les états, vues et
|
||||||
* ressources du jeu
|
* ressources du jeu
|
||||||
|
@ -37,6 +38,11 @@ public:
|
||||||
*/
|
*/
|
||||||
static const sf::Time FRAME_TIME;
|
static const sf::Time FRAME_TIME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Taille d'une case de la grille du jeu
|
||||||
|
*/
|
||||||
|
static const float GRID;
|
||||||
|
|
||||||
Manager();
|
Manager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#ifndef __PTF_MENU_HPP__
|
#ifndef __PTF_MENU_HPP__
|
||||||
#define __PTF_MENU_HPP__
|
#define __PTF_MENU_HPP__
|
||||||
|
|
||||||
#include "manager.hpp"
|
|
||||||
#include "state.hpp"
|
#include "state.hpp"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class Manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La classe Menu charge le menu du jeu
|
* La classe Menu charge le menu du jeu
|
||||||
* et permet de choisir entre jouer, lire les règles
|
* et permet de choisir entre jouer, lire les règles
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "collision.hpp"
|
#include "collision.hpp"
|
||||||
#include "manager.hpp"
|
|
||||||
#include "resource_manager.hpp"
|
|
||||||
|
|
||||||
class Level;
|
class Level;
|
||||||
class Game;
|
class Game;
|
||||||
|
@ -53,16 +51,6 @@ protected:
|
||||||
static void init(std::ifstream& file, Object::Ptr object);
|
static void init(std::ifstream& file, Object::Ptr object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Identifiants uniques des propriétés communes modifiables
|
|
||||||
*/
|
|
||||||
static const unsigned int PROP_MASS;
|
|
||||||
static const unsigned int PROP_CHARGE;
|
|
||||||
static const unsigned int PROP_RESTITUTION;
|
|
||||||
static const unsigned int PROP_STATIC_FRICTION;
|
|
||||||
static const unsigned int PROP_DYNAMIC_FRICTION;
|
|
||||||
static const unsigned int PROP_LAYER;
|
|
||||||
|
|
||||||
Object();
|
Object();
|
||||||
virtual ~Object();
|
virtual ~Object();
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#ifndef __PTF_RULES_HPP__
|
#ifndef __PTF_RULES_HPP__
|
||||||
#define __PTF_RULES_HPP__
|
#define __PTF_RULES_HPP__
|
||||||
|
|
||||||
#include "manager.hpp"
|
|
||||||
#include "state.hpp"
|
#include "state.hpp"
|
||||||
|
|
||||||
|
class Manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La classe Rules affiche les règles du jeu
|
* La classe Rules affiche les règles du jeu
|
||||||
*/
|
*/
|
||||||
|
@ -26,5 +27,4 @@ public:
|
||||||
virtual void frame();
|
virtual void frame();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
class ResourceManager;
|
class ResourceManager;
|
||||||
class Object;
|
|
||||||
class Manager;
|
class Manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "block.hpp"
|
#include "block.hpp"
|
||||||
#include "game.hpp"
|
|
||||||
|
class Game;
|
||||||
|
|
||||||
class SwitchBlock : public Block {
|
class SwitchBlock : public Block {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "manager.hpp"
|
|
||||||
|
class Manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Affiche un bouton pouvant être cliqué
|
* Affiche un bouton pouvant être cliqué
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "widget_button.hpp"
|
#include "widget_button.hpp"
|
||||||
#include "manager.hpp"
|
|
||||||
|
class Manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Affiche le compteur de temps pouvant (ou non)
|
* Affiche le compteur de temps pouvant (ou non)
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
#include "level.hpp"
|
#include "level.hpp"
|
||||||
#include "manager.hpp"
|
|
||||||
|
class Manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Représente un objet plaçable depuis la barre d'outils
|
* Représente un objet plaçable depuis la barre d'outils
|
||||||
|
|
|
@ -2,17 +2,16 @@
|
||||||
#include "level.hpp"
|
#include "level.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
#include "constants.hpp"
|
#include "manager.hpp"
|
||||||
#include "resource_manager.hpp"
|
|
||||||
|
|
||||||
const unsigned int Block::TYPE_ID = 2;
|
const unsigned int Block::TYPE_ID = 2;
|
||||||
|
|
||||||
Block::Block() : Object() {
|
Block::Block() : Object() {
|
||||||
aabb = sf::FloatRect(
|
aabb = sf::FloatRect(
|
||||||
-Constants::GRID / 2,
|
-Manager::GRID / 2,
|
||||||
-Constants::GRID / 2,
|
-Manager::GRID / 2,
|
||||||
Constants::GRID,
|
Manager::GRID,
|
||||||
Constants::GRID
|
Manager::GRID
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +89,7 @@ sf::FloatRect Block::getAABB() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
float Block::getRadius() const {
|
float Block::getRadius() const {
|
||||||
return Constants::GRID / 2;
|
return Manager::GRID / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Block::getTypeId() const {
|
unsigned int Block::getTypeId() const {
|
||||||
|
|
|
@ -8,176 +8,182 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Détermination des informations sur une collision entre
|
* Définition des variables et fonctions globales internes
|
||||||
* un cercle et un rectangle
|
* (accessibles uniquement dans ce fichier)
|
||||||
*/
|
*/
|
||||||
bool circleToAABB(CollisionData& data) {
|
namespace {
|
||||||
Object::Ptr circle = data.obj_a;
|
/**
|
||||||
Object::Ptr aabb = data.obj_b;
|
* Détermination des informations sur une collision entre
|
||||||
|
* un cercle et un rectangle
|
||||||
|
*/
|
||||||
|
bool circleToAABB(CollisionData& data) {
|
||||||
|
Object::Ptr circle = data.obj_a;
|
||||||
|
Object::Ptr aabb = data.obj_b;
|
||||||
|
|
||||||
// recherche du point le plus proche du centre du cercle
|
// recherche du point le plus proche du centre du cercle
|
||||||
// sur le rectangle. On regarde la position relative du cercle
|
// sur le rectangle. On regarde la position relative du cercle
|
||||||
// par rapport au rectangle
|
// par rapport au rectangle
|
||||||
sf::FloatRect box = aabb->getAABB();
|
sf::FloatRect box = aabb->getAABB();
|
||||||
sf::Vector2f relpos = aabb->getPosition() - circle->getPosition();
|
sf::Vector2f relpos = aabb->getPosition() - circle->getPosition();
|
||||||
sf::Vector2f closest = relpos;
|
sf::Vector2f closest = relpos;
|
||||||
|
|
||||||
// on restreint la position relative pour rester
|
// on restreint la position relative pour rester
|
||||||
// à l'intérieur du rectangle
|
// à l'intérieur du rectangle
|
||||||
if (closest.x < -box.width / 2) {
|
if (closest.x < -box.width / 2) {
|
||||||
closest.x = -box.width / 2;
|
closest.x = -box.width / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closest.x > box.width / 2) {
|
if (closest.x > box.width / 2) {
|
||||||
closest.x = box.width / 2;
|
closest.x = box.width / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closest.y < -box.height / 2) {
|
if (closest.y < -box.height / 2) {
|
||||||
closest.y = -box.height / 2;
|
closest.y = -box.height / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closest.y > box.height / 2) {
|
if (closest.y > box.height / 2) {
|
||||||
closest.y = box.height / 2;
|
closest.y = box.height / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// si la position n'a pas été changée, elle était déjà
|
// si la position n'a pas été changée, elle était déjà
|
||||||
// à l'intérieur du cercle : le cercle est dans le rectangle
|
// à l'intérieur du cercle : le cercle est dans le rectangle
|
||||||
float is_inside = false;
|
float is_inside = false;
|
||||||
|
|
||||||
if (relpos == closest) {
|
if (relpos == closest) {
|
||||||
is_inside = true;
|
is_inside = true;
|
||||||
|
|
||||||
// on se colle au bord le plus proche du rectangle
|
// on se colle au bord le plus proche du rectangle
|
||||||
if (std::abs(relpos.x) > std::abs(relpos.y)) {
|
if (std::abs(relpos.x) > std::abs(relpos.y)) {
|
||||||
if (closest.x > 0) {
|
if (closest.x > 0) {
|
||||||
closest.x = box.width / 2;
|
closest.x = box.width / 2;
|
||||||
|
} else {
|
||||||
|
closest.x = -box.width / 2;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
closest.x = -box.width / 2;
|
if (closest.y > 0) {
|
||||||
}
|
closest.y = box.height / 2;
|
||||||
} else {
|
} else {
|
||||||
if (closest.y > 0) {
|
closest.y = -box.height / 2;
|
||||||
closest.y = box.height / 2;
|
}
|
||||||
} else {
|
|
||||||
closest.y = -box.height / 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// la normale est portée par la direction
|
// la normale est portée par la direction
|
||||||
// du point le plus proche au centre du cercle
|
// du point le plus proche au centre du cercle
|
||||||
sf::Vector2f prenormal = relpos - closest;
|
sf::Vector2f prenormal = relpos - closest;
|
||||||
float squared_length = prenormal.x * prenormal.x + prenormal.y * prenormal.y;
|
float squared_length = prenormal.x * prenormal.x + prenormal.y * prenormal.y;
|
||||||
|
|
||||||
// si le cercle est à l'extérieur et que la normale est plus
|
// si le cercle est à l'extérieur et que la normale est plus
|
||||||
// longue que son rayon, il n'y a pas collision
|
// longue que son rayon, il n'y a pas collision
|
||||||
if (!is_inside && squared_length >= circle->getRadius() * circle->getRadius()) {
|
if (!is_inside && squared_length >= circle->getRadius() * circle->getRadius()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float length = std::sqrt(squared_length);
|
float length = std::sqrt(squared_length);
|
||||||
data.depth = circle->getRadius() - length;
|
data.depth = circle->getRadius() - length;
|
||||||
|
|
||||||
if (length != 0) {
|
if (length != 0) {
|
||||||
data.normal = prenormal / length;
|
data.normal = prenormal / length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_inside) {
|
if (is_inside) {
|
||||||
data.normal *= -1.f;
|
data.normal *= -1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Détermination des informations sur une collision entre
|
|
||||||
* un rectangle et un cercle
|
|
||||||
*/
|
|
||||||
bool AABBToCircle(CollisionData& data) {
|
|
||||||
// la collision rectangle -> cercle est la collision cercle -> rectangle
|
|
||||||
Object::Ptr transfer = data.obj_b;
|
|
||||||
data.obj_b = data.obj_a;
|
|
||||||
data.obj_a = transfer;
|
|
||||||
|
|
||||||
return circleToAABB(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Détermination des informations sur une collision entre
|
|
||||||
* deux cercles
|
|
||||||
*/
|
|
||||||
bool circleToCircle(CollisionData& data) {
|
|
||||||
Object::Ptr circle_a = data.obj_a;
|
|
||||||
Object::Ptr circle_b = data.obj_b;
|
|
||||||
|
|
||||||
sf::Vector2f dir = circle_b->getPosition() - circle_a->getPosition();
|
|
||||||
float squared_length = dir.x * dir.x + dir.y * dir.y;
|
|
||||||
float total_radius = circle_b->getRadius() + circle_a->getRadius();
|
|
||||||
|
|
||||||
// si les deux cercles sont à une distance supérieure
|
|
||||||
// à la somme de leurs deux rayons, il n'y a pas eu collision
|
|
||||||
if (squared_length > total_radius * total_radius) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float length = std::sqrt(squared_length);
|
|
||||||
|
|
||||||
// les cercles sont sur la même position.
|
|
||||||
// Renvoie une normale apte à séparer les deux cercles
|
|
||||||
if (length == 0) {
|
|
||||||
data.depth = total_radius;
|
|
||||||
data.normal.x = 0;
|
|
||||||
data.normal.y = -1;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// il y a eu collision
|
/**
|
||||||
data.depth = total_radius - length;
|
* Détermination des informations sur une collision entre
|
||||||
data.normal = dir / length;
|
* un rectangle et un cercle
|
||||||
return true;
|
*/
|
||||||
}
|
bool AABBToCircle(CollisionData& data) {
|
||||||
|
// la collision rectangle -> cercle est la collision cercle -> rectangle
|
||||||
|
Object::Ptr transfer = data.obj_b;
|
||||||
|
data.obj_b = data.obj_a;
|
||||||
|
data.obj_a = transfer;
|
||||||
|
|
||||||
/**
|
return circleToAABB(data);
|
||||||
* Détermination des informations sur une collision entre
|
|
||||||
* deux rectangles
|
|
||||||
*/
|
|
||||||
bool AABBToAABB(CollisionData& data) {
|
|
||||||
Object::Ptr aabb_a = data.obj_a;
|
|
||||||
Object::Ptr aabb_b = data.obj_b;
|
|
||||||
|
|
||||||
sf::FloatRect box_a = aabb_a->getAABB();
|
|
||||||
sf::FloatRect box_b = aabb_b->getAABB();
|
|
||||||
sf::Vector2f relpos = aabb_b->getPosition() - aabb_a->getPosition();
|
|
||||||
|
|
||||||
float overlap_x = box_a.width / 2 + box_b.width / 2 - std::abs(relpos.x);
|
|
||||||
float overlap_y = box_a.height / 2 + box_b.height / 2 - std::abs(relpos.y);
|
|
||||||
|
|
||||||
// si il n'y a pas de chauvauchement sur l'axe X et Y, pas de collision
|
|
||||||
if (overlap_x <= 0 || overlap_y <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// on choisit l'axe de pénétration maximale pour calculer la normale
|
/**
|
||||||
if (overlap_x < overlap_y) {
|
* Détermination des informations sur une collision entre
|
||||||
if (relpos.x < 0) {
|
* deux cercles
|
||||||
data.normal.x = -1;
|
*/
|
||||||
} else {
|
bool circleToCircle(CollisionData& data) {
|
||||||
data.normal.x = 1;
|
Object::Ptr circle_a = data.obj_a;
|
||||||
|
Object::Ptr circle_b = data.obj_b;
|
||||||
|
|
||||||
|
sf::Vector2f dir = circle_b->getPosition() - circle_a->getPosition();
|
||||||
|
float squared_length = dir.x * dir.x + dir.y * dir.y;
|
||||||
|
float total_radius = circle_b->getRadius() + circle_a->getRadius();
|
||||||
|
|
||||||
|
// si les deux cercles sont à une distance supérieure
|
||||||
|
// à la somme de leurs deux rayons, il n'y a pas eu collision
|
||||||
|
if (squared_length > total_radius * total_radius) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.normal.y = 0;
|
float length = std::sqrt(squared_length);
|
||||||
data.depth = overlap_x;
|
|
||||||
} else {
|
// les cercles sont sur la même position.
|
||||||
if (relpos.y < 0) {
|
// Renvoie une normale apte à séparer les deux cercles
|
||||||
|
if (length == 0) {
|
||||||
|
data.depth = total_radius;
|
||||||
|
data.normal.x = 0;
|
||||||
data.normal.y = -1;
|
data.normal.y = -1;
|
||||||
} else {
|
return true;
|
||||||
data.normal.y = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.normal.x = 0;
|
// il y a eu collision
|
||||||
data.depth = overlap_y;
|
data.depth = total_radius - length;
|
||||||
|
data.normal = dir / length;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
/**
|
||||||
|
* Détermination des informations sur une collision entre
|
||||||
|
* deux rectangles
|
||||||
|
*/
|
||||||
|
bool AABBToAABB(CollisionData& data) {
|
||||||
|
Object::Ptr aabb_a = data.obj_a;
|
||||||
|
Object::Ptr aabb_b = data.obj_b;
|
||||||
|
|
||||||
|
sf::FloatRect box_a = aabb_a->getAABB();
|
||||||
|
sf::FloatRect box_b = aabb_b->getAABB();
|
||||||
|
sf::Vector2f relpos = aabb_b->getPosition() - aabb_a->getPosition();
|
||||||
|
|
||||||
|
float overlap_x = box_a.width / 2 + box_b.width / 2 - std::abs(relpos.x);
|
||||||
|
float overlap_y = box_a.height / 2 + box_b.height / 2 - std::abs(relpos.y);
|
||||||
|
|
||||||
|
// si il n'y a pas de chauvauchement sur l'axe X et Y, pas de collision
|
||||||
|
if (overlap_x <= 0 || overlap_y <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// on choisit l'axe de pénétration maximale pour calculer la normale
|
||||||
|
if (overlap_x < overlap_y) {
|
||||||
|
if (relpos.x < 0) {
|
||||||
|
data.normal.x = -1;
|
||||||
|
} else {
|
||||||
|
data.normal.x = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.normal.y = 0;
|
||||||
|
data.depth = overlap_x;
|
||||||
|
} else {
|
||||||
|
if (relpos.y < 0) {
|
||||||
|
data.normal.y = -1;
|
||||||
|
} else {
|
||||||
|
data.normal.y = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.normal.x = 0;
|
||||||
|
data.depth = overlap_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CollisionData::CollisionData() {}
|
CollisionData::CollisionData() {}
|
||||||
|
|
|
@ -1,28 +1,33 @@
|
||||||
|
#include "manager.hpp"
|
||||||
#include "editor.hpp"
|
#include "editor.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "block.hpp"
|
|
||||||
#include "constants.hpp"
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
const sf::Color SELECT_RECT_COLOR = sf::Color(33, 33, 33, 40);
|
/**
|
||||||
const sf::Color SELECT_RECT_BORDER_COLOR = sf::Color(33, 33, 33, 127);
|
* Définition des variables et fonctions globales internes
|
||||||
const sf::Color ZONE_POINT_COLOR = sf::Color(140, 15, 15, 255);
|
* (accessibles uniquement dans ce fichier)
|
||||||
const sf::Color ZONE_BORDER_COLOR = sf::Color(200, 15, 15, 255);
|
*/
|
||||||
|
namespace {
|
||||||
|
const sf::Color SELECT_RECT_COLOR = sf::Color(33, 33, 33, 40);
|
||||||
|
const sf::Color SELECT_RECT_BORDER_COLOR = sf::Color(33, 33, 33, 127);
|
||||||
|
const sf::Color ZONE_POINT_COLOR = sf::Color(140, 15, 15, 255);
|
||||||
|
const sf::Color ZONE_BORDER_COLOR = sf::Color(200, 15, 15, 255);
|
||||||
|
|
||||||
const float WHEEL_SCROLL_SPEED = -7.f;
|
const float WHEEL_SCROLL_SPEED = -7.f;
|
||||||
const float POINTER_SCROLL_SPEED = 5.f;
|
const float POINTER_SCROLL_SPEED = 5.f;
|
||||||
const int POINTER_SCROLL_PADDING = 10;
|
const int POINTER_SCROLL_PADDING = 10;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arrondit le vecteur donné à une position
|
* Arrondit le vecteur donné à une position
|
||||||
* sur la grille
|
* sur la grille
|
||||||
*/
|
*/
|
||||||
inline sf::Vector2f roundVectorToGrid(sf::Vector2f input) {
|
inline sf::Vector2f roundVectorToGrid(sf::Vector2f input) {
|
||||||
input /= Constants::GRID;
|
input /= Manager::GRID;
|
||||||
input.x = round(input.x);
|
input.x = round(input.x);
|
||||||
input.y = round(input.y);
|
input.y = round(input.y);
|
||||||
input *= Constants::GRID;
|
input *= Manager::GRID;
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "resource_manager.hpp"
|
||||||
#include "finish_block.hpp"
|
#include "finish_block.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include "manager.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
#include "constants.hpp"
|
|
||||||
|
|
||||||
Game::Game(Manager& manager) : Level(manager),
|
Game::Game(Manager& manager) : Level(manager),
|
||||||
widget_timer(manager, false),
|
widget_timer(manager, false),
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "resource_manager.hpp"
|
||||||
#include "gravity_block.hpp"
|
#include "gravity_block.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "resource_manager.hpp"
|
||||||
#include "kill_block.hpp"
|
#include "kill_block.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
246
src/level.cpp
246
src/level.cpp
|
@ -1,4 +1,4 @@
|
||||||
#include "constants.hpp"
|
#include "manager.hpp"
|
||||||
#include "level.hpp"
|
#include "level.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
#include "block.hpp"
|
#include "block.hpp"
|
||||||
|
@ -14,134 +14,140 @@
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constante de gravité
|
* Définition des variables et fonctions globales internes
|
||||||
|
* (accessibles uniquement dans ce fichier)
|
||||||
*/
|
*/
|
||||||
const float GRAVITY = 235;
|
namespace {
|
||||||
|
/**
|
||||||
|
* Constante de gravité
|
||||||
|
*/
|
||||||
|
const float GRAVITY = 235;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constante de déplacement des objets à déplacement manuel
|
* Constante de déplacement des objets à déplacement manuel
|
||||||
*/
|
*/
|
||||||
const float MOVE = 200;
|
const float MOVE = 200;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Numéro actuel de version du format de fichier
|
* Numéro actuel de version du format de fichier
|
||||||
*/
|
*/
|
||||||
const unsigned int VERSION_NUMBER = 0;
|
const unsigned int VERSION_NUMBER = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dictionnaire associant les types d'objets
|
* Dictionnaire associant les types d'objets
|
||||||
* à des instances qui seront utilisées pour la
|
* à des instances qui seront utilisées pour la
|
||||||
* construction d'autres objets de ces types
|
* construction d'autres objets de ces types
|
||||||
*/
|
*/
|
||||||
std::map<unsigned int, std::function<Object::Ptr(std::ifstream&)>> object_type_map = {
|
std::map<unsigned int, std::function<Object::Ptr(std::ifstream&)>> object_type_map = {
|
||||||
{Player::TYPE_ID, Player::load},
|
{Player::TYPE_ID, Player::load},
|
||||||
{Block::TYPE_ID, Block::load},
|
{Block::TYPE_ID, Block::load},
|
||||||
{GravityBlock::TYPE_ID, GravityBlock::load},
|
{GravityBlock::TYPE_ID, GravityBlock::load},
|
||||||
{FinishBlock::TYPE_ID, FinishBlock::load},
|
{FinishBlock::TYPE_ID, FinishBlock::load},
|
||||||
{KillBlock::TYPE_ID, KillBlock::load},
|
{KillBlock::TYPE_ID, KillBlock::load},
|
||||||
{SwitchBlock::TYPE_ID, SwitchBlock::load}
|
{SwitchBlock::TYPE_ID, SwitchBlock::load}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lecture du niveau dont le chemin absolu complet est en paramètre.
|
* Lecture du niveau dont le chemin absolu complet est en paramètre.
|
||||||
* Les métadonnées sont stockées dans les variables passées par référence.
|
* Les métadonnées sont stockées dans les variables passées par référence.
|
||||||
* La callback object() est appelée séquentiellement avec les objets du niveau
|
* La callback object() est appelée séquentiellement avec les objets du niveau
|
||||||
*/
|
*/
|
||||||
void loadLevel(
|
void loadLevel(
|
||||||
std::string path, sf::String& name, int& total_time,
|
std::string path, sf::String& name, int& total_time,
|
||||||
std::vector<sf::Vector2f>& zone,
|
std::vector<sf::Vector2f>& zone,
|
||||||
std::string& background, std::string& music,
|
std::string& background, std::string& music,
|
||||||
std::function<Object::Ptr(Object::Ptr)> object_callback = {}
|
std::function<Object::Ptr(Object::Ptr)> object_callback = {}
|
||||||
) {
|
) {
|
||||||
// ouverture du fichier
|
// ouverture du fichier
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
file.open(path, std::ios::binary | std::ios::in);
|
file.open(path, std::ios::binary | std::ios::in);
|
||||||
|
|
||||||
// on vérifie que le fichier ait correctement été ouvert en lecture
|
// on vérifie que le fichier ait correctement été ouvert en lecture
|
||||||
if (file.fail()) {
|
if (file.fail()) {
|
||||||
throw std::runtime_error(
|
|
||||||
"Impossible de charger le niveau \"" + name + "\" " +
|
|
||||||
"(" + std::string(strerror(errno)) + ")"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// lecture de la signature du fichier ("BAR")
|
|
||||||
char signature[3];
|
|
||||||
file.read(signature, 3);
|
|
||||||
|
|
||||||
if (strncmp(signature, "BAR", 3) != 0) {
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Impossible de charger le niveau \"" + name + "\" " +
|
|
||||||
"(en-tête invalide)"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// lecture de la version du fichier
|
|
||||||
char file_version;
|
|
||||||
file.read(&file_version, 1);
|
|
||||||
|
|
||||||
if (file_version != VERSION_NUMBER) {
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Impossible de charger le niveau \"" + name + "\" " +
|
|
||||||
"(version non prise en charge)"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// lecture du nom du niveau
|
|
||||||
std::string std_name;
|
|
||||||
std::getline(file, std_name, '\0');
|
|
||||||
name = sf::String(std_name);
|
|
||||||
|
|
||||||
// lecture du temps total du niveau
|
|
||||||
file.read(reinterpret_cast<char*>(&total_time), 4);
|
|
||||||
total_time = ntohl(total_time);
|
|
||||||
|
|
||||||
// lecture de la zone de jeu
|
|
||||||
char control_points;
|
|
||||||
file.read(&control_points, 1);
|
|
||||||
zone.clear();
|
|
||||||
|
|
||||||
for (int i = 0; i < control_points; i++) {
|
|
||||||
float pos_x, pos_y;
|
|
||||||
|
|
||||||
file.read(reinterpret_cast<char*>(&pos_x), 4);
|
|
||||||
file.read(reinterpret_cast<char*>(&pos_y), 4);
|
|
||||||
|
|
||||||
pos_x *= Constants::GRID;
|
|
||||||
pos_y *= Constants::GRID;
|
|
||||||
|
|
||||||
zone.push_back(sf::Vector2f(pos_x, pos_y));
|
|
||||||
}
|
|
||||||
|
|
||||||
// lecture des chemins de la musique et du fond
|
|
||||||
std::getline(file, music, '\0');
|
|
||||||
std::getline(file, background, '\0');
|
|
||||||
|
|
||||||
// lecture des objets si une callback a été fournie
|
|
||||||
int object_count;
|
|
||||||
|
|
||||||
if (!object_callback) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
file.read(reinterpret_cast<char*>(&object_count), 4);
|
|
||||||
object_count = ntohl(object_count);
|
|
||||||
|
|
||||||
for (int i = 0; i < object_count; i++) {
|
|
||||||
char object_type;
|
|
||||||
file.read(&object_type, 1);
|
|
||||||
|
|
||||||
// vérifie que le type est pris en charge
|
|
||||||
// pour éviter une erreur de segmentation
|
|
||||||
if (object_type_map.count(object_type) == 0) {
|
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"Impossible de charger le niveau \"" + name + "\" " +
|
"Impossible de charger le niveau \"" + name + "\" " +
|
||||||
"(type d'objet " + std::to_string(object_type) + " inconnu)"
|
"(" + std::string(strerror(errno)) + ")"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// lecture de l'objet
|
// lecture de la signature du fichier ("BAR")
|
||||||
object_callback(object_type_map[object_type](file));
|
char signature[3];
|
||||||
|
file.read(signature, 3);
|
||||||
|
|
||||||
|
if (strncmp(signature, "BAR", 3) != 0) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Impossible de charger le niveau \"" + name + "\" " +
|
||||||
|
"(en-tête invalide)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// lecture de la version du fichier
|
||||||
|
char file_version;
|
||||||
|
file.read(&file_version, 1);
|
||||||
|
|
||||||
|
if (file_version != VERSION_NUMBER) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Impossible de charger le niveau \"" + name + "\" " +
|
||||||
|
"(version non prise en charge)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// lecture du nom du niveau
|
||||||
|
std::string std_name;
|
||||||
|
std::getline(file, std_name, '\0');
|
||||||
|
name = sf::String(std_name);
|
||||||
|
|
||||||
|
// lecture du temps total du niveau
|
||||||
|
file.read(reinterpret_cast<char*>(&total_time), 4);
|
||||||
|
total_time = ntohl(total_time);
|
||||||
|
|
||||||
|
// lecture de la zone de jeu
|
||||||
|
char control_points;
|
||||||
|
file.read(&control_points, 1);
|
||||||
|
zone.clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < control_points; i++) {
|
||||||
|
float pos_x, pos_y;
|
||||||
|
|
||||||
|
file.read(reinterpret_cast<char*>(&pos_x), 4);
|
||||||
|
file.read(reinterpret_cast<char*>(&pos_y), 4);
|
||||||
|
|
||||||
|
pos_x *= Manager::GRID;
|
||||||
|
pos_y *= Manager::GRID;
|
||||||
|
|
||||||
|
zone.push_back(sf::Vector2f(pos_x, pos_y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// lecture des chemins de la musique et du fond
|
||||||
|
std::getline(file, music, '\0');
|
||||||
|
std::getline(file, background, '\0');
|
||||||
|
|
||||||
|
// lecture des objets si une callback a été fournie
|
||||||
|
int object_count;
|
||||||
|
|
||||||
|
if (!object_callback) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.read(reinterpret_cast<char*>(&object_count), 4);
|
||||||
|
object_count = ntohl(object_count);
|
||||||
|
|
||||||
|
for (int i = 0; i < object_count; i++) {
|
||||||
|
char object_type;
|
||||||
|
file.read(&object_type, 1);
|
||||||
|
|
||||||
|
// vérifie que le type est pris en charge
|
||||||
|
// pour éviter une erreur de segmentation
|
||||||
|
if (object_type_map.count(object_type) == 0) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Impossible de charger le niveau \"" + name + "\" " +
|
||||||
|
"(type d'objet " + std::to_string(object_type) + " inconnu)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// lecture de l'objet
|
||||||
|
object_callback(object_type_map[object_type](file));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,8 +234,8 @@ void Level::save(std::string path) {
|
||||||
file.write(&control_points, 1);
|
file.write(&control_points, 1);
|
||||||
|
|
||||||
for (int i = 0; i < control_points; i++) {
|
for (int i = 0; i < control_points; i++) {
|
||||||
float pos_x = zone[i].x / Constants::GRID;
|
float pos_x = zone[i].x / Manager::GRID;
|
||||||
float pos_y = zone[i].y / Constants::GRID;
|
float pos_y = zone[i].y / Manager::GRID;
|
||||||
|
|
||||||
file.write(reinterpret_cast<char*>(&pos_x), 4);
|
file.write(reinterpret_cast<char*>(&pos_x), 4);
|
||||||
file.write(reinterpret_cast<char*>(&pos_y), 4);
|
file.write(reinterpret_cast<char*>(&pos_y), 4);
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
#include "state.hpp"
|
||||||
#include "manager.hpp"
|
#include "manager.hpp"
|
||||||
|
|
||||||
const unsigned int Manager::FPS = 60;
|
const unsigned int Manager::FPS = 60;
|
||||||
const sf::Time Manager::FRAME_TIME = sf::seconds(1.f / Manager::FPS);
|
const sf::Time Manager::FRAME_TIME = sf::seconds(1.f / Manager::FPS);
|
||||||
|
const float Manager::GRID = 32;
|
||||||
|
|
||||||
Manager::Manager() : title(sf::String(L"")) {
|
Manager::Manager() : title(sf::String(L"")) {
|
||||||
// préchargement des textures
|
// préchargement des textures
|
||||||
|
@ -45,7 +47,7 @@ void Manager::start() {
|
||||||
|
|
||||||
states.top()->processEvent(event);
|
states.top()->processEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// s'il n'y a plus d'état, on quitte
|
// s'il n'y a plus d'état, on quitte
|
||||||
if (states.empty()) {
|
if (states.empty()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
|
#include "manager.hpp"
|
||||||
#include "menu.hpp"
|
#include "menu.hpp"
|
||||||
#include "rules.hpp"
|
#include "rules.hpp"
|
||||||
#include "editor.hpp"
|
#include "editor.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
const float MAX_WIDTH_PROPORTION = 1.f / 3.f;
|
|
||||||
|
|
||||||
Menu::Menu(Manager& manager) : State(manager) {
|
Menu::Menu(Manager& manager) : State(manager) {
|
||||||
background.setTexture(getResourceManager().getTexture("bg_menu.tga"));
|
background.setTexture(getResourceManager().getTexture("bg_menu.tga"));
|
||||||
loadMainMenu();
|
loadMainMenu();
|
||||||
|
|
101
src/object.cpp
101
src/object.cpp
|
@ -1,28 +1,60 @@
|
||||||
|
#include "manager.hpp"
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "constants.hpp"
|
|
||||||
#include "collision.hpp"
|
#include "collision.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
const unsigned int Object::PROP_MASS = 1;
|
/**
|
||||||
const float DEFAULT_MASS = 0.f;
|
* Définition des variables et fonctions globales internes
|
||||||
const unsigned int Object::PROP_CHARGE = 2;
|
* (accessibles uniquement dans ce fichier)
|
||||||
const float DEFAULT_CHARGE = 0.f;
|
*/
|
||||||
const unsigned int Object::PROP_RESTITUTION = 3;
|
namespace {
|
||||||
const float DEFAULT_RESTITUTION = 0.4f;
|
// identifiant de la propriété de masse et sa valeur par défaut
|
||||||
const unsigned int Object::PROP_STATIC_FRICTION = 4;
|
// (une masse de zéro représente une masse infinie)
|
||||||
const float DEFAULT_STATIC_FRICTION = 0.4f;
|
const unsigned int PROP_MASS = 1;
|
||||||
const unsigned int Object::PROP_DYNAMIC_FRICTION = 5;
|
const float DEFAULT_MASS = 0.f;
|
||||||
const float DEFAULT_DYNAMIC_FRICTION = 0.2f;
|
|
||||||
const unsigned int Object::PROP_LAYER = 6;
|
// identifiant de la propriété de charge et sa valeur par défaut
|
||||||
const int DEFAULT_LAYER = 0;
|
const unsigned int PROP_CHARGE = 2;
|
||||||
|
const float DEFAULT_CHARGE = 0.f;
|
||||||
|
|
||||||
|
// identifiant de la propriété de restitution et sa valeur par défaut
|
||||||
|
// (plus la restitution est forte, plus les objets rebondissent)
|
||||||
|
const unsigned int PROP_RESTITUTION = 3;
|
||||||
|
const float DEFAULT_RESTITUTION = 0.4f;
|
||||||
|
|
||||||
|
// identifiant du coefficient de frottement statique et sa valeur par défaut
|
||||||
|
// (coefficient proportionnel à la qté d'énergie nécessaire pour mettre
|
||||||
|
// en mouvement l'objet)
|
||||||
|
const unsigned int PROP_STATIC_FRICTION = 4;
|
||||||
|
const float DEFAULT_STATIC_FRICTION = 0.4f;
|
||||||
|
|
||||||
|
// identifiant du coefficient de frottement dynamique et sa valeur par défaut
|
||||||
|
// (coefficient proportionnel aux pertes d'énergie en mouvement)
|
||||||
|
const unsigned int PROP_DYNAMIC_FRICTION = 5;
|
||||||
|
const float DEFAULT_DYNAMIC_FRICTION = 0.2f;
|
||||||
|
|
||||||
|
// identifiant de la propriété calque et sa valeur par défaut
|
||||||
|
// (les objets sur deux calques différents n'entrent pas en collision,
|
||||||
|
// et les objets sont dessinés par ordre de calque)
|
||||||
|
const unsigned int PROP_LAYER = 6;
|
||||||
|
const int DEFAULT_LAYER = 0;
|
||||||
|
|
||||||
|
// coefficient d'attraction. Proportionnel à la quantité d'énergie
|
||||||
|
// fournie par un objet chargé
|
||||||
|
const float ATTRACTION = 500000;
|
||||||
|
|
||||||
|
// coefficients de correction positionnelle permettant de réduire
|
||||||
|
// la visibilité des erreurs d'arrondi des flottants. Le pourcentage
|
||||||
|
// de correction indique la proportion de correction par rapport à la
|
||||||
|
// vitesse et le seuil indique le minimum de correction appliqué
|
||||||
|
const float CORRECTION_PERCENTAGE = .5f;
|
||||||
|
const float CORRECTION_SLOP = .02f;
|
||||||
|
}
|
||||||
|
|
||||||
Object::Object() :
|
Object::Object() :
|
||||||
acceleration(0, 0), velocity(0, 0), position(0, 0),
|
acceleration(0, 0), velocity(0, 0), position(0, 0),
|
||||||
selected(false), inv_mass(-1.f),
|
selected(false), inv_mass(-1.f),
|
||||||
|
|
||||||
// valeurs par défaut pour les propriétés
|
|
||||||
// de tous les objets du jeu
|
|
||||||
mass(DEFAULT_MASS),
|
mass(DEFAULT_MASS),
|
||||||
charge(DEFAULT_CHARGE),
|
charge(DEFAULT_CHARGE),
|
||||||
restitution(DEFAULT_RESTITUTION),
|
restitution(DEFAULT_RESTITUTION),
|
||||||
|
@ -40,7 +72,7 @@ void Object::init(std::ifstream& file, Object::Ptr object) {
|
||||||
file.read(reinterpret_cast<char*>(&pos_y), 4);
|
file.read(reinterpret_cast<char*>(&pos_y), 4);
|
||||||
|
|
||||||
object->setPosition(sf::Vector2f(
|
object->setPosition(sf::Vector2f(
|
||||||
pos_x * Constants::GRID, pos_y * Constants::GRID
|
pos_x * Manager::GRID, pos_y * Manager::GRID
|
||||||
));
|
));
|
||||||
|
|
||||||
// lecture des propriétés facultatives
|
// lecture des propriétés facultatives
|
||||||
|
@ -48,37 +80,37 @@ void Object::init(std::ifstream& file, Object::Ptr object) {
|
||||||
|
|
||||||
while (file.read(&prop_type, 1)) {
|
while (file.read(&prop_type, 1)) {
|
||||||
switch (prop_type) {
|
switch (prop_type) {
|
||||||
case Object::PROP_MASS:
|
case PROP_MASS:
|
||||||
float mass;
|
float mass;
|
||||||
file.read(reinterpret_cast<char*>(&mass), 4);
|
file.read(reinterpret_cast<char*>(&mass), 4);
|
||||||
object->setMass(mass);
|
object->setMass(mass);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Object::PROP_CHARGE:
|
case PROP_CHARGE:
|
||||||
float charge;
|
float charge;
|
||||||
file.read(reinterpret_cast<char*>(&charge), 4);
|
file.read(reinterpret_cast<char*>(&charge), 4);
|
||||||
object->setCharge(charge);
|
object->setCharge(charge);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Object::PROP_RESTITUTION:
|
case PROP_RESTITUTION:
|
||||||
float restitution;
|
float restitution;
|
||||||
file.read(reinterpret_cast<char*>(&restitution), 4);
|
file.read(reinterpret_cast<char*>(&restitution), 4);
|
||||||
object->setRestitution(restitution);
|
object->setRestitution(restitution);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Object::PROP_STATIC_FRICTION:
|
case PROP_STATIC_FRICTION:
|
||||||
float static_friction;
|
float static_friction;
|
||||||
file.read(reinterpret_cast<char*>(&static_friction), 4);
|
file.read(reinterpret_cast<char*>(&static_friction), 4);
|
||||||
object->setStaticFriction(static_friction);
|
object->setStaticFriction(static_friction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Object::PROP_DYNAMIC_FRICTION:
|
case PROP_DYNAMIC_FRICTION:
|
||||||
float dynamic_friction;
|
float dynamic_friction;
|
||||||
file.read(reinterpret_cast<char*>(&dynamic_friction), 4);
|
file.read(reinterpret_cast<char*>(&dynamic_friction), 4);
|
||||||
object->setDynamicFriction(dynamic_friction);
|
object->setDynamicFriction(dynamic_friction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Object::PROP_LAYER:
|
case PROP_LAYER:
|
||||||
char layer;
|
char layer;
|
||||||
file.read(&layer, 1);
|
file.read(&layer, 1);
|
||||||
object->setLayer((int) layer - 127);
|
object->setLayer((int) layer - 127);
|
||||||
|
@ -93,8 +125,8 @@ void Object::init(std::ifstream& file, Object::Ptr object) {
|
||||||
|
|
||||||
void Object::save(std::ofstream& file) const {
|
void Object::save(std::ofstream& file) const {
|
||||||
// écriture de la position de l'objet
|
// écriture de la position de l'objet
|
||||||
float pos_x = getPosition().x / Constants::GRID;
|
float pos_x = getPosition().x / Manager::GRID;
|
||||||
float pos_y = getPosition().y / Constants::GRID;
|
float pos_y = getPosition().y / Manager::GRID;
|
||||||
|
|
||||||
file.write(reinterpret_cast<const char*>(&pos_x), 4);
|
file.write(reinterpret_cast<const char*>(&pos_x), 4);
|
||||||
file.write(reinterpret_cast<const char*>(&pos_y), 4);
|
file.write(reinterpret_cast<const char*>(&pos_y), 4);
|
||||||
|
@ -103,37 +135,37 @@ void Object::save(std::ofstream& file) const {
|
||||||
char prop_type;
|
char prop_type;
|
||||||
|
|
||||||
if (mass != DEFAULT_MASS) {
|
if (mass != DEFAULT_MASS) {
|
||||||
prop_type = Object::PROP_MASS;
|
prop_type = PROP_MASS;
|
||||||
file.write(&prop_type, 1);
|
file.write(&prop_type, 1);
|
||||||
file.write(reinterpret_cast<const char*>(&mass), 4);
|
file.write(reinterpret_cast<const char*>(&mass), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (charge != DEFAULT_CHARGE) {
|
if (charge != DEFAULT_CHARGE) {
|
||||||
prop_type = Object::PROP_CHARGE;
|
prop_type = PROP_CHARGE;
|
||||||
file.write(&prop_type, 1);
|
file.write(&prop_type, 1);
|
||||||
file.write(reinterpret_cast<const char*>(&charge), 4);
|
file.write(reinterpret_cast<const char*>(&charge), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (restitution != DEFAULT_RESTITUTION) {
|
if (restitution != DEFAULT_RESTITUTION) {
|
||||||
prop_type = Object::PROP_RESTITUTION;
|
prop_type = PROP_RESTITUTION;
|
||||||
file.write(&prop_type, 1);
|
file.write(&prop_type, 1);
|
||||||
file.write(reinterpret_cast<const char*>(&restitution), 4);
|
file.write(reinterpret_cast<const char*>(&restitution), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (static_friction != DEFAULT_STATIC_FRICTION) {
|
if (static_friction != DEFAULT_STATIC_FRICTION) {
|
||||||
prop_type = Object::PROP_STATIC_FRICTION;
|
prop_type = PROP_STATIC_FRICTION;
|
||||||
file.write(&prop_type, 1);
|
file.write(&prop_type, 1);
|
||||||
file.write(reinterpret_cast<const char*>(&static_friction), 4);
|
file.write(reinterpret_cast<const char*>(&static_friction), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dynamic_friction != DEFAULT_DYNAMIC_FRICTION) {
|
if (dynamic_friction != DEFAULT_DYNAMIC_FRICTION) {
|
||||||
prop_type = Object::PROP_DYNAMIC_FRICTION;
|
prop_type = PROP_DYNAMIC_FRICTION;
|
||||||
file.write(&prop_type, 1);
|
file.write(&prop_type, 1);
|
||||||
file.write(reinterpret_cast<const char*>(&dynamic_friction), 4);
|
file.write(reinterpret_cast<const char*>(&dynamic_friction), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer != DEFAULT_LAYER) {
|
if (layer != DEFAULT_LAYER) {
|
||||||
prop_type = Object::PROP_LAYER;
|
prop_type = PROP_LAYER;
|
||||||
file.write(&prop_type, 1);
|
file.write(&prop_type, 1);
|
||||||
|
|
||||||
char write_layer = layer + 127;
|
char write_layer = layer + 127;
|
||||||
|
@ -176,7 +208,7 @@ sf::Vector2f Object::getForces(const Game& game) const {
|
||||||
// normalisation du vecteur direction qui porte
|
// normalisation du vecteur direction qui porte
|
||||||
// la force d'attraction, puis application de la norme
|
// la force d'attraction, puis application de la norme
|
||||||
attraction /= std::sqrt(distance_squared);
|
attraction /= std::sqrt(distance_squared);
|
||||||
attraction *= Constants::ATTRACTION * (
|
attraction *= ATTRACTION * (
|
||||||
(getCharge() * attractive->getCharge()) /
|
(getCharge() * attractive->getCharge()) /
|
||||||
distance_squared
|
distance_squared
|
||||||
);
|
);
|
||||||
|
@ -294,9 +326,8 @@ void Object::solveCollision(Game& game, Object::Ptr obj, const sf::Vector2f& nor
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::positionalCorrection(Object::Ptr obj, const sf::Vector2f& normal, float depth) {
|
void Object::positionalCorrection(Object::Ptr obj, const sf::Vector2f& normal, float depth) {
|
||||||
float position_correction = std::max(depth - Constants::CORRECTION_SLOP, 0.0f) /
|
float position_correction = std::max(depth - CORRECTION_SLOP, 0.0f) /
|
||||||
(getMassInvert() + obj->getMassInvert()) *
|
(getMassInvert() + obj->getMassInvert()) * CORRECTION_PERCENTAGE;
|
||||||
Constants::CORRECTION_PERCENTAGE;
|
|
||||||
|
|
||||||
setPosition(getPosition() - getMassInvert() * position_correction * normal);
|
setPosition(getPosition() - getMassInvert() * position_correction * normal);
|
||||||
obj->setPosition(obj->getPosition() + obj->getMassInvert() * position_correction * normal);
|
obj->setPosition(obj->getPosition() + obj->getMassInvert() * position_correction * normal);
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
|
#include "manager.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "game.hpp"
|
|
||||||
#include "block.hpp"
|
|
||||||
#include "constants.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
const unsigned int Player::TYPE_ID = 1;
|
const unsigned int Player::TYPE_ID = 1;
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using dir_iter = boost::filesystem::directory_iterator;
|
|
||||||
using fs_path = boost::filesystem::path;
|
|
||||||
|
|
||||||
ResourceManager::ResourceManager() : preloaded(false),
|
ResourceManager::ResourceManager() : preloaded(false),
|
||||||
music_volume(20), playing_state(false), current_music("") {
|
music_volume(20), playing_state(false), current_music("") {
|
||||||
// initialisation de la musique en bouclage et au volume par défaut
|
// initialisation de la musique en bouclage et au volume par défaut
|
||||||
|
@ -17,8 +14,8 @@ void ResourceManager::preload() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_path current = boost::filesystem::current_path();
|
boost::filesystem::path current = boost::filesystem::current_path();
|
||||||
dir_iter end;
|
boost::filesystem::directory_iterator end;
|
||||||
|
|
||||||
// on garde une référence aux chemins des différentes ressources
|
// on garde une référence aux chemins des différentes ressources
|
||||||
textures_path = current / "res/textures";
|
textures_path = current / "res/textures";
|
||||||
|
@ -27,7 +24,7 @@ void ResourceManager::preload() {
|
||||||
musics_path = current / "res/musics";
|
musics_path = current / "res/musics";
|
||||||
|
|
||||||
// préchargement de toutes les textures
|
// préchargement de toutes les textures
|
||||||
for (dir_iter it(textures_path); it != end; ++it) {
|
for (boost::filesystem::directory_iterator it(textures_path); it != end; ++it) {
|
||||||
if (boost::filesystem::is_regular_file(it->path())) {
|
if (boost::filesystem::is_regular_file(it->path())) {
|
||||||
std::string full_path = boost::filesystem::canonical(it->path()).string();
|
std::string full_path = boost::filesystem::canonical(it->path()).string();
|
||||||
std::string name = it->path().filename().string();
|
std::string name = it->path().filename().string();
|
||||||
|
@ -47,7 +44,7 @@ void ResourceManager::preload() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// préchargement de toutes les polices
|
// préchargement de toutes les polices
|
||||||
for (dir_iter it(fonts_path); it != end; ++it) {
|
for (boost::filesystem::directory_iterator it(fonts_path); it != end; ++it) {
|
||||||
if (boost::filesystem::is_regular_file(it->path())) {
|
if (boost::filesystem::is_regular_file(it->path())) {
|
||||||
std::string full_path = boost::filesystem::canonical(it->path()).string();
|
std::string full_path = boost::filesystem::canonical(it->path()).string();
|
||||||
std::string name = it->path().filename().string();
|
std::string name = it->path().filename().string();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "rules.hpp"
|
#include "rules.hpp"
|
||||||
#include <cmath>
|
#include "manager.hpp"
|
||||||
|
|
||||||
Rules::Rules(Manager& manager) : State(manager) {
|
Rules::Rules(Manager& manager) : State(manager) {
|
||||||
background.setTexture(getResourceManager().getTexture("bg_rules.png"));
|
background.setTexture(getResourceManager().getTexture("bg_rules.png"));
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "manager.hpp"
|
||||||
#include "switch_block.hpp"
|
#include "switch_block.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
|
#include "manager.hpp"
|
||||||
#include "widget_button.hpp"
|
#include "widget_button.hpp"
|
||||||
|
|
||||||
const unsigned int WidgetButton::ARROW_UP = 0;
|
const unsigned int WidgetButton::ARROW_UP = 0;
|
||||||
const unsigned int WidgetButton::ARROW_DOWN = 1;
|
const unsigned int WidgetButton::ARROW_DOWN = 1;
|
||||||
|
|
||||||
const sf::Color ARROW_COLOR = sf::Color(33, 33, 33);
|
/**
|
||||||
const sf::Color NORMAL_COLOR = sf::Color(230, 230, 230);
|
* Définition des variables et fonctions globales internes
|
||||||
const sf::Color HOVER_COLOR = sf::Color(220, 220, 220);
|
* (accessibles uniquement dans ce fichier)
|
||||||
const sf::Color ACTIVE_COLOR = sf::Color(190, 190, 190);
|
*/
|
||||||
|
namespace {
|
||||||
|
const sf::Color ARROW_COLOR = sf::Color(33, 33, 33);
|
||||||
|
const sf::Color NORMAL_COLOR = sf::Color(230, 230, 230);
|
||||||
|
const sf::Color HOVER_COLOR = sf::Color(220, 220, 220);
|
||||||
|
const sf::Color ACTIVE_COLOR = sf::Color(190, 190, 190);
|
||||||
|
}
|
||||||
|
|
||||||
WidgetButton::WidgetButton(
|
WidgetButton::WidgetButton(
|
||||||
Manager& manager, std::function<void(void)> click_cb,
|
Manager& manager, std::function<void(void)> click_cb,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
#include "manager.hpp"
|
||||||
#include "widget_timer.hpp"
|
#include "widget_timer.hpp"
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
WidgetTimer::WidgetTimer(Manager& manager, bool can_change, std::function<void(int)> time_left_cb) :
|
WidgetTimer::WidgetTimer(Manager& manager, bool can_change, std::function<void(int)> time_left_cb) :
|
||||||
manager(manager), can_change(can_change), time_left_cb(time_left_cb),
|
manager(manager), can_change(can_change), time_left_cb(time_left_cb),
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "manager.hpp"
|
||||||
#include "widget_toolbar.hpp"
|
#include "widget_toolbar.hpp"
|
||||||
#include "block.hpp"
|
#include "block.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
@ -7,7 +8,14 @@
|
||||||
#include "kill_block.hpp"
|
#include "kill_block.hpp"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
const int PADDING = 8;
|
|
||||||
|
/**
|
||||||
|
* Définition des variables et fonctions globales internes
|
||||||
|
* (accessibles uniquement dans ce fichier)
|
||||||
|
*/
|
||||||
|
namespace {
|
||||||
|
const int PADDING = 8;
|
||||||
|
}
|
||||||
|
|
||||||
ToolbarCategory::Ptr WidgetToolbar::addCategory(sf::String name) {
|
ToolbarCategory::Ptr WidgetToolbar::addCategory(sf::String name) {
|
||||||
auto cat = ToolbarCategory::Ptr(new ToolbarCategory);
|
auto cat = ToolbarCategory::Ptr(new ToolbarCategory);
|
||||||
|
|
Loading…
Reference in New Issue