IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

Un jeu de snake en 2D et tile mapping


Sujet :

Qt

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 20
    Points : 1
    Points
    1
    Par défaut Un jeu de snake en 2D et tile mapping
    Bonjour a tous,

    J'ai un projet a réaliser qui consiste a recoder le celebre jeu Snake en C++, avec pour GUI Qt.
    Le 'core' de mon programme est deja code, il me transmet en parametre un tableau en deux dimensions d'entiers contenant des entiers (oh really? ) allant de 0 a 7, chaque entier correspondant a un element du jeu (0 = vide, 1 = mur, 2 = queue du serpent, 3 = corps, 4 = tete et 7 = pomme).

    Le tableau de depart est celui ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 2 3 3 4 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 
    1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    Mon problème est le suivant :
    je souhaite pouvoir parcourir ce tableau d'entiers en affichant a chaque valeur rencontrée (0,1,2,3 ...) l'image qui lui correspond. J'ai déjà essaye et réussi a le faire en utilisant QGraphicsScenem QGraphicsView et QGraphicsItem.
    L'affichage est le suivant :


    Voila le code d’implémentation des images :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
      QGraphicsItem *item;
      QPixmap image;
      int   width = 0;
      int   heigth = 0;
     
      for (int i = 0; i < size; i++)
        {
          for (int j = 0; j < size; j++)
            {
              if (tab[i][j] == 1)
                {
                  image.load("./res/mur.png", 0, Qt::AutoColor);
                  item = scene->addPixmap(image);
                  item->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 4)
                {
                  image.load("./res/tete.png", 0, Qt::AutoColor);
                  item = scene->addPixmap(image);
                  item->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 2)
                {
                  image.load("./res/queue.png", 0, Qt::AutoColor);
                  item = scene->addPixmap(image);
                  item->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 3)
                {
                  image.load("./res/corps.png", 0, Qt::AutoColor);
                  item = scene->addPixmap(image);
                  item->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 7)
                {
                  image.load("./res/apple.jpg", 0, Qt::AutoColor);
                  item = scene->addPixmap(image);
                  item->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 0)
                width += 20;
            }
          heigth += 20;
          width = 0;
        }
    }
    Je parcours mon tableau de case en case en checkant quel entier est contenu dans la case, et en y placant l'item (et donc l'image) correspondant, a la largeur (width) et la hauteur (heigth) donnée. Puis je décale la largeur de 20, les images faisant elles mêmes 20 pixels.
    Si la case contient un 0, elle est donc vide, il n'y a rien a afficher, je decale la largeur de 20 et passe a la case suivante.

    Mais lorsque je modifie la position de mon serpent, c'est a dire en modifiant la position des 2, 3 et 4 dans mon tableau, l'affichage dans ma fenetre lui ne bouge pas. Il reste tel qu'il est sur le screen ci dessus. En clair ma fenêtre n'est pas animée, elle reste a la position initiale du tableau.

    Je pense que les items une fois positionnés dans ma scène, ne peuvent pas être chevauchés par de nouveaux items, et ainsi l'image reste fixe. Mais étant un débutant total en Qt, je ne suis pas du tout sur de ce raisonnement et surtout je n'ai aucune idée de comment résoudre mon problème.

    Merci d'avance pour les réponses que vous pourrez m'apporter

  2. #2
    Rédacteur

    Avatar de johnlamericain
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    3 742
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 3 742
    Points : 8 140
    Points
    8 140
    Par défaut
    C'est une solution pas du tout optimisé tout ça sachant que certains de tes éléments ne bougent pas

    Disons que tu as prévu une étape d'optimisation plus tard, essaye un sur ta scène à chaque rafraichissement.

  3. #3
    Membre actif
    Avatar de GreatTux
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2009
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2009
    Messages : 77
    Points : 287
    Points
    287
    Par défaut
    Hello,

    Les items de ta scène peuvent être déplacés, superposés par d'autres etc. Pas de contraintes à ce niveau là.

    Je pense que c'est plutôt un problème de conception.

    Si tu veux pouvoir déplacer les items existants, tu dois garder un pointeur vers ton QGraphicsItem et ne pas en recréer un à chaque fois, est-ce bien ce que tu fais?
    Nokia certified Qt developer
    Mon profil Linkedin

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Idem, je pense que tu as un (très gros ?) problème de conception. Tu ne fais pas du tout de la POO là, tu as une fonction qui fait tout le boulot.
    Il faudrait plutôt surcharger des QGraphicsPixmapItem pour faire ton snake (ou un QGraphicsGroupItem pour avoir plusieurs pixmaps), tes mures, ton sol, etc. Et définir un comportement pour chaque classe dérivée (la pomme disparait quand elle est avalée par le serpent, le serpent grandi quand il mange, meurt quand il se fait une bosse, etc.)

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 20
    Points : 1
    Points
    1
    Par défaut
    Wow tout d'abord merci a vous trois pour la rapidite de reaction!

    J'etais sur que c'etait pas optimise

    J'ai tente un scene->clear(); a chaque debut de boucle mais ca n'a pas fonctionne.

    Pour ce qui est du pointeur, non j'en recreais bien un a chaque fois en effet (d'ailleurs je me rends compte que je ne vous ai pas mis tout le code, c'est maintenant chose faite : )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    void    QtAff::AffMap(int **tab, int size, QGraphicsScene *scene)
    {
      QPixmap image;
      int   width = 0;
      int   heigth = 0;
     
      for (int i = 0; i < size; i++)
        {
          for (int j = 0; j < size; j++)
            {
              if (tab[i][j] == 1)
                {
                  image.load("./res/mur.png", 0, Qt::AutoColor);
                  _mur = scene->addPixmap(image);
                  _mur->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 4)
                {
                  image.load("./res/tete.png", 0, Qt::AutoColor);
                  _tete = scene->addPixmap(image);
                  _tete->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 2)
                {
                  image.load("./res/queue.png", 0, Qt::AutoColor);
                  _queue = scene->addPixmap(image);
                  _queue->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 3)
                {
                  image.load("./res/corps.png", 0, Qt::AutoColor);
                  _corps = scene->addPixmap(image);
                  _corps->setPos(width, heigth);
                  width += 20;
    }
              if (tab[i][j] == 4)
                {
                  image.load("./res/tete.png", 0, Qt::AutoColor);
                  _tete = scene->addPixmap(image);
                  _tete->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 2)
                {
                  image.load("./res/queue.png", 0, Qt::AutoColor);
                  _queue = scene->addPixmap(image);
                  _queue->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 3)
                {
                  image.load("./res/corps.png", 0, Qt::AutoColor);
                  _corps = scene->addPixmap(image);
                  _corps->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 7)
                {
                  image.load("./res/apple.jpg", 0, Qt::AutoColor);
                  _apple = scene->addPixmap(image);
                  _apple->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 0)
                width += 20;
            }
          heigth += 20;
          width = 0;
        }
    }
     
    int     main(int argc, char *argv[])
    {
      QApplication app(argc, argv);
      QGraphicsScene *scene = new QGraphicsScene;
      QtAff Aff;
      int size = 25;
      int **tab = Aff.creat_tab(size);
      int dir = UP;
      int cpt = 0;
     
      Aff.setWidth(520);
      Aff.setHeigth(520);
      while (1)
        {
          scene->clear();
          Aff.AffMap(tab, size, scene);
          QGraphicsView vue(scene);
          vue.setFixedSize(Aff.getWidth(), Aff.getHeigth());
          vue.setWindowTitle("Snake");
          vue.show();
          return app.exec();
          Aff.decal(tab, size, dir); // sert a decaler le serpent dans mon tableau d'entiers
       }
    }
    J'ai ecoute ton conseil et ai cree dans ma classe 5 pointeurs representant les 5 items dont j'ai besoin (apple, tete, queue, corps et mur). Changement par rapport a avant donc ou j'utilisais un seul et meme item pour chaque image et qui etait une variable temporaire.
    Mais l'affichage reste tout de meme statique

    Devrais-je utiliser un seul et meme pointeur d'item pour toutes les images et le placer dans ma classe?

    Edit : Pour ce qui est de la conception ne t’inquiète pas, ceci n'est qu'une ebauche et n'est pas du tout finalise, le code sera decoupe et surcharge plus tard, pour l'instant mon seul but est de pouvoir afficher en dynamique graphiquement mon tableau d'entiers.
    Si tu préfères la partie 'core' (gestion du jeu) est faite, il ne me reste que la partie graphique Qt a finir.

    Merci en tous cas de m'avoir déjà éclairé sur certains points.

  6. #6
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 20
    Points : 1
    Points
    1
    Par défaut
    (Desole du doublon)

    Pour faire plus clair je veux juste que ma fonction AffMap() puisse parcourir mon tableau a deux dimensions et afficher 'bêtement' l'image qui correspond a la valeur de chaque case. C'est tout.

  7. #7
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Bonjour,

    Dans votre main(), vous avez :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    {
      ...
      Aff.setWidth(520);
      Aff.setHeigth(520);
      while (1)
        {
          scene->clear();
          Aff.AffMap(tab, size, scene);
          QGraphicsView vue(scene);
          vue.setFixedSize(Aff.getWidth(), Aff.getHeigth());
          vue.setWindowTitle("Snake");
          vue.show();
          return app.exec();
          Aff.decal(tab, size, dir); // sert a decaler le serpent dans mon tableau d'entiers
       }
    }
    Tel que la boucle est conçue, vous faite l'équivalent de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    {
      ...
      Aff.setWidth(520);
      Aff.setHeigth(520);
      scene->clear();
      Aff.AffMap(tab, size, scene);
      QGraphicsView vue(scene);
      vue.setFixedSize(Aff.getWidth(), Aff.getHeigth());
      vue.setWindowTitle("Snake");
      vue.show();
      return app.exec();
    }
    ... ce qui n'est en réalité pas une boucle. Vous faites un nettoyage inutile de la scène, vous placez tous les éléments dans la scène, vous créez la vue et vous l'affichez à l'écran.

    Jolie norme E... GNU.

    Bonne continuation,
    Amnell.
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  8. #8
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 20
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Merci pour votre reponse

    Qt etant tout nouveau pour moi (j'ai commence il y a deux jours), je ne saisis pas encore completement l'usage de toutes ses classes et certaines de mes utilisations doivent vous faire bondir j'en ai conscience

    J'ai quelques peu avance dans mon code, et le resultat est different :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
     
    void    QtAff::AffMap(int **tab, int size, QGraphicsScene *scene)
    {
      QPixmap       image;
      int   width = 0;
      int   heigth = 0;
     
      for (int i = 0; i < size; i++)
        {
          for (int j = 0; j < size; j++)
            {
              if (tab[i][j] == 1)
                {
                  image.load("./res/mur.png", 0, Qt::AutoColor);
                  item_mur = scene->addPixmap(image);
                  item_mur->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 4)
                {
                  image.load("./res/tete.png", 0, Qt::AutoColor);
                  item_tete = scene->addPixmap(image);
                  item_tete->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 2)
                {
                  image.load("./res/queue.png", 0, Qt::AutoColor);
                  item_queue = scene->addPixmap(image);
                  item_queue->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 3)
                {
                  image.load("./res/corps.png", 0, Qt::AutoColor);
                  item_corps = scene->addPixmap(image);
                  item_corps->setPos(width, heigth);
                  width += 20;
                }
              if (tab[i][j] == 7)
                {
                  image.load("./res/apple.jpg", 0, Qt::AutoColor);
                  item_apple = scene->addPixmap(image);
                  item_apple->setPos(width, heigth);
                  width += 20;
                }
    if (tab[i][j] == 0)
                width += 20;
            }
          heigth += 20;
          width = 0;
        }
    }
     
    int     main(int argc, char *argv[])
    {
      QApplication app(argc, argv);
      QGraphicsScene *scene = new QGraphicsScene; //creation de la scene                                                                                                                                                                         
      QtAff Aff;
      int size = 25;
      int **tab = Aff.creat_tab(size);
      int dir = UP;
      int cpt = 0;
      QGraphicsView vue(scene);
     
      Aff.initWindow();
      vue.setFixedSize(Aff.getWidth(), Aff.getHeigth());
      vue.setWindowTitle("Snake");
      while (1)
        {
          Aff.AffMap(tab, size, scene);
          vue.show();
          app.exec();
          sleep(1);
          Aff.decal(tab, size, dir);
          cpt++;
          if (cpt == 3)
            dir = LEFT;
          if (cpt == 7)
            dir = DOWN;
          if (cpt == 10)
            dir = RIGHT;
        }
      return app.exec();
    }
    J'ai donc retire la création de ma vue et son paramétrage de ma boucle, et retire le return app.exec() pour ne laisser qu'un app.exec().

    Le resultat est le suivant : ma premiere fenetre est la meme que lors de mon premier post, par contre lorsque je la ferme, une deuxieme fenetre apparait, ou on voit que mon serpent s'est deplace, mais que les anciennes images de son corps elles sont restees. Illustration :




    Pour au final donner :



    Mes problemes sont donc les suivants :
    Comment supprimer tous les items de ma scene apres chaque affichage, afin d'eviter que les items ne se superposent? (j'ai essaye de faire un scene->removeItem(item) pour mes 5 pointeurs sur item apres chaque affichage, mais ca segfault )
    Pourquoi l'affichage se fait-il en plusieurs fenetres et non pas en une seule qui s'actualise?

    Merci d'avance pour le temps que vous m'accorderez, et bonne journée !

    PS : Amnell je suis perce a jour

  9. #9
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Re,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    vue.show();
    app.exec();
    Ces deux éléments sont les fautifs ; je vous redirige donc vers la doc :

    http://qt.developpez.com/doc/4.7/qapplication/#exec
    http://qt.developpez.com/doc/4.7/qwidget/#visible-prop

    (j'ai essaye de faire un scene->removeItem(item) pour mes 5 pointeurs sur item apres chaque affichage, mais ca segfault )
    Notez deux choses :
    • RemoveItem() ne libère pas la mémoire, il retire juste l'élément de la scène ;
    • Chacun de vos appels à AffMap change l'adresse sur laquelle pointe chacun de vos pointeurs.


    Bonne continuation,
    Amnell.
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  10. #10
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 20
    Points : 1
    Points
    1
    Par défaut
    Merci pour la doc, même si ne maîtrisant pas du tout la technologie j'ai peur du temps qu'il me faudra pour trouver ce que je cherche, je dois avouer qu'elle est complète.

    Pour la suppression des pointeurs c'est chose faite, j'ai intégré ma scène dans ma classe, et je supprime mes items juste après chaque affichage (donc avant un nouvel appel a AffMap, ainsi pas de changement d'adresse). Cela ne marche touours pas comme je le voudrais mais au moins il y a du progres

    Je vais continuer a chercher dans cette voie, je reviens vers vous si j'ai du nouveau, merci beaucoup !

  11. #11
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 20
    Points : 1
    Points
    1
    Par défaut
    Malgre mes recherches impossible de trouver comment avoir une seule et meme fenetre que je pourrai vider puis re-remplir, un indice?

  12. #12
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Citation Envoyé par Wanabee Voir le message
    Malgre mes recherches impossible de trouver comment avoir une seule et meme fenetre que je pourrai vider puis re-remplir, un indice?
    Avec Qt, une fenêtre est une classe dérivée de QWidget qui a été show() : faites donc un unique appel à show().

    App.exec(), pour faire simple, c'est une sorte de while (1) qui récupère et transmet les événements (KeyPress, MouseMove, MousePress, CloseEvent, etc.), et qui bloque donc la fermeture du programme (si vous avez fait votre première année dans l'école où vous êtes, vous avez dû faire de la mlx ; avec cette lib, l'équivalent est mlx_loop(mlx_ptr)). C'est pour cela que l'on fait return app.exec().

    Bonne continuation,
    Amnell.
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  13. #13
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 20
    Points : 1
    Points
    1
    Par défaut
    Le souci est que justement je n'ai pas eu a utiliser la mlx l’année dernière ce sont donc mes premiers pas dans le domaine du graphique, voila pourquoi mon raisonnement est étrange et mes difficultés de compréhension grandes .

    Le problème est que mon décalage a besoin de la boucle infinie while(1) présente dans mon main, et je ne vois donc pas ou placer cet unique appel a show(), vu qu'en dehors de la boucle il ne sera pas appelé.

    Merci pour les explications sur app.exec() , c'etait a peu pres ce que j'avais compris mais ca parait deja plus clair. Et ca explique pourquoi est ce que j'ai besoin de fermer la fenêtre pour passer au décalage suivant. Mais je n'ai aucune idee de comment actualiser mon affichage, du fait de cette boucle infinie

    Merci en tous cas pour l'aide que vous m'apportez!

    PS : J'ai modifie le code en ajoutant des removeItems(), et voici le résultats (toujours en plusieurs fenêtres néanmoins)





  14. #14
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 20
    Points : 1
    Points
    1
    Par défaut
    J'ai trouve mon probleme concernant la suppression des items, il s'agissait en fait du fait que j'ai 2 items 'corps' sur ma scene et que je n'en supprimai qu'un seul. En effet, lors de mon affichage, la valeur du pointeur du premier corps est ecrasee par la valeur du deuxieme.

    On le voit ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (tab[i][j] == 3) // si ma case est egale a 3, c'est a dire le corps du serpent
                {
                  image.load("./res/corps.png", 0, Qt::AutoColor);
                  item_corps = scene->addPixmap(image); // je set l'item avec l'image du corps, mais etant donne que le serpent a 2 cases corps, lors de l'affichage du deuxieme corps, la valeur du premier est ecrasee
                  item_corps->setPos(width, heigth);
                  width += 20;
                }
    La première case du corps est donc perdue et impossible a supprimer. J'ai trouve une solution (mais elle n'est que temporaire) qui consiste a creer un deuxième pointeur 'corps' afin de stocker la valeur du premier corps. Mais cette solution n'est pas viable car il m'est impossible de créer un pointeur pour chaque partie du corps du Snake, etant donne qu'il est destine a grandir.

    Creer un tableau pour stocker chaque adresse des pointeurs sur item_corps me parait sale et démesuré, mais je n'ai pas d'autres idees pour le moment...

  15. #15
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Re,

    Le souci est que vous partez du principe que l'affichage ne peut être effectué qu'à partir du moment où toute la scène a été remplie et qu'il faut tout effacer pour pouvoir effectuer une modification. Une solution simple est de créer la scène, de créer la vue, de lier les deux puis d'afficher la vue avec show(). Alors, vous pouvez garnir la scène de tous les objets que vous souhaitez afficher ; une peinture de la scène sera effectuée après l'appel de la fonction update() ou repaint() (sauf si cela s'effectue automatiquement, je ne me souviens plus).

    Plutôt que de passer par des pointeurs simples pour gérer les composantes du snake, pourquoi ne pas utiliser une des classes jouant le rôle de conteneur d'éléments (QList/QVector/autre selon les besoins) ?

    Bonne continuation,
    Amnell.

    EDIT : la perspective d'une liste chaînée circulaire pourrait également être envisagée.
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  16. #16
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Citation Envoyé par Wanabee Voir le message
    Le problème est que mon décalage a besoin de la boucle infinie while(1) présente dans mon main, et je ne vois donc pas ou placer cet unique appel a show(), vu qu'en dehors de la boucle il ne sera pas appelé.

    Merci pour les explications sur app.exec() , c'etait a peu pres ce que j'avais compris mais ca parait deja plus clair. Et ca explique pourquoi est ce que j'ai besoin de fermer la fenêtre pour passer au décalage suivant. Mais je n'ai aucune idee de comment actualiser mon affichage, du fait de cette boucle infinie
    J'ai survolé rapidement cela ; j'apporte donc une réponse. Faire une boucle infinie avec un sleep d'une seconde dedans pourrait mener à penser que ce n'est pas la bonne façon de faire. Avec Qt, on a QTimer qui peut permettre d'appeler une fonction toutes les x ms :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    QTimer timer;
    timer.setInterval(1000);
    QObject::connect(&timer, SIGNAL(timeout()), classe, SLOT(update_scene()));
    timer.start();
    gbdivers parlait plus haut de problème de conception, comme quoi vous faites du C++ mais que vous traitez tout dans une fonction. Je reprends donc ce qu'il dit : il serait intéressant de faire un arbre de classes par exemple pour le snake, avec une classe mère globale à tous les éléments (murs, morceau de serpent, tête du serpent, etc.) et qui aurait des dérivées (les éléments donnés précédemment). De là, chaque sous-classe aurait un comportement particulier (la tête en contact avec une pomme/mur). Vu que le projet est un projet de C++, je suis certain que les correcteurs seraient intéressés par ce type de chose et que cela déteindrait sur la note.

    Je m'explique également sur l'EDIT fait sur le post précédent quand je parlais de liste chaînée circulaire : le souci que pose votre architecture actuelle est que vous ré-allouez toutes les secondes un objet pour ensuite le positionner devant. Alors, vous retirez le dernier élément. Avec une liste chaînée circulaire, on aurait un référentiel vers la tête. À chaque mouvement, on déplacerait le référentiel de la tête en disant que le dernier devient le premier (donc l'ancien premier devient le deuxième). Du coup, l'unique item qui se déplacerait serait le dernier qui se placerait devant le premier (je ne sais pas si c'est très clair).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     O
    OO
     
    // Mouvement :
     
     OO
     O
     
    // Le dernier item passe devant le premier.
    Bonne continuation,
    Amnell.
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  17. #17
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 20
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Amnell Voir le message
    Re,

    Le souci est que vous partez du principe que l'affichage ne peut être effectué qu'à partir du moment où toute la scène a été remplie et qu'il faut tout effacer pour pouvoir effectuer une modification. Une solution simple est de créer la scène, de créer la vue, de lier les deux puis d'afficher la vue avec show(). Alors, vous pouvez garnir la scène de tous les objets que vous souhaitez afficher ; une peinture de la scène sera effectuée après l'appel de la fonction update() ou repaint() (sauf si cela s'effectue automatiquement, je ne me souviens plus).
    En effet vous m'avez bien cerne , je vais donc tenter de faire comme cela. (même si tout recommencer ou presque ne m;enchante guère le projet étant a rendre sous tres peu x) )

    Citation Envoyé par Amnell Voir le message
    Plutôt que de passer par des pointeurs simples pour gérer les composantes du snake, pourquoi ne pas utiliser une des classes jouant le rôle de conteneur d'éléments (QList/QVector/autre selon les besoins) ?

    Bonne continuation,
    Amnell.

    EDIT : la perspective d'une liste chaînée circulaire pourrait également être envisagée.
    Concernant les conteneurs je crois qu'il y a eu meprise. Mon projet consiste a creer un core qui est le coeur du programme, et a creer separement des fonctions s'occupant de l'affichage graphique. Mon core est d'ores et deja pret et fonctionnel, ma derniere tache n'est autre que de gerer l'affichage du tableau + la gestion des touches. Le reste de l'algo est fait.
    Ma boucle infinie decalant le serpent n'est donc que temporaire, c'est un moyen rapide de tester mon affichage, a terme ils devront disparaitre. (car deja present dans le core). Cette boucle ne sera pas presente dans mon code final, c'est le core qui s'occupera du decalage du serpent et appellera ma fonction AffMap pour afficher le tableau.

    Mon travail sur Qt consiste donc 'juste' a faire une fonction AffMap qui prend en paramètre un tableau d'entiers (envoyé par le core) et qui parcourt ce tableau en inserant les images correspondantes. Mon travail ici ne concerne que le graphique, pas le coeur de l'algo.

    En tous cas merci beaucoup pour l'attention que vous prêtez a mon cas, je m'en veux juste de ne pas avoir les compétences nécessaires pour comprendre et appliquer tout ce qui a été dit sur ce topic car je suis sur que ca marcherait parfaitement...

  18. #18
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Citation Envoyé par Wanabee Voir le message
    En effet vous m'avez bien cerne , je vais donc tenter de faire comme cela. (même si tout recommencer ou presque ne m;enchante guère le projet étant a rendre sous tres peu x) )
    En même temps, si ce n'est "que" l'affichage qui est à réaliser, cela ne devrait pas prendre beaucoup de temps. Avec Qt, le ré-affichage est géré automatiquement, il n'y a pas d'expose à gérer ou autre. Une fois qu'on à placé quelque chose à l'écran, ça y reste jusqu'à ce qu'on retire l'élément en question.
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  19. #19
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 20
    Points : 1
    Points
    1
    Par défaut
    Surement pour vous mais je n'ai pas encore la 'logique' Qt et j'avance donc a tatons.

    Procedons par etapes :

    1- J'appelle dans mon main une fonction createScene()
    2- Cette fonction me cree une scene, puis une vue en la liant a ma scene
    3- J'affiche ma fenetre via show() a la fin de ma fonctione createScene()
    4- J'entre dans la boucle infinie de mon main en commencant par appeler AffMap() qui va ajouter des items sur ma scene comme fait precedemment
    5- J'update ma fenetre via la fonction membre update()
    6- Je supprime mes items (reste le probleme de comment supprimer tous les items du corps du serpent)
    7- Je décale la position du serpent

    Les étapes 4 5 6 et 7 se répétant car étant positionnées dans la boucle infinie.

    Cela vous parait-il viable?

    EDIT : Je viens de tester et l'appel a show() seul ne suffit pas a creer un fenetre, je suppose que vous le saviez mais moi non
    Ma boucle infinie empechant l'execution du return app.exec(), je ne vois pas comment afficher ma fenetre. J'ai cru comprendre qu'en utilisant un QTimer a 0 cela etait possible mais je n'en suis pas sur

  20. #20
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Citation Envoyé par Wanabee Voir le message
    Surement pour vous mais je n'ai pas encore la 'logique' Qt et j'avance donc a tatons.

    Procedons par etapes :

    1- J'appelle dans mon main une fonction createScene()
    2- Cette fonction me cree une scene, puis une vue en la liant a ma scene
    3- J'affiche ma fenetre via show() a la fin de ma fonctione createScene()
    4- J'entre dans la boucle infinie de mon main en commencant par appeler AffMap() qui va ajouter des items sur ma scene comme fait precedemment
    5- J'update ma fenetre via la fonction membre update()
    6- Je supprime mes items (reste le probleme de comment supprimer tous les items du corps du serpent)
    7- Je décale la position du serpent

    Les étapes 4 5 6 et 7 se répétant car étant positionnées dans la boucle infinie.

    Cela vous parait-il viable?
    Je n'aime pas l'idée de faire une boucle infinie avec un sleep dans le sens où cela bloque complètement le process (qui - sauf erreur de ma part - ne peut donc pas faire en interne ses manipulations d'affichage, etc.). Un timer qui appelle une fonction toutes les secondes est bien mieux dans le sens où ça ne bloque pas la boucle principale (app.exec()) et donc, par conséquent, l'affichage. Pour illustrer, sous Windows ou autre système gérant les freezes des fenêtres, avec un sleep de 1 seconde, la fenêtre ne cesserait de freezer et de virer au blanc car les events seraient traités en retard (voire pas du tout).

    Citation Envoyé par Wanabee Voir le message
    EDIT : Je viens de tester et l'appel a show() seul ne suffit pas a creer un fenetre, je suppose que vous le saviez mais moi non et j'ai beau lire les pages de doc je ne comprends pas pourquoi.
    Cela ressemble à un problème de durée de vie. Dans un main, on peut créer une variable de type QWidget et faire un show(). Grâce à app.exec(), la variable ne serait pas détruite avant la fermeture de l'application. Dans une autre fonction, il faudrait créer un pointeur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    QWidget *win = new QWidget();
    win->resize(200, 300);
    win->show();
    À moins que ce ne soit votre sleep qui bloque l'ouverture.

    Bonne continuation,
    Amnell.
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

Discussions similaires

  1. Jeu du snake en python
    Par pythonovice dans le forum Général Python
    Réponses: 1
    Dernier message: 24/04/2015, 10h46
  2. Jeu du Snake
    Par aimasdu06 dans le forum C++
    Réponses: 4
    Dernier message: 30/10/2014, 15h36
  3. Réponses: 2
    Dernier message: 23/06/2013, 14h10
  4. Jeu du snake en C
    Par deWeb dans le forum C
    Réponses: 4
    Dernier message: 01/01/2011, 03h18
  5. Quelques questions sur le tile mapping
    Par LexxusEVC dans le forum Développement 2D, 3D et Jeux
    Réponses: 11
    Dernier message: 21/10/2009, 08h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo