Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Animation SFML en C++  (Lu 5417 fois)

0 Membres et 1 Invité sur ce sujet

Versatis59

  • Newbie
  • *
  • Messages: 4
    • Voir le profil
    • E-mail
Animation SFML en C++
« le: Novembre 26, 2016, 10:18:23 am »
Bonsoir, je suis actuellement entrain de coder un jeu en C++ avec SFML. J'ai un personnage (Sprite ninja), avec une animation, pour choisir l’animation. J'utilise une image avec étage 1 : Position fixe ; étage 2 : Courir.

Mais j'ai un problème, au lieu de m'afficher un carré de l'image et de changer d'image très rapidement, l'image défile de gauche à droite, je ne comprend pas pourquoi, voila le code : ( animation ligne 49 )

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <SFML/Graphics.hpp>

using namespace std;
using namespace sf;

int main()
{
        // Création d'une fenêtre en SFML //
        RenderWindow window(VideoMode(800, 480, 32), "app");
        window.setFramerateLimit(60);
        window.setVerticalSyncEnabled(true);

        // Création des sprites //
        Texture backgroundTexture;
        Sprite background;
        Texture ninjaTexture;
        Sprite ninja;

        // Chargement des textures //
        if (!ninjaTexture.loadFromFile("graphics/ninja/final.png"))
        {
                cout << "Erreur durant le chargement de l'image de background." << endl;
        }
        else
        {
                ninja.setTexture(ninjaTexture);
                ninja.scale(0.3f, 0.3f);
                ninja.setPosition(300, 377);
        }

        if (!backgroundTexture.loadFromFile("graphics/background.png"))
        {
                cout << "Erreur durant le chargement de l'image de background." << endl;
        }
        else
        {
                background.setTexture(backgroundTexture);
                background.scale(0.5f, 0.5f);
        }

        // Animations //

        int frameTimer(4), frameNumber(0), frameMax(10), direction(0), w(363), h(329), etat(0);

        // Boucle principale du jeu //

        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();

                        if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
                        {
                                etat = 1;
                                direction = 0;
                                w = (363);
                                h = (329);
                                ninja.move(4, 0);
                        }
                        else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q))
                        {
                                etat = 1;
                                direction = 1;
                                w = (363);
                                h = (329);
                                ninja.move(-4, 0);
                        }
                        else if (!sf::Keyboard::isKeyPressed(sf::Keyboard::D) && !sf::Keyboard::isKeyPressed(sf::Keyboard::Q))
                        {
                                etat = 0;
                                w = (232);
                                h = (329);
                        }
                }

                // Animations //
                if (frameTimer <= 0)
                {
                        frameTimer = 4;
                        frameNumber++;
                        if (frameNumber >= frameMax)
                        {
                                frameNumber = 0;
                        }
                }
                else
                {
                        frameTimer--;
                }
                if (direction == 1)
                {
                        ninja.setTextureRect(sf::IntRect(frameNumber * w, etat * h, -w, h));
                }
                else
                {
                        ninja.setTextureRect(sf::IntRect(frameNumber * w, etat * h, w, h));
                }

                // Affichage //
                window.clear();
                window.draw(background);
                window.draw(ninja);
                window.display();
        }

        // Fin //
        return 0;

}

Quelqu'un aurait t'il une piste pour m'aider à résoudre le problème ?

Merci d'avance.
« Modifié: Novembre 26, 2016, 10:28:42 am par Laurent »

G.

  • Hero Member
  • *****
  • Messages: 1592
    • Voir le profil
Re : Animation SFML en C++
« Réponse #1 le: Novembre 26, 2016, 11:52:46 am »
w c'est vraiment la largeur d'une seule animation ?
Tu peux nous montrer l'image ?

Versatis59

  • Newbie
  • *
  • Messages: 4
    • Voir le profil
    • E-mail
Re : Animation SFML en C++
« Réponse #2 le: Novembre 26, 2016, 12:06:16 pm »
Merci de ta réponse ! J'ai poster le même poste sur un autre forum il y a 17h, tu es le seul à m'avoir répondu.
Pour w, oui c'est la largeur d'une seul image, sachant que la position fixe est plus petite car quand mon personnage cours il se penche, et donc prend de la largeur, voici l'image :
http://zupimages.net/viewer.php?id=16/47/ubeo.png

G.

  • Hero Member
  • *****
  • Messages: 1592
    • Voir le profil
