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

Auteur Sujet: Problème view + sélection d'un sprite  (Lu 3341 fois)

0 Membres et 1 Invité sur ce sujet

Djesteur

  • Newbie
  • *
  • Messages: 14
    • Voir le profil
Problème view + sélection d'un sprite
« le: Octobre 11, 2014, 10:37:27 pm »
Bonsoir,

j'ai un problème lorsque je déplace ma view et que j'essaye de déplacer un personnage.
Indépendamment, les deux fonctionnent très bien, mais quand je déplace ma view et que je clique sur un sprite avec la texture de sélection, le résultat est assez aléatoire : si je déplace une ou deux fois la view, le personnage ne va pas aller au bon endroit, et si je la déplace plus il ne bouge plus du tout.  :o
En revanche, pas de problèmes si je ne bouge pas ma vue.

Je n'ai mis que les parties concernées afin que la page ne fasse pas 3 km.

main.cpp
int main()
{
    RenderWindow app(VideoMode(1250, 750), "SFML window");
    Carte carte("lvl5");
    Personnage perso("hero1", 5, 3);
    View view1 = app.getDefaultView();


    while (app.isOpen())
    {

        Event event;
        while (app.pollEvent(event))
        {

            if (event.type == Event::MouseButtonReleased)
                {
                   if (event.mouseButton.button == Mouse::Right)

                    perso.bouge(event.mouseButton.x, event.mouseButton.y, &carte);
        }
            if (event.type == Event::Resized){
            FloatRect visibleArea(0, 0, event.size.width, event.size.height);
            app.setView(View(visibleArea));

        }

            if (Keyboard::isKeyPressed(Keyboard::Up)) { view1.move(0, -50);}
            if (Keyboard::isKeyPressed(Keyboard::Right)){view1.move(50, 0);}
            if (Keyboard::isKeyPressed(Keyboard::Down)){view1.move(0, 50);}
            if (Keyboard::isKeyPressed(Keyboard::Left)) {view1.move(-50, 0);}

            if (event.type == Event::Closed)
                app.close();
        }

        app.setView(view1);
        app.clear(Color::Blue);
        perso.canMove(&carte); // Vérifie où le personnage peut se déplacer et décide des sprites à afficher en conséquences
        carte.draw(&app);
        perso.draw(&app);
        app.display();
    }
    return EXIT_SUCCESS;
}
 

carte.cpp
void Carte::getMove(int pixX, int pixY, int deplacement) { // Fonction décrite juste au dessus (qui passe d'abord par le personnage)

    for (int i (0-deplacement); i <= deplacement; i++) {
        for (int j (0-deplacement); j <= deplacement; j++) {

            if (m_tabSquare[pixX+i][pixY+j+1].getPassage() == 0) {
                    if (abs(i) + abs(j) > deplacement) {}
                    else if (i == 0 && j == 0) {}
                    else { m_tabSquare[pixX+i][pixY+j].moveSquare(); }
                }

            else {}
        }

    }
}
 

personnage.cpp
Personnage::Personnage(){}
Personnage::Personnage(std::string persoName, int pixX, int pixY): m_pixX(pixX), m_pixY(pixY) {

    if (!m_textPerso.loadFromFile("textures\\" + persoName + ".png")) { cout << "Erreur chargement : texture personnage" << endl; }
    m_spritePerso.setTexture(m_textPerso);
    m_spritePerso.setPosition(m_pixX*50, m_pixY*50);
    m_deplacement = 3;

}
Personnage::~Personnage() {}

void Personnage::draw (RenderWindow* app) { app->draw(m_spritePerso); }
void Personnage::canMove (Carte* carte) { carte->getMove(m_pixX, m_pixY, m_deplacement); }
void Personnage::bouge (int sourisx, int sourisy, Carte* carte) {

    // Je convertit les coordonnées de la souris car ma carte est juste une image de plusieurs pixel
    int pixSourisX = round(sourisx/50);
    int pixSourisY = round(sourisy/50);

    if (carte->moveOk(pixSourisX, pixSourisY, m_deplacement) == 1)  {
            m_pixX = pixSourisX;
            m_pixY = pixSourisY;
            m_spritePerso.setPosition(m_pixX*50, m_pixY*50);

        }
    else {}
}
 

Merci d'avance pour vos réponses !

G.

  • Hero Member
  • *****
  • Messages: 1592
    • Voir le profil
Re : Problème view + sélection d'un sprite
« Réponse #1 le: Octobre 11, 2014, 10:51:45 pm »
J'ai pas tout lu. Les coordonnées de la souris sont relatives à la fenêtre, or toi tu veux les coordonnées qui correspondent à cette position dans ton monde (relatives à ta vue etc.). Pour cela tu dois utiliser la fonction mapPixelToCoords, en prenant soin d'indiquer à cette fonction la vue correspondante si tu en as plusieurs.

Djesteur

  • Newbie
  • *
  • Messages: 14
    • Voir le profil
