Fusion des classes PhysicsObject et Object

Tous les objets sont dotés de propriétés physiques.
Les blocs ont une masse infinie : ils ne sont pas déplaçables.
This commit is contained in:
Mattéo Delabre 2016-03-15 17:08:21 +01:00
parent 4a8b31816b
commit 7a31d950c0
8 changed files with 147 additions and 158 deletions

View File

@ -4,13 +4,14 @@
#include <SFML/Graphics.hpp>
#include <iostream>
#include "engine_state.hpp"
#include "physics_object.hpp"
#include "object.hpp"
class Ball : public PhysicsObject {
protected:
class Ball : public Object {
private:
sf::Texture texture;
sf::CircleShape shape;
protected:
/**
* Calcule les forces appliquées à l'objet
*/
@ -22,7 +23,7 @@ public:
/**
* Dessine la balle dans la fenêtre donnée
*/
void draw(sf::RenderWindow& window);
virtual void draw(sf::RenderWindow& window);
/**
* Récupère la boîte englobante de l'objet

View File

@ -7,7 +7,7 @@
#include "engine_state.hpp"
class Block : public Object {
protected:
private:
sf::Texture texture;
sf::RectangleShape shape;
@ -17,13 +17,7 @@ public:
/**
* Dessin du bloc dans la fenêtre donnée
*/
void draw(sf::RenderWindow& window);
/**
* Met à jour l'objet juste avant le dessin d'une frame
* Reçoit l'état actuel du moteur
*/
void update(EngineState& state);
virtual void draw(sf::RenderWindow& window);
/**
* Récupère la boîte englobante de l'objet

View File

@ -6,44 +6,73 @@
#include "engine_state.hpp"
class Object {
protected:
private:
sf::Vector2f acceleration;
sf::Vector2f velocity;
sf::Vector2f position;
sf::VertexArray accelerationLine;
sf::VertexArray velocityLine;
float mass;
float charge;
int layer;
protected:
/**
* Calcule les forces appliquées à l'objet
*/
virtual sf::Vector2f getForces(EngineState& state);
public:
Object(float x, float y);
/**
* Dessine l'objet dans la fenêtre donnée
*/
virtual void draw(sf::RenderWindow& window) = 0;
virtual void draw(sf::RenderWindow& window);
/**
* Met à jour l'objet juste avant le dessin d'une frame
* Reçoit l'état actuel du moteur
*/
virtual void update(EngineState& state) = 0;
virtual void update(EngineState& state);
/**
* Récupère la boîte englobante de l'objet
*/
virtual std::unique_ptr<sf::FloatRect> getAABB() = 0;
/**
* Récupère l'accélération de l'objet
*/
sf::Vector2f getAcceleration();
/**
* Récupère la vitesse de l'objet
*/
sf::Vector2f getVelocity();
/**
* Modifie la vitesse de l'objet
* (à utiliser avec précaution, préférer modifier les forces)
*/
void setVelocity(sf::Vector2f set_velocity);
/**
* Récupère la position de l'objet
*/
sf::Vector2f getPosition();
/**
* Récupère la couche d'affichage de l'objet
* Récupère la masse de l'objet
*/
unsigned int getLayer();
float getMass();
/**
* Modifie la couche d'affichage de l'objet
* Modifie la masse de l'objet
*/
void setLayer(unsigned int set_layer);
void setMass(float set_mass);
/**
* Récupère la charge de l'objet
@ -54,6 +83,16 @@ public:
* Modifie la charge de l'objet
*/
void setCharge(float set_charge);
/**
* Récupère la couche d'affichage de l'objet
*/
unsigned int getLayer();
/**
* Modifie la couche d'affichage de l'objet
*/
void setLayer(unsigned int set_layer);
};
/**

View File

@ -1,58 +0,0 @@
#ifndef __PTF_PHYSICS_OBJECT_HPP__
#define __PTF_PHYSICS_OBJECT_HPP__
#include <SFML/Graphics.hpp>
#include <iostream>
#include "object.hpp"
#include "engine_state.hpp"
class PhysicsObject : public Object {
protected:
float mass;
sf::Vector2f acceleration;
sf::VertexArray accelLine;
sf::Vector2f velocity;
sf::VertexArray velLine;
/**
* Calcule les forces appliquées à l'objet
*/
virtual sf::Vector2f getForces(EngineState& state);
public:
PhysicsObject(float x, float y);
/**
* Dessine l'objet dans la fenêtre donnée
*/
virtual void draw(sf::RenderWindow& window);
/**
* Met à jour la physique de l'objet juste avant le dessin d'une frame
* Reçoit l'état actuel du moteur
*/
void update(EngineState& state);
/**
* Récupère la vitesse de l'objet
*/
sf::Vector2f getVelocity();
/**
* Modifie la vitesse de l'objet
* (à utiliser avec précaution, préférer modifier les forces)
*/
void setVelocity(sf::Vector2f set_velocity);
/**
* Récupère la masse de l'objet
*/
int getMass();
/**
* Modifie la masse de l'objet
*/
void setMass(int set_mass);
};
#endif

