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

Tkinter Python Discussion :

Mise à jour d'un canvas (changer de niveau dans un jeu) [Python 3.X]


Sujet :

Tkinter Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2014
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 43
    Points : 19
    Points
    19
    Par défaut Mise à jour d'un canvas (changer de niveau dans un jeu)
    Bonjour,
    j'ouvre un nouveau fil pour cerner mon dernier problème.

    J'arrive au bout d'un jeu de labyrinthe mais je n'arrive pas à changer de niveau.

    Suit le code d'un de mes essais :
    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
     
    from tkinter import *
     
    def droite(event,win,can,perso):
        can.move(perso, 30, 0)
        can.pack()
     
    def maj(event,win,can,perso):
        # Efface le canvas
        liste = can.find_all()
        for i in liste :
            can.delete(i)
        global personnage
        personnage = can.create_image(0,30, anchor = NW, image = TUX)
        can.pack()
        print(n)
     
    def quitter(event,win):
        win.destroy()
     
    def config_touches( canvas, fen, perso):
        fen.bind("<Right>", lambda event, f = fen, can = canvas, p = perso : droite(event,f,can,p))
        fen.bind("<space>", lambda event, f = fen, can = canvas, p = perso : maj(event,f,can,p))
        fen.bind("<Escape>", lambda event, f = fen : quitter(event,f))
     
    # Création de la fenetre et du canvas
    n = 1
    fenetre = Tk()
    toile = Canvas(fenetre, width = 90, height = 90)
    MUR = PhotoImage(file="mur_h.gif")
    toile.create_image(30,30, anchor = NW, image = MUR)
    TUX = PhotoImage(file="tux.gif")
    personnage = toile.create_image(0,30, anchor = NW, image = TUX)
    toile.pack()
    config_touches(toile,fenetre,personnage)
    fenetre.mainloop()
    C'est la fonction "maj" qui me pose problème. Quand elle est utilisée, la fonction "droite" ne fonctionne plus. J'ai essayé de déclarer "personnage" en global mais il ne se déplace pas avec la fonction "droite".
    Comment faire pour que cette fonction "droite" voit le "personnage".

    Merci d'avance.
    Sylvain.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par SPC89 Voir le message
    C'est la fonction "maj" qui me pose problème. Quand elle est utilisée, la fonction "droite" ne fonctionne plus. J'ai essayé de déclarer "personnage" en global mais il ne se déplace pas avec la fonction "droite".
    Dans la fonction "droite", personnage n'est pas une variable globale mais un paramètre de fonction associé au même objet que celui qui a été associé à personnage à l'instant où a été exécuté le "bind" (dans les paramètres par défaut de vos lambda).
    Dans ces conditions sans refaire le "bind", çà ne peut pas fonctionner.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2014
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 43
    Points : 19
    Points
    19
    Par défaut
    Merci,

    Citation Envoyé par wiztricks Voir le message
    Dans la fonction "droite", personnage n'est pas une variable globale mais un paramètre de fonction associé au même objet que celui qui a été associé à personnage à l'instant où a été exécuté le "bind" (dans les paramètres par défaut de vos lambda).
    - W
    Comme la fonction "droite" marche tant "maj" n'a pas été lancée, je pensais que "personnage" était l'id de l'image.

    Citation Envoyé par wiztricks Voir le message
    Dans ces conditions sans refaire le "bind", çà ne peut pas fonctionner.
    - W
    Je dois donc relancer"config_touches" pour refaire l'association entre "personnage" et cet objet image ?

    Sylvain

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par SPC89 Voir le message
    Comme la fonction "droite" marche tant "maj" n'a pas été lancée, je pensais que "personnage" était l'id de l'image.
    Il ne faut pas penser mais ouvrir votre documentation préférée Tkinter au chapitre Canvas. .create_image retourne un identifiant numérique unique correspondant à l'item créé. C'est un entier qui n'est pas réutilisé par le Canvas (i.e. il est unique).

    Citation Envoyé par SPC89 Voir le message
    Je dois donc relancer"config_touches" pour refaire l'association entre "personnage" et cet objet image ?
    Si vous détruisez l'item pour le remplacer par un autre, stocker sa valeur dans une variable globale comme personnage fonctionne(*). Les autres options sont de changer l'image associée à cet item (canvas.itemconfig(...)) - ce qui évite de créer un nouvel item et donc de modifier l'identifiant - ou de lui associer un tag - dans ce cas, l'identifiant est la chaine de caractères que vous voulez et non un identifiant opaque géré par le Canvas.

    (*) votre soucis est que vu la façon dont vous l'utilisez, ce n'est pas une variable globale (pour les fonctions qui l'utilisent).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2014
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 43
    Points : 19
    Points
    19
    Par défaut
    Merci pour les éclaircissements,

    Citation Envoyé par wiztricks Voir le message
    Il ne faut pas penser mais ouvrir votre documentation préférée Tkinter au chapitre Canvas. .create_image retourne un identifiant numérique unique correspondant à l'item créé. C'est un entier qui n'est pas réutilisé par le Canvas (i.e. il est unique).
    Je ne sais pas comment vous avez commencé, mais cette documentation je l'ai lue et j'en ai lu d'autres. Mais sans une idée (même fausse) au préalable je suis incapable d'y trouver la solution, il y a trop de choses.

    Citation Envoyé par wiztricks Voir le message
    Si vous détruisez l'item pour le remplacer par un autre, stocker sa valeur dans une variable globale comme personnage fonctionne. Votre soucis est que vu la façon dont vous l'utilisez, ce n'est pas une variable globale (pour les fonctions qui l'utilisent).
    Au cas (probable) où je ne comprenne pas la suite, comment faire pour utiliser l'id de l'image comme variable globale ?

    Citation Envoyé par wiztricks Voir le message
    Les autres options sont de changer l'image associée à cet item (canvas.itemconfig(...)) - ce qui évite de créer un nouvel item et donc de modifier l'identifiant - ou de lui associer un tag - dans ce cas, l'identifiant est la chaine de caractères que vous voulez et non un identifiant opaque géré par le Canvas.
    - W
    Je vais essayer cela. J'ai bien besoin de changer l'image associée dans la fonction mouvement pour orienter le personnage en fonction du sens de déplacement. Mais je voudrais complétement modifier le plateau de jeu au changement de niveau. Est-ce mieux d'effacer toutes les images (ici 20x20 soit 400) ou alors de modifier tous les éléments.

    Sylvain.

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par SPC89 Voir le message
    Au cas (probable) où je ne comprenne pas la suite, comment faire pour utiliser l'id de l'image comme variable globale ?
    En évitant de passer personnage en paramètre de vos fonctions (puisque c'est une variable globale...) et après avoir revu dans votre tuto préféré à quoi ressemble une variable globale.

    Citation Envoyé par SPC89 Voir le message
    Est-ce mieux d'effacer toutes les images (ici 20x20 soit 400) ou alors de modifier tous les éléments.
    Les images, c'est ce que l'utilisateur voit, vous vous codez donc vous supprimez ou modifiez des items d'un Canvas.
    De toutes façons, ce sera 400 opérations avec des conséquences sur l'identification des différents items et le temps CPU utilisé s'ils sont remplacés - mais les CPU sont puissants et c'est juste un tableau à deux dimensions à mettre à jour -.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2014
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 43
    Points : 19
    Points
    19
    Par défaut
    Bonjour,
    Citation Envoyé par wiztricks Voir le message
    En évitant de passer personnage en paramètre de vos fonctions (puisque c'est une variable globale...)
    - W
    Effectivement ce n'était pas vraiment judicieux. Mais dans l'exemple que je suis, la gestion des événements est utilisée avec des fonctions lambda.
    Maintenant cela fonctionne parfaitement avec des fonctions "normales" et des variables globales.
    Mais logiquement : des variables globales c'est mal !
    Une fois fenetre.mainloop() exécutée on ne revient plus dans le programme principal. Comment alors faire travailler les différentes fonctions sur des données communes sans utiliser de variables globales ?
    Merci, Sylvain.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par SPC89 Voir le message
    Mais logiquement : des variables globales c'est mal !
    Certes mais avec Python, une variable dite globale n'est pas "globale": leur portée est limitée au module. De plus, lorsque vous définissez une fonction ou une classe, vous créez des déjà variables globales... Et c'est heureux car vous ne pourriez pas les utiliser sinon.

    Citation Envoyé par SPC89 Voir le message
    Une fois fenetre.mainloop() exécutée on ne revient plus dans le programme principal. Comment alors faire travailler les différentes fonctions sur des données communes sans utiliser de variables globales
    Le problème avec les variables globales est leur nombre... qui va rendre le programme difficile à lire car il sera difficile de savoir quelles fonctions utilise/modifie une variable globale donnée. Une solution est de les confiner dans des espaces de noms appelées classes (et donc apprendre à utiliser les constructions de la POO avec Pyhon) ou modules (qui peuvent être vus comme un Singleton particulier).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2014
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 43
    Points : 19
    Points
    19
    Par défaut
    Ok, je vais pouvoir marquer la discussion par "résolu".
    Citation Envoyé par wiztricks Voir le message
    Salut,
    Le problème avec les variables globales est leur nombre... qui va rendre le programme difficile à lire car il sera difficile de savoir quelles fonctions utilise/modifie une variable globale donnée. Une solution est de les confiner dans des espaces de noms appelées classes (et donc apprendre à utiliser les constructions de la POO avec Pyhon) ou modules (qui peuvent être vus comme un Singleton particulier).
    - W
    Malheureusement je n'ai pas le temps de m'attaquer à la POO, il faut que je passe à Python sur Raspberry puis l'utilisation de Django pour y placer un site vaguement dynamique pour les projets de lycée (STI2D).
    Merci, Sylvain.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de mise à jour d'un Canvas
    Par byubi dans le forum Composants
    Réponses: 4
    Dernier message: 03/05/2011, 01h11
  2. mise à jour d'un fichier qui se trouve dans un package .ear
    Par MedNaceur dans le forum Développement Web en Java
    Réponses: 0
    Dernier message: 04/04/2011, 18h17
  3. Mise à jour de la base de données niveau forms
    Par madina dans le forum Forms
    Réponses: 7
    Dernier message: 26/07/2010, 14h31
  4. Réponses: 2
    Dernier message: 24/06/2007, 16h59
  5. mise à jour d'un Canvas
    Par bubu251 dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 11/09/2006, 14h22

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