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

Auteur Sujet: Besoin d'aide pour affichage de texte  (Lu 4055 fois)

0 Membres et 2 Invités sur ce sujet

Teltboy

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Besoin d'aide pour affichage de texte
« le: Avril 18, 2014, 07:04:56 pm »
Bonjour,

Je dois développer une application en 2D avec la SFML comme projet de fin d'année avec 3 autres personnes, et je m'occupe de l'écriture des dialogues et de leur affichage. Alors pour l'instant celui qui gère les collisions a déjà défini que si on déplace le personnage jouable dans une zone à proximité d'un lapin, un texte est affiché au dessus du lapin, d'ailleurs voici une partie du code qui permet cet affichage :

////////////////////////////////////////////////////////////
sf::Sprite pnj;//On définit tout ce qui est relatif au lapin
sf::Texture pnjTexture;
pnjTexture.loadFromFile("images/lapin.png");
pnj.setTexture(pnjTexture);
pnj.setScale(0.5,0.5);
pnj.setPosition(900,50);
sf::Sprite pnjZone;
sf::Texture pnjZoneTexture;
pnjZoneTexture.create(38,38);
pnjZone.setTexture(pnjZoneTexture);
pnjZone.setPosition(pnj.getPosition().x - 8, pnj.getPosition().y - 8);
sf::FloatRect pnjHitbox = pnj.getGlobalBounds();
sf::FloatRect pnjZoneHitbox = pnjZone.getGlobalBounds();
////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////
sf::Text message("T'aurais une carotte ?",alger,15);//On définit le texte à afficher, la police et la taille
message.setPosition(pnj.getPosition().x-70,pnj.getPosition().y-15);//On définit la zone d'affichage du texte
///////////////////////////////////////////////////////////////////
 
////////////////////////////////////////
if(linkHitbox.intersects(pnjZoneHitbox))
    {
        window.draw(message);//On définit que si link rentre dans la zone, le lapin affiche du texte
    }
////////////////////////////////////////
 
/////////////////
window.draw(pnj);//On dessine le lapin
/////////////////

Au cas ou j'ai mis le code complet https://www.dropbox.com/s/jliawmnxih8wo3m/main.cpp.

Déjà cet affichage de texte c'est pas moi qui l'ai fait et j'ai été sur la documentation voir mais moi à la base je sais programmer en C, pas en C++. On doit voir le C++ en deuxième et le prof nous a dit qu'on pouvait développer en C++ (tout le reste de la classe développe en C avec la SDL ^^).

Mon pote arrive à coder sans comprendre le C++, moi pas je suis bloqué aux sf::, class blabla{ public: /*du code*/ private: /*re du code*/} les virtual void y faudrait que je me tape plein de tutos ça va prendre la blinde de temps et justement la date de remise arrive à grands pas.

Voilà, donc ce que j'aimerais faire c'est afficher du texte dans une bulle de dialogue avec des bords arrondis, une image qu'on affiche quoi, ensuite du texte qui s'affiche lettre par lettre très rapidement un peu à la Zelda, et quand tout est affiché on appuie sur une touche pour passer à la bulle suivante.

Donc ce que j'ai eu comme idée, c'est de stocker le texte dans des tableaux à une dimension, et à chaque fois qu'il affiche une valeur du tableau, la boucle se répète et le compteur s'incrémente d'un, ainsi quand on arrive au dernier 0 (caractère après le dernier caractère du tableau) il permet de passer à l'affichage du texte suivant en autorisant l'évènement de la touche d'interaction à être prise en compte.

Voilà j'ai cherché sur le forum de la SFML mais je n'ai rien compris à ce que j'ai trouvé.

Si quelqu'un saurait m'aider à concrétiser ça en code ça m'aiderait ÉNORMÉMENT.

