Annonce

Réduire
Aucune annonce.

Programmation d'une interface graphique (GUI) en Python ?

Réduire
X
 
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • Programmation d'une interface graphique (GUI) en Python ?

    Bonjour,

    J'ai finis le jeu en mode console, et je suis en train de le passer en mode graphique en utilisant le module tkinter.

    En fait, c'est un personnage qui se déplace dans un labyrinthe, s'il trouve un trésor il gagne des pièces d'or (PO dans la barre), s'il trouve un ennemi il le tue mais il perd des points de vie PV. Le trésor comme les ennemies sont des nombre aléatoire.

    Le soucis que je rencontre en mode graphique c'est que je n'arrive pas à comprendre comment il faut écrire pour que, lorsque je touche un trésor ou en ennemi, le faire disparaître tel qu'il le fait en mode console.

    PD: Je vous laisse aussi le zip avec tous les fichiers du mode graphique (sprites et *.py)
    https://mega.co.nz/#!xZYXULhC!CfYuZO...ulAY1_u-SMIOzM

    MODE CONSOLE

    level_.txt
    Code:
    +------------------+
    |       |          |
    |--- +  |  ----+ $ |
    |  1 |         | 3 |
    | +  +-----+ $ | $ |
    | |  $     | 2 |   |
    | +---+    +---+   |
    |     |            |
    |--+  +------------|
    |     |     $      |
    |--+  |   +        |
    | 3|  +   |   +----|
    | $|      |      2 |
    |  +------+---+    |
    |             |    |
    |    +----+ $ +    |
    |    |             |
    | +--|   +---------|
    |    |     $      O|
    +------------------+
    Lab.py
    Code:
    import random
    import curses
    
    def init_curses(lignes,cols,pos):
        curses.initscr()
        curses.noecho()
        curses.cbreak()
        curses.curs_set(0)
    
        window = curses.newwin(lignes,cols,pos[0],pos[1])
        window.border(0)
        window.keypad(1)
        return window
    
    def close_curses():
        curses.echo()
        curses.nocbreak()
        curses.curs_set(1)
        curses.endwin()
    
    def init_colors():
        curses.start_color()
        curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
        curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK)
        curses.init_pair(3, curses.COLOR_BLACK, curses.COLOR_BLUE)
        return ["RED","GREEN","BLUE"]
    
    def color(code, l_color):
        return curses.color_pair(l_color.index(code)+1)
        
    
    def charge_labyrinthe(nom):
        try:
            fic = open(nom+".txt","r")
            data = fic.readlines()
            fic.close()
        except IOError:
            print("Impossible de lire le fichier {}.txt".format(nom))
            exit(1)
    
        for i in range(len(data)):
            data [i] = data[i].strip()
    
        return data
    
    
    def barre_score(data, win, coul):
        barre = "PV : {:2d}    PO : {:4d}    Level : {:3d}"
        win.addstr(21, 1, barre.format(data["pv"],data["po"], data["level"]), color("BLUE", coul))
                                                                 
        
    def affiche_labyrinthe(lab,perso,pos_perso, tresor, win, coul):
        n_ligne = 0
        for ligne in lab:
            for i in range(1,4):
                ligne = ligne.replace(str(i), tresor)
            if n_ligne == pos_perso[1]:
                win.addstr(n_ligne+1,10, ligne[0:pos_perso[0]]+perso+ligne[pos_perso[0]+1:])
                win.addstr(n_ligne+1,10+pos_perso[0],perso,color("RED",coul))
            else:
                win.addstr(n_ligne+1,10,ligne)
            n_ligne = n_ligne + 1
    
    def decouverte_tresor(categorie, data):
        if categorie == "1":
            data["po"] = data["po"] + random.randint(1,5)
        elif categorie == "2":
            data["po"] = data["po"] + random.randint(5,10)
        else:
            data["po"] = data["po"] + random.randint(0,25)
    
    def combat(data):
        de = random.randint(1,10)
        if de ==1:
            data["pv"] = data["pv"] - random.randint(5,10)
        elif de >=2 and de <=4:
            data["pv"] = data["pv"] - random.randint(1,5)
    
    def verification_deplacement(lab,pos_col,pos_ligne,data):
        n_cols = len(lab[0])
        n_lignes = len(lab)
        if pos_ligne < 0 or pos_col < 0 or pos_ligne > (n_lignes -1) or pos_col > (n_cols-1):
            return None
        elif lab[pos_ligne][pos_col] == "O":
            return[-1,-1]
        elif lab[pos_ligne][pos_col]=="1" or lab[pos_ligne][pos_col]== "2" or lab[pos_ligne][pos_col]== "3":
            decouverte_tresor(lab[pos_ligne][pos_col],data)
            lab[pos_ligne] = lab[pos_ligne][:pos_col]+" "+lab[pos_ligne][pos_col+1:]
            return[pos_col, pos_ligne]
        elif lab[pos_ligne][pos_col] == "$":
            combat(data)
            lab[pos_ligne] = lab[pos_ligne][:pos_col]+" "+lab[pos_ligne][pos_col+1:]        ### SUPPRIME LE TRESOR TROUVE
            return[pos_col, pos_ligne]                                                      ###
        elif lab[pos_ligne][pos_col] != " ":
            return None
        else:
            return[pos_col,pos_ligne]
    
    def choix_joueur(lab,pos_perso,data,win):
        dep = None
        choix = win.getch()
        if choix == curses.KEY_UP:
            dep = verification_deplacement(lab, pos_perso[0], pos_perso[1]-1, data)
        elif choix == curses.KEY_DOWN:
            dep = verification_deplacement(lab, pos_perso[0], pos_perso[1]+1, data)
        elif choix == curses.KEY_LEFT:
            dep = verification_deplacement(lab, pos_perso[0] -1, pos_perso[1], data)
        elif choix == curses.KEY_RIGHT:
            dep = verification_deplacement(lab, pos_perso[0] +1, pos_perso[1], data)
        elif choix == 27:
            close_curses()
            exit(0)
        if dep != None:
            pos_perso[0] = dep[0]
            pos_perso[1] = dep[1]
        
    
    def jeu(level, data, perso, pos_perso, tresor, win, coul):
        while True:
            affiche_labyrinthe(level, perso, pos_perso, tresor, win, coul)
            barre_score(data, win, coul)
            if data["pv"] <=0:
                win.addstr(1,20,"Vous avez PERDU", color("RED",coul))
                win.getch()
                close_curses()
                exit(0)
            choix_joueur(level, pos_perso,data,win)
            if pos_perso == [-1,-1]:
                win.addstr(22,1, "Vous avez passé le niveau!", color("RED",coul))
                win.addstr(23,1, "Appuyez sur <Return> pour continuer", color("RED",coul))
                win.getch()
                win.addstr(1,20," "*50)
                win.addstr(1,21," "*50)
                break
    GLMF_Game.py

    Code:
    #!/usr/bin/python3
    import Lab
    
    if __name__ == "__main__":
    
        perso          = "X"
        pos_perso      = [1,1]
        tresor         = "#"
        n_levels_total = 20
        data = {
            "po"   : 0,
            "pv"   : 25,
            "level": None
        }
    win = Lab.init_curses(25,41,(0,0))
    coul = Lab.init_colors()
    
    #Lancement de la partie
    for n_level in range(1, n_levels_total+1):
        level = Lab.charge_labyrinthe("level_"+ str(n_level))
        data["level"] = n_level
        Lab.jeu(level, data, perso, pos_perso, tresor,win,coul)
    win.addstr(1,22, "Vous avez gagné!", Lab.color("RED",coul))
    win.getch()
    Lab.close_curses()
    MODE GRAPHIQUE

    LEVEL_1.txt est le même

    Lab.py

    Code:
    import random
    from tkinter import *
    
    def charge_labyrinthe(nom):
        try:
            fic = open(nom+".txt","r")
            data = fic.readlines()
            fic.close()
        except IOError:
            print("Impossible de lire le fichier {}.txt".format(nom))
            exit(1)
    
        for i in range(len(data)):
            data [i] = data[i].strip()
    
        return data
                                                                 
        
    def affiche_labyrinthe(lab,fenetre,size_sprite,pos_perso):
        can = Canvas(fenetre, width = 600, height = 600)
        photo_wall     = PhotoImage(file = "sprites/wall.gif")
        photo_treasure = PhotoImage(file = "sprites/treasure.gif")
        photo_ennemy   = PhotoImage(file = "sprites/ennemy.gif")
        photo_exit     = PhotoImage(file = "sprites/exit.gif")
        photo_hero     = PhotoImage(file = "sprites/hero.gif")
    
        n_ligne = 0
        for ligne in lab:
            n_col = 0
            for car in ligne:
                if car == "+" or car == "-" or car =="|":
                    can.create_image(n_col + n_col * size_sprite, n_ligne + n_ligne * size_sprite, anchor = NW, image = photo_wall)
                if car == "1" or car == "2" or car == "3":
                    can.create_image(n_col + n_col * size_sprite, n_ligne + n_ligne * size_sprite, anchor = NW, image = photo_treasure)
                if car == "$":
                    can.create_image(n_col + n_col * size_sprite, n_ligne + n_ligne * size_sprite, anchor = NW, image = photo_ennemy)
                if car == "O":
                    can.create_image(n_col + n_col * size_sprite, n_ligne + n_ligne * size_sprite, anchor = NW, image = photo_exit)
                n_col +=1
            n_ligne +=1
        #affiche personnage
        sprite_hero = can.create_image(pos_perso[0] + pos_perso[0] * size_sprite, pos_perso[1] + pos_perso[1] * size_sprite, anchor = NW, image = photo_hero)
    
        #Ce texte montre le niveau, plus tard je essaiera de rajouter la barre score
        data = can.create_text(pos_perso[0] + pos_perso[0] * size_sprite, pos_perso[1] + pos_perso[1] * size_sprite, anchor = NW, text = "LEVEL_1")
        
        can.pack()
    	
    
        return (can, sprite_hero, {
            "hero"     : photo_hero,
            "wall"     : photo_wall,
            "treasure" : photo_treasure,
            "ennemy"   : photo_ennemy,
            "exit"     : photo_exit})
    
    
    def deplacement(event,can,dep,lab,pos_perso,perso):
        n_cols = len(lab[0])
        n_lignes = len(lab)
        pos_col, pos_ligne = [pos_perso[0], pos_perso[1]]
    
        if dep == "right":
            pos_col += 1
        if dep == "left":
            pos_col -=1
        if dep == "up":
            pos_ligne -= 1
        if dep == "down":
            pos_ligne +=1
         
    	
        #si le deplacement n'est pas possible return None"
        if pos_ligne <0 or pos_col <0 or pos_ligne > (n_lignes-1) or pos_col>(n_cols -1):
            return None
        #deplacement case vide, ok
        if lab[pos_ligne][pos_col] == " ":
            can.coords(perso, pos_col + pos_col * 30, pos_ligne + pos_ligne * 30)
            del pos_perso[0]
            del pos_perso[0]
            pos_perso.append(pos_col)
            pos_perso.append(pos_ligne)
        #if lab[pos_ligne][pos_col] == "$":
        #comment faire pour effacer l'ennemy "$"
        #if lab[pos_ligne][pos_col] == "O":
        #return [-1,-1]
        # J'ai essayé avec break quand la position est -1,-1 mais en mode grafique no fonctionne pas.
            
            
    def destroy(event,fenetre):
        fenetre.destroy()
        
    
    def init_touches(fenetre, canvas, lab, pos_perso, perso):
        fenetre.bind("<Right>", lambda event, can = canvas, l =lab, pos = pos_perso, p = perso: deplacement(event, can, "right", l, pos, p))
        fenetre.bind("<Left>", lambda event, can = canvas, l =lab, pos = pos_perso, p = perso: deplacement(event, can, "left", l, pos, p))
        fenetre.bind("<Down>", lambda event, can = canvas, l =lab, pos = pos_perso, p = perso: deplacement(event, can, "down", l, pos, p))
        fenetre.bind("<Up>", lambda event, can = canvas, l =lab, pos = pos_perso, p = perso: deplacement(event, can, "up", l, pos, p))
        fenetre.bind("<Escape>", lambda event, fen = fenetre : destroy(event, fen))
    GLMF_Game.py
    Code:
    #!/usr/bin/python3
    import Lab
    from tkinter import *
    
    if __name__ == "__main__":
    
        perso          = "X"
        pos_perso      = [1,1]
        tresor         = "#"
        n_levels_total = 20
        data = {
            "po"   : 0,
            "pv"   : 25,
            "level": None
        }
        size_sprite = 29
        #Initialisation de l'affichage graphique
        fenetre = Tk()
        fenetre.title("GLMF Game")
        #Lancement de la partie
        level = Lab.charge_labyrinthe("level_1")
    
        (canvas, sprite_perso, photos) = Lab.affiche_labyrinthe(level, fenetre, size_sprite, pos_perso)
        Lab.init_touches(fenetre, canvas, level, pos_perso, sprite_perso)
        #Boucle événementielle
        fenetre.mainloop()
    Dernière modification par Zorbak, 17 mai 2014, 19h01. Motif: Correction fautes

  • #2
    Bonjour,

    Program mode grafique
    "Programme"
    "Graphique"

    Quand même...
    Je corrige ça et ton post, fais attention la prochaine fois


    Suivre Hackademics: Twitter, Google+, Facebook.

    Commentaire


    • #3
      Envoyé par _47 Voir le message
      Bonjour,


      "Programme"
      "Graphique"

      Quand même...
      Je corrige ça et ton post, fais attention la prochaine fois
      Je ne suis pas français donc je n'ai pas trop l'habitude d'écrire en français, mais je vais utiliser systématiquement le correcteur, ne vous inquiétez pas.

      Commentaire


      • #4
        Dans ce cas là pas de problème, je serais moins exigeant


        Suivre Hackademics: Twitter, Google+, Facebook.

        Commentaire


        • #5
          Le soucis que je rencontre en mode graphique c'est que je n'arrive pas à comprendre comment il faut écrire pour que lorsque je touche un trésor ou en ennemie, le faire disparaître tel qu'il le fait en mode console.
          Quel est l'objet python que tu souhaites faire disparaître lorsque tu touches un trésor (Canvas, ...) ?

          Dans un Canvas, tu crées plusieurs item (images, rectangle, cercle, ...). La suppression se fait simplement.

          Code:
          myCanvas.delete(item)
          Si ton moteur de jeu (sans graphique) est performant, tu dois pouvoir détecter la présence entre trésor et l'image.

          Commentaire


          • #6
            En fait je ne pense pas du tout que le moteur sans graphique sois performant (est simple mais fonctionnel).

            Je l'ai fait en suivant un tutoriel qui propose aux néophytes comme moi (partant de 0 connaissances) faire un jeux, et à la fin il commence à l'écrire en mode graphique mais il ne le finis pas... donc je souhaitais le faire. Mais après voir et revoir plein des fois le code... je vais sans doute acheter un livre pour apprendre python de 0, et des que j'aurais des bonnes bases reprendre le jeux.

            Merci de ta réponse Fred.

            Commentaire


            • #7
              Tu sais c'est assez simple

              Voici un exemple

              Code:
              sol = ['M', None, 'B', None, None, 'M'] # représentation du sol
              
              # M -> Mur
              # B -> Bonhomme
              # None -> Rien
              
              actuellePosition = sol.index('B') # position actuelle du bonhomme
              
              # déplacement du bonhomme, tant qu'on rencontre pas le Mur
              
              while sol[actuellePosition+1] != 'M':
                  sol[actuellePosition+1] = 'B' # le bonhomme avance
                  sol[actuellePosition] = None # il ne reste plus rien à cette position
                  actuellePosition = sol.index('B') # index de la nouvelle position du bonhomme
              
              print(sol) # ['M', None, None, None, 'B', 'M']
              Ensuite rien n'empêche de créer une fonction permettant la détection du bonhomme et d'en faire ce que tu veux, même le supprimer

              Commentaire

              Chargement...
              X