View File

@ -1,12 +1,12 @@
#include "ball.hpp"
#include "constants.hpp"
Ball::Ball(float x, float y) : PhysicsObject(x, y), shape(10 * mass) {
shape.setOrigin(sf::Vector2f(10 * mass, 10 * mass));
Ball::Ball(float x, float y) : Object(x, y), shape(10) {
shape.setOrigin(sf::Vector2f(10, 10));
}
void Ball::draw(sf::RenderWindow& window) {
PhysicsObject::draw(window);
Object::draw(window);
// chargement de la texture de test
if (!texture.loadFromFile("./res/ball.png")) {
@ -14,21 +14,20 @@ void Ball::draw(sf::RenderWindow& window) {
}
shape.setTexture(&texture);
shape.setPosition(position);
shape.setPosition(getPosition());
window.draw(shape);
}
std::unique_ptr<sf::FloatRect> Ball::getAABB() {
return std::unique_ptr<sf::FloatRect>(new sf::FloatRect(
position.x - 10 * mass,
position.y - 10 * mass,
20 * mass, 20 * mass
getPosition().x - 10,
getPosition().y - 10,
20, 20
));
}
sf::Vector2f Ball::getForces(EngineState& state) {
sf::Vector2f forces = PhysicsObject::getForces(state);
sf::Vector2f forces = Object::getForces(state);
// déplacement de la balle après appui sur les touches de direction
if (state.keys[sf::Keyboard::Left]) {
@ -49,7 +48,7 @@ sf::Vector2f Ball::getForces(EngineState& state) {
}
// vecteur allant de l'objet attirant vers l'objet considéré
sf::Vector2f attraction(position - attractive->getPosition());
sf::Vector2f attraction(getPosition() - attractive->getPosition());
// la norme de ce vecteur est la distance entre les objets
float distanceSquared = attraction.x * attraction.x +
@ -64,7 +63,7 @@ sf::Vector2f Ball::getForces(EngineState& state) {
// la force d'attraction, puis application de la norme
attraction /= std::sqrt(distanceSquared);
attraction *= Constants::ATTRACTION * (
(charge * attractive->getCharge()) /
(getCharge() * attractive->getCharge()) /
distanceSquared
);

View File

@ -1,11 +1,18 @@
#include "block.hpp"
#include "constants.hpp"
Block::Block(float x, float y) : Object(x, y), shape(sf::Vector2f(Constants::GRID, Constants::GRID)) {
Block::Block(float x, float y) : Object(x, y),
shape(sf::Vector2f(Constants::GRID, Constants::GRID)) {
// par défaut, les blocs ne sont pas déplaçables
// et ont donc une masse infinie
setMass(0.f);
shape.setOrigin(sf::Vector2f(Constants::GRID / 2, Constants::GRID / 2));
}
void Block::draw(sf::RenderWindow& window) {
Object::draw(window);
// chargement de la texture de test
if (!texture.loadFromFile("./res/block.png")) {
// erreur
@ -13,26 +20,22 @@ void Block::draw(sf::RenderWindow& window) {
shape.setTexture(&texture);
if (charge > 0) {
if (getCharge() > 0) {
shape.setFillColor(sf::Color(180, 180, 255));
} else if (charge < 0) {
} else if (getCharge() < 0) {
shape.setFillColor(sf::Color(255, 180, 180));
} else {
shape.setFillColor(sf::Color::White);
}
shape.setPosition(position);
shape.setPosition(getPosition());
window.draw(shape);
}
void Block::update(EngineState& state) {
// rien à mettre à jour
}
std::unique_ptr<sf::FloatRect> Block::getAABB() {
return std::unique_ptr<sf::FloatRect>(new sf::FloatRect(
position.x - Constants::GRID / 2,
position.y - Constants::GRID / 2,
getPosition().x - Constants::GRID / 2,
getPosition().y - Constants::GRID / 2,
Constants::GRID, Constants::GRID
));
}

View File

@ -1,17 +1,75 @@
#include "object.hpp"
#include "constants.hpp"
Object::Object(float x, float y) : position(x, y), charge(0.f), layer(10) {}
Object::Object(float x, float y) :
acceleration(0, 0), velocity(0, 0), position(x, y),
accelerationLine(sf::Lines, 2),
velocityLine(sf::Lines, 2),
mass(1.f), charge(0.f), layer(10) {}
sf::Vector2f Object::getForces(EngineState& state) {
sf::Vector2f forces(0, 0);
// force de gravité
forces += sf::Vector2f(0, Constants::GRAVITY);
return forces;
}
void Object::draw(sf::RenderWindow& window) {
velocityLine[0].position = position;
velocityLine[0].color = sf::Color::Green;
velocityLine[1].position = position + velocity * 1.f;
velocityLine[1].color = sf::Color::Green;
accelerationLine[0].position = position;
accelerationLine[0].color = sf::Color::Red;
accelerationLine[1].position = position + acceleration * 1.f;
accelerationLine[1].color = sf::Color::Red;
window.draw(velocityLine);
window.draw(accelerationLine);
}
void Object::update(EngineState& state) {
// on représente les objets de masse infinie avec une
// masse nulle. Ces objets ne sont pas déplaçables
if (mass == 0) {
acceleration.x = acceleration.y = 0;
velocity.x = velocity.y = 0;
return;
}
// intégration de la vitesse dans la position
position += velocity * state.delta;
// intégration des forces appliquées sur l'objet dans la vitesse
acceleration = getForces(state) / mass;
velocity += acceleration * state.delta;
}
sf::Vector2f Object::getAcceleration() {
return acceleration;
}
sf::Vector2f Object::getVelocity() {
return velocity;
}
void Object::setVelocity(sf::Vector2f set_velocity) {
velocity = set_velocity;
}
sf::Vector2f Object::getPosition() {
return position;
}
unsigned int Object::getLayer() {
return layer;
float Object::getMass() {
return mass;
}
void Object::setLayer(unsigned int set_layer) {
layer = set_layer;
void Object::setMass(float set_mass) {
mass = set_mass;
}
float Object::getCharge() {
@ -22,6 +80,14 @@ void Object::setCharge(float set_charge) {
charge = set_charge;
}
unsigned int Object::getLayer() {
return layer;
}
void Object::setLayer(unsigned int set_layer) {
layer = set_layer;
}
bool ObjectCompare::operator()(Object* const &t1, Object* const &t2) {
return t1->getLayer() > t2->getLayer();
}

View File

@ -1,55 +0,0 @@
#include "physics_object.hpp"
#include "constants.hpp"
PhysicsObject::PhysicsObject(float x, float y) :
Object(x, y), mass(1), accelLine(sf::LinesStrip, 2),
velLine(sf::LinesStrip, 2) {}
void PhysicsObject::draw(sf::RenderWindow& window) {
velLine[0].position = position;
velLine[0].color = sf::Color::Green;
velLine[1].position = position + velocity * 1.f;
velLine[1].color = sf::Color::Green;
accelLine[0].position = position;
accelLine[0].color = sf::Color::Red;
accelLine[1].position = position + acceleration * 1.f;
accelLine[1].color = sf::Color::Red;
window.draw(velLine);
window.draw(accelLine);
}
void PhysicsObject::update(EngineState& state) {
// intégration de la vitesse dans la position
position += velocity * state.delta;
// intégration des forces appliquées sur l'objet dans la vitesse
acceleration = getForces(state) / mass;
velocity += acceleration * state.delta;
}
sf::Vector2f PhysicsObject::getForces(EngineState& state) {
sf::Vector2f forces(0, 0);
// force de gravité
forces += sf::Vector2f(0, Constants::GRAVITY);
return forces;
}
sf::Vector2f PhysicsObject::getVelocity() {
return velocity;
}
void PhysicsObject::setVelocity(sf::Vector2f set_velocity) {
velocity = set_velocity;
}
int PhysicsObject::getMass() {
return mass;
}
void PhysicsObject::setMass(int set_mass) {
mass = set_mass;
}