Merci d'avance.
« Modifié: Avril 25, 2014, 04:10:50 pm par Teltboy »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Besoin d'aide pour affichage de texte
« Réponse #1 le: Avril 18, 2014, 11:12:58 pm »
Vous voulez qu'on fasse vos devoirs parce que vous avez choisi un language que vous ne connaissez pas ? Ce ne serait pas juste plus simple de le faire en C ?

Vous n'arriverez jamais à rien comme ça... "sf::", "class", "blabla" ce ne sont pas juste des mots-clé, ce sont des concepts fondamentaux qu'il faut appréhender dans leur globalité. Ton pote "arrive" à coder du C++ sans rien y comprendre, tant mieux (ou tant pis, selon le point de vue) pour lui.

Le mieux que je puisse faire c'est te conseiller. Ce qui te fera perdre le moins de temps ce serait :
- coder en C, même si le projet est en C++ (ça marche aussi)
- lâcher le C++ et tout faire en C, avec CSFML (le binding C de SFML) si vous n'aimez pas SDL.

Continuer sur le C++ sans l'apprendre, c'est se tirer une balle dans le pied tout en fonçant dans un mur ;)
Laurent Gomila - SFML developer

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : Besoin d'aide pour affichage de texte
« Réponse #2 le: Avril 18, 2014, 11:36:53 pm »
Mon pote arrive à coder sans comprendre le C++, moi pas je suis bloqué aux sf::, class blabla{ public: /*du code*/ private: /*re du code*/} les virtual void
Vous allez vous taper une énorme taule. :o

Je pense aussi que recommencer en C serait plus rapide que de continuer et vous donnerait une meilleure note.
Ah et vu que vous êtes un peu en galère, si ça rapporte pas de points de faire un affichage lettre par lettre, ne le faites pas. :p Vous pouvez éventuellement le faire quand vous aurez fait les trucs qui rapportent des points, s'il vous reste du temps.
« Modifié: Avril 18, 2014, 11:40:11 pm par G. »

Teltboy

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Re : Besoin d'aide pour affichage de texte
« Réponse #3 le: Avril 19, 2014, 12:26:35 am »
Oui mais on a trop avancé dans le projet pour tout refaire avec le binding C de SFML, je vais pas dire que c'est presque fini (loin de la) mais une des parties qui reste à implémenter c'est les affichages de dialogues, alors on pourrait faire en sorte de créer une image par bulle de dialogue, mais pour le ré-édit c'est embêtant de refaire une image à chaque modification, et puis c'est bien plus beau quand ça s'affiche lettre par lettre.

Maintenant je ne savais pas qu'afficher une lettre après une autre x pixels après la précédente était si dur que ça, désolé d'avoir essayé de "déléguer mes devoirs" c'est juste une petite partie du projet. Au pire on peut afficher les phrases lettre par lettre avec une variable par lettre (ceci était une blague).

@ G. : Et quand on a commencé bizarrement je n'ai pas cherché assez que pour se rendre compte de l'existence du CSFML, alors malheureusement on a pas le temps de tout refaire en CSFML. Effectivement c'est très risqué et très dur de travailler un l'apprentissage d'un langage en cours de travail, mais ça reste possible. Alors on a un résultat fonctionnel et on se débrouille avec. Je crois que je ferai ça quand nous aurons fait les trucs qui rapportent plus de points au vu de son degré d'importance.

On utilise le C++ uniquement pour les fonctions de la SFML et on va faire le reste en C c'est plus prudent. Je vais fouiller la documentation à la recherche de ce que j'ai besoin.

Fin bon z'avez pas répondu à ma question, c'est peut-être mieux comme ça, et merci des conseils ;)

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : Besoin d'aide pour affichage de texte
« Réponse #4 le: Avril 19, 2014, 12:35:00 am »
http://en.sfml-dev.org/forums/index.php?topic=6490.0
C'est plus ou moins ce que tu dis. Une variable qui représente le nombre de caractères à afficher et qui augmente avec le temps. Et tu coupes le texte à afficher avec substr.