Re : Problème view + sélection d'un sprite
« Réponse #2 le: Octobre 11, 2014, 11:12:37 pm »
Super, ça marche nickel  :D
Par contre j'ai l'impression des fois que lorsque j'appuie une ou deux fois sur une touche fléchée , la view se décale beaucoup plus vite que le normale (plus vite que si je laisse appuyer sur une touche ou que si j'appuie plusieurs fois rapidement). J'ai encore raté quelque chose, ou cela vient-il de mon ordi/clavier (sans fils) ?

G.

  • Hero Member
  • *****
  • Messages: 1592
    • Voir le profil
Re : Problème view + sélection d'un sprite
« Réponse #3 le: Octobre 11, 2014, 11:46:47 pm »
Pas de problème avec ton clavier ou ordi.
Ne mets pas tes trucs de mouvement à l'intérieur de la boucle d'évènements s'ils n'utilisent pas d'évènements. Là tu vérifies si isKeyPressed à chaque fois qu'il y a un évènement et ce quelque soit l'évènement. Genre si tu laisses appuyé sur une touche et que tu te mets à bouger frénétiquement ta souris ça va générer plein d'évènements MouseMoved et donc exécuter plein de fois ton code qui déplace la vue et elle va bouger bien vite. ;)

Djesteur

  • Newbie
  • *
  • Messages: 14
    • Voir le profil
Re : Problème view + sélection d'un sprite
« Réponse #4 le: Octobre 12, 2014, 01:02:03 am »
Effectivement la vitesse de déplacement de la view ne dépend plus de la souris, mais du coup réduction de la vitesse obligée (disons que + - 50 pixel par boucle sa va un peut vite 8) )
Un grand merci encore une fois, je reposterai surement d'autres problèmes ici, la flemme de recréer un topic à chaque fois  :P

G.

  • Hero Member
  • *****
  • Messages: 1592
    • Voir le profil
Re : Problème view + sélection d'un sprite
« Réponse #5 le: Octobre 12, 2014, 01:24:29 am »
Et ouai c'est sûr que passer de 50 pixels par évènement à 50 pixels par frame y'a des chances que ça aille plus vite.
Prochaine étape, rendre ta vitesse de déplacement indépendante du nombre de frames. :p

Djesteur

  • Newbie
  • *
  • Messages: 14
    • Voir le profil
Re : Problème view + sélection d'un sprite
« Réponse #6 le: Octobre 12, 2014, 01:08:05 pm »
En passant la vitesse à 10, le déplacement devient raisonnable. Je pense le rendre indépendant plus tard ( avec un Clock ?). En fait je pensait surtout régler où mon personnage peut aller. Pour l'instant il peut se déplacer de n cases, mais ça ne prend pas en compte si il y a un mur entre le personnage et une case nécessitant 2 ou 3 en déplacement :/

Djesteur

  • Newbie
  • *
  • Messages: 14
    • Voir le profil
