Bonjour !
Alors voilà, je viens de faire ma propre classe Anim, pour gérer les animations à l'écran. Il n'y a pour l'instant aucune fonction de pause ou même de déplacement. Considérez donc que ce code marche pour quelque chose comme une fontaine. Dans les grandes lignes, on va demander à la classe de faire un vector de textures ( chaque texture contiendra un fichier png, soit une étape du mouvement ). Ensuite, selon le temps écoulé, on va charger un élément x du vector dans un sprite, sprite qu'on va ensuite dessiner à l'écran. Ma classe est une dérivée de la classe sf::Drawable, du coup je sais pas trop si c'est bien d'utiliser des sprite à l'intérieur de ma classe, sachant que les sprites sont eux mêmes dérivés de la classe sf::Drawable.
Enfi bref, voici la bête :
Anim.cpp :
#include "Anim.h"
#include <SFML/Graphics.hpp>
/* À chaque appel de cette fonction, on charge un nouveau fichier dans m_texture, puis on place une copie de m_texture dans un nouvel
élément de Tableau. i compte le nombre de fois que l'on répète cette action, soit le nombre d'éléments de Tableau */
void Anim::addFrame(std::string chemin)
{
sf::Texture m_texture;
m_texture.loadFromFile(chemin);
Tableau.push_back(m_texture);
i++;
}
/* Simple réutilisation de la fonction setPosition de la classe sf::Sprite */
void Anim::setPosition(int x, int y)
{
m_sprite.setPosition(x, y);
}
/* À chaque passage de la boucle while, on regarde le rapport suivant : temps écoulé/temps d'affichage de chaque image. Ce rapport,
tronqué à la première décimale grace à une pseudo conversion en entier, nous permet de nous déplacer dans Tableau. Chaque texture,
chaque élément du tableau est successivement chargé dans m_sprite, m_sprite étant ensuite affiché à l'écran par la fonction
virtuelle draw, présente dans le header de cette classe.
On remarque un décalage de 1 : juste après le lancement de clock, le rapport, encore inférieur à 1, est tronqué à sa première décimale
et vaut donc 0. Or, la première case de Tableau n'est pas la case [0] mais la case [1] puisque la première fois qu'on a modifié le
Tableau c'était après un push_back. L'erreur est ensuite corrigée dans la fonction setTexture, par a-1. Notons enfin le clock.restart() :
la fonction marche en boucle, il est donc normal de réinitialiser l'horloge une fois que l'on a dépassé le temps total d'affichage d'une
boucle */
void Anim::update()
{
int a=((clock.getElapsedTime().asSeconds())/framerate)+1;
if (a>i)
{
clock.restart();
}
else if (a<=i)
{
m_sprite.setTexture(Tableau[a-1]);
}
}
/* x est le temps d'affichage de chaque frame, framerate représente donc le nombre de frame par seconde */
void Anim::setFrameRate(float x)
{
x=1/x;
framerate=x;
}
Anim.h :
#ifndef Anim_h
#define Anim_h
#include <SFML/Graphics.hpp>
class Anim : public sf::Drawable
{
public:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
target.draw(m_sprite, states);
}
void addFrame(std::string chemin);
void setPosition(int x, int y);
void update();
void setFrameRate(float x);
private:
std::vector<sf::Texture>Tableau;
sf::Sprite m_sprite;
sf::Clock clock;
unsigned int i;
float framerate;
};
#endif
main.cpp :
#include <SFML/Graphics.hpp>
#include "Anim.h"
int main()
Anim fontaine;
fontaine.addFrame("/Users/blabla/0.png");
fontaine.addFrame("/Users/blabla/1.png");
fontaine.addFrame("/Users/blabla/2.png");
fontaine.addFrame("/Users/blabla/3.png");
fontaine.addFrame("/Users/blabla/4.png");
fontaine.setFrameRate(20);
fontaine.setPosition(300, 200);
sf::RenderWindow window(sf::VideoMode(800, 600), "Fenetre");
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
}
window.clear();
fontaine.update();
window.draw(fontaine);
window.display();
}
return 0;
}
Voilà voilà… Et donc je me demandais si vous aviez des suggestions d'améliorations à faire, enfin ma classe marche plutôt bien, mais je suis ouvert aux critiques donc je viens vous demander votre avis !
Mr Pchoun.