Pas très évolué mais rapide à faire. ;)

Teltboy

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Re : Besoin d'aide pour affichage de texte
« Réponse #5 le: Avril 19, 2014, 10:41:03 am »
Merci pour le lien G. c'est exactement ce dont j'avais besoin ;D
« Modifié: Avril 19, 2014, 10:45:31 am par Teltboy »

Teltboy

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Re : [Résolu] Besoin d'aide pour affichage de texte
« Réponse #6 le: Avril 25, 2014, 04:09:17 pm »
J'ai encore un dernier petit souci à régler,

Il m'affiche le dialogue contenu dans un tableau lettre par lettre, et quand je presse la touche E, il passe directement au dialogue suivant et modifie bien la vitesse d'affichage des lettres, par contre le but est de modifier la vitesse d'affichage des lettres quand on appuie UNE fois sur E, et de passer au dialogue suivant quand on appuie sur E APRÈS que character soit égal à str.size().

Je pense faire en sorte que la vitesse d'affichage soit augmentée (donc l'intervalle diminué) uniquement si la touche est pressée ET ensuite relâchée. Idem pour passer au dialogue suivant pour éviter que deux conditions relatives à l'appui de la touche E soient remplies en même temps.

J'ai été voir sur la docu http://www.sfml-dev.org/documentation/2.1-fr/classsf_1_1Keyboard.php, et je vois comment faire un isKeyPressed mais pas un KeyReleased. J'ai aussi cherché sur le forum anglais mais le code que j'ai inclus n'a pas fonctionné (probablement une erreur de syntaxe).

Je peux aussi faire un cooldown de x temps dans lequel l'entrée de la touche ne serait prise en compte, donc pas de passage à la suivante (vu qu'il faudrait que je presse E pendant UN SEUL passage de while(window.isOpen()) et pendant (pas après) qu'il vérifie le if qui définit le changement d'intervalle ce qui est humainement impossible x_x). Sauf que c'est pas pratique, parce que selon la longueur du texte à afficher, il faudrait peut-être adapter le cooldown.

J'ai commenté le code presque ligne par ligne (sauf après //ON PASSE AU SECOND MESSAGE, c'est presque le même) :