Re : Problème view + sélection d'un sprite
« Réponse #7 le: Octobre 12, 2014, 06:33:31 pm »
Bon, finalement après plusieurs tests, je n'arrive pas a vérifier qu'il n'y ai pas un mur entre mon personnage et la case où il peut se déplacer  :'( . J'ai essayé plusieurs chose comme rajouter une variable qui regarde si il y a un mur entre les deux, si oui cela met une variable à 1, et si elle est à 1 ne pas l'afficher mais ça fonctionne qu'à moitié. Voici le code que j'utilise pour vérifier si on peut se déplacer et afficher les cases correspondantes:

carte.cpp
// Première fonction qui affiche les cases où le personnage peut se déplacer
void Carte::getMove(int pixX, int pixY, int deplacement) { // pixX et pixY sont les coordonnées du personnage

    for (int i (0-deplacement); i <= deplacement; i++) {
        for (int j (0-deplacement); j <= deplacement; j++) {

            if(pixX+i < 0 || pixX+i >= m_mapx || pixY+j < 0 || pixY+j >= m_mapy){} // Vérifie que l'on essaye pas d accéder a une caseavec des coordonnées négatives (càd hors du tableau)
            else if ((pixX+i < 0 && pixY+j < 0) || (pixX+i < 0 && pixY+j >= m_mapy) || (pixX+i >= m_mapx && pixY+j < 0) || (pixX+i >= m_mapx && pixY+j >= m_mapy)) {}
            else if (m_tabSquare[pixX+i][pixY+j+1].getPassage() == 1){} // Si c'est un mur, ne rien faire
            else  if (abs(i) + abs(j) > deplacement) {} // Si le déplacement est de 3 et que j'affiche la case m_tabSquare[pixX+3][pixY+3], il faudra en fait un déplacement de 5 cases pour y accéder (mon personnage ne se déplace pas en diagonal)
            else if (i == 0 && j == 0) {} // Inutile de déplacer le personnage sur la case où il est actuellement
            else {m_tabSquare[pixX+i][pixY+j].moveSquare(); } //m_tabSquare est le tableau stockant toutes les cases de ma carte, la fonction moveSquare permettant d'afficher le sprite de déplacement si cela est possible
       
        }
    }

}

// Seconde fonction qui, si le déplacement sélectionné est bon, donne au personnage le droit de bouger (return 1 == peut bouger pour le personnage appelant cette fonction) et effacer les sprites de déplacement. Celles ci seront ré afficher avec la nouvelle position du personnage lors de l'utilisation de la fonction au dessus.
int Carte::moveOk(int pixSourisX, int pixSourisY, int deplacement){

    if (m_tabSquare[pixSourisX][pixSourisY].getAff() == 1) {

        for (int i (0); i < m_mapx; i++) {
            for (int j (0); j < m_mapy; j++) {
                if (m_tabSquare[i][j].getAff() == 1) { m_tabSquare[i][j].noMoveSquare(); } // Efface toutes les sprites de déplacement de la carte
                else {}
            }

        }
        return 1;}

    else {return 0;}
}
 

J'en profite pour demander quelque chose qui n'a rien avoir avec ce qu'il y a au dessus: je voudrait afficher une interface qui bouge en fonction de la vue, comment dois-je m'y prendre ? Utiliser 2 views ? Modifier les coordonnées du sprite lorsque je bouge la view principal ? (J'avoue que je n'ai pas bien compris la partie du tuto sur les views)

Edit: J'ai trouvé comment faire pour déplacer mon interface avec une view, mais du coup je retrouve le bug de départ ><.

Edit 2: J'ai corrigé mon bug, il suffisait de mettre en second paramètre la view que j'utilise lors de la conversion de la position de la souris en coordonnées monde.
« Modifié: Octobre 13, 2014, 07:22:00 pm par Djesteur »

Djesteur

  • Newbie
  • *
  • Messages: 14
    • Voir le profil
Re : Problème de sprite blanc
« Réponse #8 le: Octobre 15, 2014, 03:09:37 pm »
Bonjour,  je suis (déjà) de retour avec un autre problème.

J'ai créé une classe Joueur qui possède un vector de personnages. Le problème vient de l'affichage car j'obtient un carré blanc, alors que lorsque j'utilise le constructeur de ma classe Personnage, la texture est (en tout cas devrait) être socké dans la variable m_textPerso.

Joueur.cpp
// Passage du constructeur concernant m_personnage qui est mon vector de Personnage
 m_personnage.push_back(Personnage()); // Le personnage sélectionné de base est juste un sprite transparent.
 while (getline(m_infosLvl, donneActuel)) {
        istringstream iss(donneActuel);

        while (iss >> nom >> posX >> posY) {
            m_personnage.push_back(Personnage(nom, posX, posY));
            m_nbPersos++;
        }
        if (!iss.eof()) { cout << "L'extraction a planté. Quel dommage" << endl;}
    }

void Joueur::draw(RenderWindow* app, Carte* carte){

    for (int i(0); i < m_nbPersos; i++){ m_personnage[i].draw(app);}
    m_personnage[m_personnageSelected].canMove(carte);
}
 

Personnage.cpp
Personnage::Personnage() {

    if (!m_textPerso.loadFromFile("textures\\rien.png")) { cout << "Erreur chargement : texture personnage" << endl; }
    m_infos.resize(8);
    for (int i(0); i<=7; i++) {m_infos[i] = 0;}
    m_spritePerso.setTexture(m_textPerso);
    m_spritePerso.setPosition(0, 0);
}
Personnage::Personnage(string persoName, int pixX, int pixY): m_persoName(persoName), m_pixX(pixX), m_pixY(pixY) {

    if (!m_textPerso.loadFromFile("textures\\" + m_persoName + ".png")) { cout << "Erreur chargement : texture personnage" << endl; }
    ifstream m_donnes ("donnes\\guerrier.txt"); if (m_donnes){} else { cout << "Erreur chargement : données personnage" << endl; }
    m_spritePerso.setTexture(m_textPerso);

    string ligneActuel;
    istringstream iss;

    m_infos.resize(8);

    for (int i(0); i<=7; i++) {
        getline(m_donnes, ligneActuel);
        istringstream iss (ligneActuel);
        iss >> m_infos[i];
    }

    m_spritePerso.setPosition(m_pixX*50, m_pixY*50);
}
void Personnage::draw (RenderWindow* app) {app->draw(m_spritePerso);}
 

Je ne pense pas que le problème vienne du constructeur de Personnage car je l'utilisait avant d'ajouter ma classe Joueur sans avoir de problèmes mais le sprite est blanc, donc sa texture n'est plus bonne :(

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Problème view + sélection d'un sprite
« Réponse #9 le: Octobre 15, 2014, 03:26:51 pm »
Il faut un constructeur de copie à ta classe, sinon lors d'une copie (qui survient lorsque tu ajoutes une instance à ton vector) le nouveau sprite pointera toujours vers la vieille texture, qui n'existera alors plus.
Laurent Gomila - SFML developer