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 :

.bind et POO [Python 3.X]


Sujet :

Tkinter Python

  1. #1
    Membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Mai 2018
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2018
    Messages : 47
    Points : 40
    Points
    40
    Par défaut .bind et POO
    Bonjour,

    J'ai lié mes flèches directionnelles à une méthode on_arrow qui renvoie la direction (cx,cy)

    Je veux ensuite mettre cette direction en argument d'une méthode de la classe pacman pour le faire bouger.

    Au début, comme je n'appuie pas sur les flèches directionnelles, la méthode update_pacman_pos recoit une fonction en argument au lieu d'un tuple d'entier et cela ne marche donc pas.

    J'ai mis en PJ le niveau 1 qu'il faut mettre dans un dossier Map

    Comment je peux faire pour régler le problème ?

    Cette façon d'écrire le programme est elle correcte ?

    Merci

    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
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    from tkinter import Tk, Canvas, Frame
    from numpy import loadtxt, ndenumerate
     
    # Constants
    CASE_SIZE = 20
    PAC_SIZE = 8 # rayon
     
    MOTIONS = {
                'Up':   (0, -1),
                'Down': (0, 1),
                'Left': (-1, 0),
                'Right':(1, 0)
               }
     
    # Class
     
    class Level():
        def __init__(self):
            self.level_number = 1
            self.load_map()
     
        def load_map(self):
            file_name = 'Map/' + str(self.level_number) + '.txt'
            self.map_game = loadtxt(file_name)
     
        def get_map(self):
            return self.map_game
     
    class Pacman:
        def __init__(self,map_game):
            self.init_position(map_game)
     
        def init_position(self,map_game):
            for (x,y), value in ndenumerate(map_game):
                if map_game[x,y] == 2:
                    self.case_row = x
                    self.case_column = y
                    break
     
        def get_position(self):
            return (self.case_row,self.case_column)   
     
        def update_pacman_pos(self,direction): 
            if direction:
                cx = direction[0]
                cy = direction[1]
                if self.check_terrain(self):
                    self.case_row = self.case_row + cy 
                    self.case_column = self.case_column + cx
     
        def check_terrain(self):
            row = self.case_row + self.cy 
            col = self.case_column + self.cx
            if col >= 0 and col < self.map_game.shape[1] and \
                row >= 0 and row < self.map_game.shape[0] and \
                self.map_game[row,col] !=1:
                    return True            
     
    class GUI:
        def __init__(self,map_game,root):    
            self.root = root
            self.map_game = map_game
            self.init_game_graphics()
            self.init_terrain()
            self.pacman_motion()
     
        def init_game_graphics(self):
            lar = self.map_game.shape[0]*CASE_SIZE
            hau = self.map_game.shape[1]*CASE_SIZE  
     
            self.frame_game = Frame(self.root,bg="light yellow")
            self.frame_game.pack()
     
            self.can_game = Canvas(self.frame_game,width=lar, height=hau, bg="black")
            self.can_game.pack(padx =10, pady=(0,10),side=('bottom'))
            self.can_game.focus_set()              
     
        def init_terrain(self):
            for (x,y), value in ndenumerate(self.map_game):
                if self.map_game[x,y] == 1:
                    self.can_game.create_rectangle(y*CASE_SIZE,x*CASE_SIZE,
                                               (y+1)*CASE_SIZE,(x+1)*CASE_SIZE,
                                              outline='blue')            
     
        def cercle(self,x, y, r, coul ='black'):
            self.can_game.create_oval(x-r, y-r, x+r, y+r, fill=coul) 
     
        def draw_boule(self,pos,coul):
            row = pos[0]
            col = pos[1]
            self.boule = self.cercle(col*CASE_SIZE+CASE_SIZE/2,row*CASE_SIZE+CASE_SIZE/2, PAC_SIZE,coul)        
     
        def pacman_motion(self):
            for key in MOTIONS:
                self.can_game.bind('<%s>' % key, self.on_arrow) 
     
        def on_arrow(self, event):
            direction = event.keysym
            cx, cy = MOTIONS[direction] 
            return (cx,cy)
     
    # Main 
    root = Tk()
    launch_level = Level()   
    map_game = launch_level.get_map()
    pacman = Pacman(map_game)
     
    graphique = GUI(map_game,root)   
    graphique.draw_boule(pacman.get_position(),"gold")
     
    pacman.update_pacman_pos(GUI.on_arrow) 
     
    root.mainloop()
    Fichiers attachés Fichiers attachés
    • Type de fichier : txt 1.txt (55 octets, 79 affichages)

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 292
    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 292
    Points : 36 788
    Points
    36 788
    Par défaut
    Salut,

    Citation Envoyé par Kazvert Voir le message
    Comment je peux faire pour régler le problème ?

    Cette façon d'écrire le programme est elle correcte ?
    on_arrow est un callback qui sera appelé par tkinter lorsqu'on appuie sur une flèche comme vous l'avez demandé via les .bind. Si elle et appelée par tkinter, c'est que vous n'allez jamais récupérer le (cx,cy) qu'elle retourne. Et ce qui me laisse perplexe est ce que vous espérez en écrivant pacman.update_pacman_pos(GUI.on_arrow): çà ne peut pas fonctionner comme çà!!!
    Et à part vous recommander s'ouvrir un tuto. pour apprendre les bases de la programmation avec tkinter, je ne peux pas faire grand chose pour vous, désolé.

    - W

  3. #3
    Membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Mai 2018
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2018
    Messages : 47
    Points : 40
    Points
    40
    Par défaut
    J'avais compris que le binder ne marche qu'en cas d’interaction avec le clavier mais je ne vois pas comment faire dans ce cas pour transférer cx et cy. Je vais continuer à chercher.

    J'avais aussi fait un programme avec seulement deux classes ou cela marche assez bien mais je trouve que l'on s'y perd de trop sur le reste.

    Pour le tuto, je lis : Tkinter GUI Application development Blueprints de Bhaskar Chaudhary. Dans son exemple avec les classes au chapitre III, il n'utilise qu'une classe, cela simplifie pas mal les problèmes je trouve. J'espère qu'il traite de problèmes avec plusieurs classes ensuite.

    C'es un peu long, mais mon code pacman avant (il manque l'algo de recherche de chemin que j'importe au début) :

    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
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    from tkinter import Tk, Frame, Canvas,X, Label , StringVar
    from numpy import loadtxt, ndenumerate
    import Algo_A_V5
     
    MOTIONS = {
                'Up':   (0, -1),
                'Down': (0, 1),
                'Left': (-1, 0),
                'Right':(1, 0)
               }
     
    CASE_SIZE = 20
    COIN_SIZE = 5 # rayon
    PAC_SIZE = 8 # rayon
    LIFE = 3
    ENNEMI_SPEED = 300
     
    def cercle(cadre,x, y, r, coul ='black'):
        "tracé d'un cercle de centre (x,y) et de rayon r"
        return(cadre.create_oval(x-r, y-r, x+r, y+r, fill=coul))
     
    class PacMan:
        def __init__(self, root):   
            self.game_over = False
            self.level = 1
            self.life = LIFE
            self.run_game = True 
            self.score = 0          
            self.load_map()
            self.init_position() 
            self.root = root
            self.root.title('Pac Man')
            self.init_game_graphics()     
            self.free_case = self.map_game.shape[0]*self.map_game.shape[1]
            self.init_terrain()    
            self.init_boule()
            self.boule_motion_launch()
            self.ennemi_A = Ennemie(self.can_game,self.map_game)
            self.ennemi_A.pacman_position(self.case_row,self.case_column)   
            self.ennemi_A.path()
            self.move()     
     
        def relaunch_game(self):
            self.game_over = False
            self.can_game.delete('all') 
            self.level = 1
            self.life = LIFE        
            self.run_game = True 
            self.score = 0
            self.load_map()
            self.init_position()
            self.free_case = self.map_game.shape[0]*self.map_game.shape[1]
            self.init_terrain()    
            self.init_boule()
            self.boule_motion_launch()
          #  self.ennemi_A = Ennemie(self.can_game,self.map_game)
     
        def init_position(self):
            for (x,y), value in ndenumerate(self.map_game):
                if self.map_game[x,y] == 2:
                    self.case_row = x
                    self.case_column = y
                    break
     
        def init_game_graphics(self):
            self.lar = self.map_game.shape[0]*CASE_SIZE
            self.hau = self.map_game.shape[1]*CASE_SIZE
     
            self.frame_game = Frame(self.root,bg="light yellow")
            self.frame_game.pack()
     
            self.can_game = Canvas(self.frame_game,width=self.lar, height=self.hau, bg="black")
            self.can_game.pack(padx =10, pady=(0,10),side=('bottom'))
            self.can_game.focus_set()
     
            self.label_var_score = StringVar()
            self.label_score = Label(self.frame_game,textvariable=self.label_var_score, bg="light yellow", font='Helvetica 7 bold italic')
            self.label_score.pack(side=('bottom'))
     
            self.label_var_score.set('Score ' + str(self.score))           
            self.label_var_level = StringVar()
            self.label_level = Label(self.frame_game,textvariable=self.label_var_level, bg="light yellow", font='Helvetica 7 bold italic')
            self.label_level.pack(side=('left'),padx = (20,0))
            self.label_var_level.set('Level ' + str(self.level))
     
            self.label_var_life = StringVar()
            self.label_life = Label(self.frame_game,textvariable=self.label_var_life, bg="light yellow", font='Helvetica 7 bold italic')
            self.label_life.pack(side=('right'), padx=(0,20))
            self.label_var_life.set('Life ' + str(self.life))
     
        def load_map(self):
            file_name = 'Map/' + str(self.level) + '.txt'
            self.map_game = loadtxt(file_name) 
     
        def on_arrow(self, event):
            self.direction = event.keysym
            self.cx, self.cy = MOTIONS[self.direction]   
            self.move()
     
        def init_boule(self):
     
            self.can_game.delete("pacman")
     
            self.boule = cercle(self.can_game, self.case_column*CASE_SIZE+CASE_SIZE/2,
                                self.case_row*CASE_SIZE+CASE_SIZE/2, PAC_SIZE,"gold") 
            self.can_game.addtag_withtag("pacman",self.boule)
            self.direction = None 
            self.cy = 0      
            self.cx = 0  
     
        def restart(self,event):
            self.can_game.delete('all')
            if self.game_over:
                self.relaunch_game()
     
        def boule_motion_launch(self):
            for key in MOTIONS:
                self.can_game.bind('<%s>' % key, self.on_arrow)  
     
        def check_ennemi_pos(self): 
            ennemi_pos = self.ennemi_A.ennemi_position()
            print(ennemi_pos)
            row = ennemi_pos[0]
            col = ennemi_pos[1]
            if self.case_row == row and self.case_column == col:        
                self.echec()
                return False
            else:
                return True
     
        def echec(self):     
            print("failure")               
            self.life -= 1 
            self.label_var_life.set('Life ' + str(self.life))
            if self.life == 0:
                self.run_game = False 
                self.can_game.delete('all')
                self.can_game.create_text(self.lar/2, self.hau/2, fill="white",font="Times 8 italic bold",text="Game Over,\n Press enter to restart")  
                self.game_over = True
                self.can_game.bind('<Return>', self.restart)
            else:    
                self.init_position()
                self.init_boule()
                self.ennemi_A.relaunch()
     
        def move(self): 
            if self.direction and self.check_terrain() and self.run_game:  
                self.case_row = self.case_row + self.cy
                self.case_column = self.case_column + self.cx     
                self.ennemi_A.pacman_position(self.case_row,self.case_column) 
     
     
     
     
                if self.check_ennemi_pos():    
                    self.can_game.move(self.boule,self.cx*CASE_SIZE,self.cy*CASE_SIZE)   
                    if self.map_game[self.case_row,self.case_column] != 0:
                        self.object_eater()
                        self.victory()       
            #self.can_game.after(150,self.move)   
     
        def victory(self):
            if self.free_case == 0:
                print("victory")
     
        def update_score(self):
            if self.map_game[self.case_row,self.case_column]==2:
                self.score = self.score+1
            elif self.map_game[self.case_row,self.case_column]==3:  
                self.score = self.score+2
            self.label_var_score.set('Score ' + str(self.score))             
     
        def object_eater(self):   
            self.update_score()
            object_finder = self.can_game.find_enclosed((self.case_column+1/2)*CASE_SIZE-COIN_SIZE-1, 
                                                   (self.case_row+1/2)*CASE_SIZE-COIN_SIZE-1,
                                                   (self.case_column+1/2)*CASE_SIZE+COIN_SIZE+1, 
                                                   (self.case_row+1/2)*CASE_SIZE+COIN_SIZE+1)        
            self.can_game.delete(object_finder[0])
            self.map_game[self.case_row,self.case_column] = 0
            self.free_case -= 1
     
        def check_terrain(self):
            row = self.case_row + self.cy 
            col = self.case_column + self.cx
            if col >= 0 and col < self.map_game.shape[1] and \
                row >= 0 and row < self.map_game.shape[0] and \
                self.map_game[row,col] !=1:
                    return True   
     
        def init_terrain(self):    
            for (x,y), value in ndenumerate(self.map_game):
                if self.map_game[x,y] == 1:
                    self.can_game.create_rectangle(y*CASE_SIZE,x*CASE_SIZE,
                                               (y+1)*CASE_SIZE,(x+1)*CASE_SIZE,
                                              outline='blue')  
                    self.free_case -= 1
                elif self.map_game[x,y] == 2:
                    cercle(self.can_game,CASE_SIZE*(y+1/2),CASE_SIZE*(x+1/2),
                           COIN_SIZE,"yellow")                    
                elif self.map_game[x,y] == 3:     
                    cercle(self.can_game,CASE_SIZE*(y+1/2),CASE_SIZE*(x+1/2),
                           COIN_SIZE,"green")   
     
    class Ennemie():
        def __init__(self, can_game,map_game):  
            self.can_game = can_game
            self.map_game = map_game         
            self.position = self.init_position() 
            self.draw_boule()
            self.pac_man_row = float('inf') 
            self.pac_man_col = float('inf') 
            self.counter_motions = 0
            self.cx = 0
            self.cy = -1       
     
            if self.pac_man_row < float('inf'):  
                source = [self.case_row,self.case_column]  
                target = [self.pac_man_row,self.pac_man_col] 
                print(target)
     
        def init_position(self):
            for (x,y), value in (ndenumerate(self.map_game)):
                if self.map_game[x,y] == 2:
                    self.case_row = x
                    self.case_column = y
     
        def draw_boule(self):  
            self.can_game.delete("ennemi")        
            self.boule = cercle(self.can_game, self.case_column*CASE_SIZE+CASE_SIZE/2,
                                self.case_row*CASE_SIZE+CASE_SIZE/2, PAC_SIZE,"red")
            self.can_game.addtag_withtag("ennemi",self.boule)
     
        def path(self):
            source = [self.case_row,self.case_column]  
            target = [self.pac_man_row,self.pac_man_col] 
            self.Algo = Algo_A_V5.Algo_A(source,target,self.map_game)     
            self.motion_list = self.Algo.return_result()
            self.ma_liste_titled=[]     # UP => Up, LEFT => Left 
            [self.ma_liste_titled.append(self.motion_list[i].title()) for i in range(len(self.motion_list))]
            self.move() 
     
        def move(self):  
            if self.ma_liste_titled:
                self.cx, self.cy = MOTIONS[self.ma_liste_titled.pop(0)]
                self.case_row = self.case_row + self.cy
                self.case_column = self.case_column + self.cx  
                self.can_game.move(self.boule,self.cx*CASE_SIZE,self.cy*CASE_SIZE)                  
                self.can_game.after(ENNEMI_SPEED,self.move)  
            else:
                self.path()
     
        def ennemi_position(self):
            return (self.case_row,self.case_column)
     
        def pacman_position(self,row,col):
            self.pac_man_row = row
            self.pac_man_col = col
     
        def relaunch(self):
            print("ok")
            self.init_position()
            self.draw_boule()
     
    if __name__ == '__main__':
        root = Tk()
        pacMan_launch = PacMan(root)
     
    root.mainloop()

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 292
    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 292
    Points : 36 788
    Points
    36 788
    Par défaut
    Salut,

    Citation Envoyé par Kazvert Voir le message
    Pour le tuto, je lis : Tkinter GUI Application development Blueprints de Bhaskar Chaudhary. Dans son exemple avec les classes au chapitre III, il n'utilise qu'une classe, cela simplifie pas mal les problèmes je trouve. J'espère qu'il traite de problèmes avec plusieurs classes ensuite.
    tkinter est un des rares GUI que vous pouvez apprendre sans utiliser des constructions de la POO.
    Vous pourriez commencer par essayer de déplacer un carre ou un cercle d'un Canvas avec les flèches.
    Ca se fait en quelques lignes et çà vous permettrait de voir (et comprendre) comment fonctionnent les mécanismes à utiliser.


    - W

  5. #5
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 301
    Points : 6 781
    Points
    6 781
    Par défaut
    Ce qu'on te dit est que le return du slot on_arrow n'a aucun sens. return à qui ?

    Remplace ça par pacman.update_pacman_pos(cx,cy)

    Et supprime pacman.update_pacman_pos(GUI.on_arrow)

  6. #6
    Membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Mai 2018
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2018
    Messages : 47
    Points : 40
    Points
    40
    Par défaut
    J'aimerais ne pas appeler pacman.update_pacman_pos(cx,cy) dans ma classe GUI mais j'aimerais l’appeler dans mon main. Je ne sais pas si c'est possible

    J'arrive bien à faire bouger ma boule avec une seule classe.

    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
    from tkinter import Tk, Frame, Canvas
    from numpy import ndenumerate, zeros
     
    MOTIONS = {
                'Up':   (0, -1),
                'Down': (0, 1),
                'Left': (-1, 0),
                'Right':(1, 0)
               }
     
    CASE_SIZE = 20
    PAC_SIZE = 8 # rayon
     
    def cercle(cadre,x, y, r, coul ='black'):
        "tracé d'un cercle de centre (x,y) et de rayon r"
        return(cadre.create_oval(x-r, y-r, x+r, y+r, fill=coul))
     
    class PacMan:
        def __init__(self, root):      
            self.root = root
            self.map_game = zeros((10,10))        
            self.init_game_graphics() 
            self.case_row = 0        
            self.case_column = 0         
            self.init_boule()
            self.boule_motion_launch()  
     
        def init_game_graphics(self):
            self.lar = self.map_game.shape[0]*CASE_SIZE
            self.hau = self.map_game.shape[1]*CASE_SIZE
     
            self.frame_game = Frame(self.root,bg="light yellow")
            self.frame_game.pack()
     
            self.can_game = Canvas(self.frame_game,width=self.lar, height=self.hau, bg="black")
            self.can_game.pack(padx =10, pady=10)
            self.can_game.focus_set()
     
        def on_arrow(self, event):
            self.direction = event.keysym
            self.cx, self.cy = MOTIONS[self.direction]   
            self.move()
     
        def init_boule(self):
            self.can_game.delete("pacman")
            self.boule = cercle(self.can_game, self.case_column*CASE_SIZE+CASE_SIZE/2,
                                self.case_row*CASE_SIZE+CASE_SIZE/2, PAC_SIZE,"gold") 
            self.can_game.addtag_withtag("pacman",self.boule)
            self.direction = None 
            self.cy = 0      
            self.cx = 0  
     
        def boule_motion_launch(self):
            for key in MOTIONS:
                self.can_game.bind('<%s>' % key, self.on_arrow)  
     
        def move(self): 
            if self.direction and self.check_terrain():  
                self.case_row = self.case_row + self.cy
                self.case_column = self.case_column + self.cx      
                self.can_game.move(self.boule,self.cx*CASE_SIZE,self.cy*CASE_SIZE)   
     
        def check_terrain(self):
            row = self.case_row + self.cy 
            col = self.case_column + self.cx
            if col >= 0 and col < self.map_game.shape[1] and row >= 0 and row < self.map_game.shape[0]:
                return True   
     
    if __name__ == '__main__':
        root = Tk()
        pacMan_launch = PacMan(root)
     
    root.mainloop()

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 292
    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 292
    Points : 36 788
    Points
    36 788
    Par défaut
    Citation Envoyé par Kazvert Voir le message
    J'aimerais ne pas appeler pacman.update_pacman_pos(cx,cy) dans ma classe GUI mais j'aimerais l’appeler dans mon main. Je ne sais pas si c'est possible
    Si vous compreniez comment fonctionne tkinter (et n'importe quelle application pilotée par les évènements) vous comprendriez que ce n'est pas possible.

    Citation Envoyé par Kazvert Voir le message
    J'arrive bien à faire bouger ma boule avec une seule classe.
    L'idée des classes est de partitionner l'application en entités étanches (définies par les différentes boîtes construites par ces classes) pour pouvoir leur donner des rôles et des responsabilités bien définis. Le soucis étant ensuite de définir relations et interfaces qui vont permettre à ces entités d'échanger des informations.
    Savoir faire çà s'appelle faire de la POO et c'est un style de programmation à apprendre indépendamment du langage (car les solutions s'appliquent à tous les langages OO).

    Sûr que programmer avec une seule classe, c'est comme programmer sans classe du tout (et c'est bien plus facile, c'est pour çà que vous commencez par là).

    Mais si vous découvrez çà, c'est parce que vous avez zappé l'apprentissage des bases de la programmation et tout ce qu'il est nécessaire d'avoir compris avant que d'être à l'aise pour modifier des exemples de codes recopiés dans votre bouquin. Encore désolé mais "apprendre", c'est fabriquer des connexions entre vos neurones... un processus chimique qui prend du temps (sauf dans les films de science fiction).

    - W

  8. #8
    Membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Mai 2018
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2018
    Messages : 47
    Points : 40
    Points
    40
    Par défaut
    Effectivement, beaucoup de confusion dans ma tête.

    Je pensais avoir compris alors que c'est du bon gros bricolage.

    Je vais regarder la POO indépendamment du langage.

    J'ai quand même modifier deux trois choses histoire de ne pas rester sur un échec. j'ai écrit un code sans classe avec des variables globales (part contre j'utilise boule et can_game dans la fonction move alors qu'ils ne sont pas en argument ni en global, c'est pour le moins étrange. Encore du bricolage !) et j'ai modifié celui avec les classes pour avoir des classes étanches.

    Sans classe :

    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
    from tkinter import Tk, Canvas, Frame
    from numpy import zeros, ndenumerate
     
    # Constants
    CASE_SIZE = 20
    PAC_SIZE = 8 # rayon
    MAP_GAME = zeros((10,10))
     
    MOTIONS = {
                'Up':   (0, -1),
                'Down': (0, 1),
                'Left': (-1, 0),
                'Right':(1, 0)
               }
     
    #Fonctions
    def cercle(can_game,x, y, r, coul ='gold'):
        boule = can_game.create_oval(x-r, y-r, x+r, y+r, fill=coul) 
        return boule
     
    def on_arrow(event):
        vector_dir = MOTIONS[event.keysym] 
        move(vector_dir)
     
    def move(vector_dir):
        global col_p, row_p
        row_p += vector_dir[1]    
        col_p += vector_dir[0] 
        print(row_p,col_p)
        if col_p >= 0 and col_p < MAP_GAME.shape[1] and row_p >= 0 and row_p < MAP_GAME.shape[0]:
            can_game.coords(boule,col_p*CASE_SIZE+2,row_p*CASE_SIZE+2,(col_p+1)*CASE_SIZE-2,(row_p+1)*CASE_SIZE-2)  
        else:
            row_p -= vector_dir[1]    
            col_p -= vector_dir[0]        
     
    #Main
    root = Tk()
     
    lar = MAP_GAME.shape[0]*CASE_SIZE
    hau = MAP_GAME.shape[1]*CASE_SIZE  
    can_game = Canvas(root,width=lar, height=hau, bg="black")
    can_game.pack(padx=10,pady=10)
    can_game.focus_set() 
     
    col_p = 0
    row_p = 0
     
    boule = cercle(can_game,col_p*CASE_SIZE+CASE_SIZE/2,row_p*CASE_SIZE+CASE_SIZE/2, PAC_SIZE,"gold") 
     
    for key in MOTIONS:
        can_game.bind('<%s>' % key, on_arrow)  
     
    root.mainloop()

    Avec les classes. .bind est mnt dans le main et on a bien des classes étanches.

    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
    99
    from tkinter import Tk, Canvas, Frame
    from numpy import zeros, ndenumerate   
     
    # Constants
    CASE_SIZE = 20
    PAC_SIZE = 8 # rayon
     
    MOTIONS = {
                'Up':   (0, -1),
                'Down': (0, 1),
                'Left': (-1, 0),
                'Right':(1, 0)
               }
     
    # Class
    class Level():
        def __init__(self):
            self.map_game = zeros((10,10))
     
        def get_map(self):
            return self.map_game
     
    class Pacman:
        def __init__(self,map_game):
            self.map_game = map_game    
            self.case_row = 0
            self.case_column = 0
            self.vector_dir = (0,0)
     
        def update_pacman_pos(self,vector_dir):
            cx = vector_dir[0]
            cy = vector_dir[1]
            if self.check_terrain(cx,cy):
                self.case_row = self.case_row + cy 
                self.case_column = self.case_column + cx 
     
        def check_terrain(self,cx,cy):
            row = self.case_row + cy 
            col = self.case_column + cx
            if col >= 0 and col < self.map_game.shape[1] and row >= 0 and row < self.map_game.shape[0]:
                return True    
     
        def get_position(self):
            return (self.case_row,self.case_column)   
     
        def set_dir(self,vector_dir):
            self.update_pacman_pos(vector_dir)
     
    class GUI:
        def __init__(self,map_game,root):    
            self.root = root
            self.map_game = map_game
            self.init_game_graphics()
     
        def init_game_graphics(self):
            lar = self.map_game.shape[0]*CASE_SIZE
            hau = self.map_game.shape[1]*CASE_SIZE  
     
            self.can_game = Canvas(self.root,width=lar, height=hau, bg="black")
            self.can_game.pack(padx=10,pady=10)
            self.can_game.focus_set()              
     
        def cercle(self,x, y, r, coul ='black'):
            boule = self.can_game.create_oval(x-r, y-r, x+r, y+r, fill=coul) 
            return boule
     
        def draw_boule(self,pos,coul):
            row = pos[0]
            col = pos[1]
            boule = self.cercle(col*CASE_SIZE+CASE_SIZE/2,row*CASE_SIZE+CASE_SIZE/2, PAC_SIZE,coul) 
            return boule
     
        def move_boule(self,objet, pos): 
            row = pos[0]
            col = pos[1]
            self.can_game.coords(objet,col*CASE_SIZE+2,row*CASE_SIZE+2,(col+1)*CASE_SIZE-2,(row+1)*CASE_SIZE-2)
     
        def get_canvas(self):
            return self.can_game
     
    # Main 
     
    def on_arrow(event):
        vector_dir = MOTIONS[event.keysym]
        pacman.set_dir(vector_dir)    
        graphique.move_boule(boule,pacman.get_position())
     
    root = Tk()
    level = Level()   
    pacman = Pacman(level.get_map())
     
    graphique = GUI(level.get_map(),root)
    boule = graphique.draw_boule(pacman.get_position(),"gold")
    can_game = graphique.get_canvas()
     
    for key in MOTIONS:
        can_game.bind('<%s>' % key, on_arrow)    
     
    root.mainloop()

    Merci d'avoir pris le temps de répondre.

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 292
    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 292
    Points : 36 788
    Points
    36 788
    Par défaut
    Salut,

    Citation Envoyé par Kazvert Voir le message
    Je pensais avoir compris alors que c'est du bon gros bricolage.
    C'est bien d'avoir pris le temps de faire fonctionner quelque chose.
    Mais çà reste du bricolage!
    En écrivant votre code, vous avez du réaliser que découper son code en classe est arbitraire (pourquoi créer 1, 2, n classes, que ranger dans la classe A, B,...), que les relations entre classes vont dépendre de ce découpage.
    En bossant un peu la POO, vous allez découvrir ce qu'on appelle les patterns (ou les patrons) de conception qui vont vous aider à savoir comment découper (ici le patron de conception que vous appliquez sans le savoir (et fort mal) s'appelle MVC).

    - W

  10. #10
    Membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Mai 2018
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2018
    Messages : 47
    Points : 40
    Points
    40
    Par défaut
    D'accord. Je vais me concentrer sur la POO avant de refaire des programmes comme Pacman

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

Discussions similaires

  1. [Débutant] DataSet Binding assistant et POO et compagnie ..
    Par david.catus dans le forum C#
    Réponses: 10
    Dernier message: 30/11/2015, 21h17
  2. Bind ou pas Bind?
    Par jonzuzu dans le forum MFC
    Réponses: 4
    Dernier message: 19/03/2004, 10h00
  3. []Erreur sur second emploi collection binding
    Par jacma dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 08/03/2004, 18h02
  4. Bind - sous-domaine
    Par _Gabriel_ dans le forum Réseau
    Réponses: 4
    Dernier message: 07/03/2004, 11h54
  5. lier un cube à un objet (POO)
    Par Hypnos dans le forum OpenGL
    Réponses: 12
    Dernier message: 26/08/2003, 21h46

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