Re : Animation SFML en C++
« Réponse #3 le: Novembre 26, 2016, 08:19:51 pm »
Je sais pas comment tu as calculé la largeur de tes images, mais c'est pas du tout correct.

Sur la première ligne de l'image chaque frame de l'animation fait 174 pixels (ou 175 je sais pas trop, j'te laisse mesurer :p) de large alors que dans ton code tu mets 232.
Et pour la ligne du bas où le perso court c'est environ 271 pixels alors que dans ton code tu mets 363.
La hauteur a l'air bonne par contre.

Ensuite, tu devrais mettre tes if(sf::Keyboard::isKeyPressed... en dehors de la boucle d'évènement, car là la vérification des mouvements ne se fait que quand des évènements sont déclenchés, au lieu d'être executé à chaque frame. Laisse appuyé sur D et bouge la souris rapidement en même temps, tu verras que ton personnage se déplacera plus vite car ton move est appelé à chaque évènement, même ceux déclenchés par la souris.
De plus, t'as dû remarquer que ton perso ne se déplace pas immédiatement à l'appui d'une touche. C'est normal car dans le cas de l'appui sur une touche du clavier, l'évènement est déclenché une fois puis est répété plein de fois après une courte pause (qui dépend des réglages de l'OS de l'utilisateur) (C'est comme quand tu écris ici sur le forum et que tu laisses une touche appuyée, elle va se répéter qu'après une petite pause)
isKeyPressed vérifie l'état d'une touche ("elle est enfoncée en ce moment ou pas ?") et tu n'as pas besoin d'être dans la boucle d'évènements pour ça. ;)

Versatis59

  • Newbie
  • *
  • Messages: 4
    • Voir le profil
    • E-mail
Re : Animation SFML en C++
« Réponse #4 le: Novembre 26, 2016, 08:44:18 pm »
Mais je suis vraiment *** ! C'était ça l'erreur, merci infiniment !  ;)
Et tu as tout à fait raison, donc si j'ai bien compris, il  ne faut pas mettre isKeyPressed, ou pas dans la boucle principale en tout cas ? Mais je le met ou dans ce cas la ?

G.

  • Hero Member
  • *****
  • Messages: 1592
    • Voir le profil
Re : Animation SFML en C++
« Réponse #5 le: Novembre 27, 2016, 05:09:47 pm »
Faut le sortir de la boucle d'évènement (la boucle pollEvent), au lieu de faire ça :
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();

            if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
            {
                etat = 1;
                direction = 0;
                w = (363);
                h = (329);
                ninja.move(4, 0);
            }
            else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q))
            {
                etat = 1;
                direction = 1;
                w = (363);
                h = (329);
                ninja.move(-4, 0);
            }
            else if (!sf::Keyboard::isKeyPressed(sf::Keyboard::D) && !sf::Keyboard::isKeyPressed(sf::Keyboard::Q))
            {
                etat = 0;
                w = (232);
                h = (329);
            }
        }
Tu fais ça :
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
        {
            etat = 1;
            direction = 0;
            w = (363);
            h = (329);
            ninja.move(4, 0);
        }
        else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q))
        {
            etat = 1;
            direction = 1;
            w = (363);
            h = (329);
            ninja.move(-4, 0);
        }
        else if (!sf::Keyboard::isKeyPressed(sf::Keyboard::D) && !sf::Keyboard::isKeyPressed(sf::Keyboard::Q))
        {
            etat = 0;
            w = (232);
            h = (329);
        }

Avec ça tu remarqueras que ton perso se déplace plus vite aussi, car au lieu de le déplacer de 4 pixels par évènement tu vas le déplacer de 4 pixels par frame, donc à voir pour la suite. :p

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Animation SFML en C++
« Réponse #6 le: Novembre 27, 2016, 06:29:05 pm »
Ca ne changera rien à ton problème, mais ton dernier "else if" pourrait être un simple else.
Laurent Gomila - SFML developer

Versatis59

  • Newbie
  • *
  • Messages: 4
    • Voir le profil
    • E-mail
Re : Animation SFML en C++
« Réponse #7 le: Novembre 27, 2016, 06:35:03 pm »
Merci beaucoup, pour tes réponses, une réponse par jour c'est assez long :P je rigole bien sur, ça valait le temps d'attendre. Et si Laurent ça résout totalement mon problème, merci quand même !

 

anything