if(linkHitbox.intersects(pnjZoneHitbox))//si le personnage se trouve dans la zone du pnj
{
        HUD_existe=false;//le HUD ne sera pas affiché
        if (timer.getElapsedTime() > time_entre_chaque_lettre && character < str.size())//si le temps écoulé depuis l'affichage de la lettre précédente est est plus grand que le délai entre chaque lettre affichée ET si le compteur character est plus petit que la taille totale du tableau de caractères
        {
                if(character < str.size())//si il n'a pas fini d'afficher des caractères
                {
                        if (sf::Keyboard::isKeyPressed(sf::Keyboard::E))
                        {
                                if (event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::E)
                                {
                                        time_entre_chaque_lettre=temps_un_ms_passer_dialogue;//si la touche E est pressée, il devrait afficher les prochaines lettres avec un délai non plus de 40 ms mais 1ms.
                                }
                        }
                }
                timer.restart();//pour que dans la prochaine comparaison, le timer soit redémarré
                character++;//incrémente d'un le nombre de lettres déjà affichées + celle qui s'affichera en sortie
                message.setPosition(46,596);//définit la position du sf::Text message
                message.setString( sf::String( str.substr(0, character) ) );//remplit le tableau d'une lettre

                if(!buffer2.loadFromFile("sons/bip_texte.wav"))//charge un son tant que la condition en dessous de "HUD_existe=false;" est respectée
                        return -1;//si le son ne se charge pas, le programme se ferme
                son2.setBuffer(buffer2);//mise en tampon
                son2.play();//joue un son tant que la condition en dessous de "HUD_existe=false;" est respectée
        }
        if(character == str.size()-1)//si il a affiché le dernier caractère du tableau
        {
                if(!buffer3.loadFromFile("sons/text_done.wav"))
                        return -1;
                son3.setBuffer(buffer3);
                son3.play();//joue le son
        }
        if(character == str.size())//quand le compteur character est égal à la taille du tableau de caractères
        {
                window.draw(spriteAnime_fleche_dialogue);//il dessine la flèche indiquant que l'on peut passer à la bulle de dialogue suivante
        }
        window.draw(sprite_dialogue);//dessine la bulle de dialogue
        window.draw(message);//dessine le contenu du tableau str
        //ON PASSE AU SECOND MESSAGE
        if (timer.getElapsedTime() > time_entre_chaque_lettre && character < str.size())
        {
                if(character < str.size())//si il n'a pas fini d'afficher des caractères
                {
                        if (sf::Keyboard::isKeyPressed(sf::Keyboard::E))
                        {
                                if (event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::E)
                                {
                                        time_entre_chaque_lettre=temps_un_ms_passer_dialogue;//si la touche E est pressée, il devrait afficher les prochaines lettres avec un délai non plus de 40 ms mais 1ms.
                                }
                        }
                }
                timer.restart()
                character++;
                message.setPosition(46,596);
                message.setString( sf::String( str.substr(0, character) ) );
                                       
                if(!buffer2.loadFromFile("sons/bip_texte.wav"))
                        return -1;
                son2.setBuffer(buffer2);
                son2.play();
                }
                if(character == str.size()-1)
                {
                        if(!buffer3.loadFromFile("sons/text_done.wav"))
                                return -1;
                        son3.setBuffer(buffer3);
                        son3.play();
                }
                if(character == str.size())
                {
                        window.draw(spriteAnime_fleche_dialogue);
                }
                window.draw(message);
        }
}

Je pourrais aussi faire en sorte que la touche E passe d'un dialogue à un autre et que par exemple la touche U définisse l'intervalle, mais c'est vraiment pas cool pour l'utilisateur final ...

Merci d'avance

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : Besoin d'aide pour affichage de texte
« Réponse #7 le: Avril 25, 2014, 08:43:19 pm »
http://www.sfml-dev.org/tutorials/2.1/window-events-fr.php
http://www.sfml-dev.org/tutorials/2.1/window-inputs-fr.php

sf::Keyboard sert à récupérer l'état d'une touche : "est-ce que cette touche est actuellement (à cet instant précis) enfoncée ?"
sf::Event::KeyPressed et KeyReleased t'indiquent des évènements qui viennent de se produire : "cette touche vient d'être enfoncée (ou relâchée)" et DOIVENT se trouver dans la boucle d'évènements.

Là dans ton code tu regardes si y'a l'évènement KeyReleased pour la touche E, pendant que la touche E est enfoncée... Ça te choque pas ?

Perso ce que je ferais (pour que ça colle à ce que tu dis, enfin ce que j'en ai compris) c'est me servir uniquement des évènements.
Quand on appuie sur E, on vérifie si le texte est affiché en entier. S'il l'est on passe au message suivant, sinon on accélère sa vitesse de défilement (en réduisant le temps entre 2 lettres). Quand on relache E on remet la vitesse normale de défilement du texte.
En prenant soin au préalable de désactiver la répétition des lettres. (sinon plusieurs évènements KeyPressed sont générés quand on laisse enfoncée la touche)

en pseudo code :
boucle d'évènement
{
   si on a un évènement de type KeyPressed associé à la touche E
   {
      si le message est affiché en entier
      {
         passer au message suivant
      }
      else
      {
         accélérer le texte
      }
   }
   si on a un évènement de type KeyReleased associé à la touche E
   {
      remettre la vitesse normale de défilement du texte
   }
}

Teltboy

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Re : Besoin d'aide pour affichage de texte
« Réponse #8 le: Avril 25, 2014, 10:12:35 pm »
Super je vais essayer d'intégrer ça  ;D