Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Pygame][Mini-projet] jeu surprise

    24 octobre 2010 à 22:09:28

    Bonjour,
    j'ai crû remarquer qu'il y avait de + en + de forumeurs qui s'intéressaient à pygame, et je me suis dit qu'on pourrait essayer, ensemble, de faire un piti jeu simple.
    Je vous proposerai donc des petits exercices qui, mis bout à bout, finiront par former un programme...Du moins je l'espère :p

    je ne vous dit pas quel jeu j'ai en tête, c'est un jeu genre puzzle que j'ai dejà codé et que je suis entrain de recoder pour organiser la chronologie des exercices.
    Mais je pense que vous allez très vite trouver de quoi il s'agit.

    je vais d'abord poser les bases.

    Le jeu se joue sur un tableau dont les cases font 30x30 pixels.
    Le tableau fait 40 par 30 cases.

    Case_size = 30 
    Tab_width, tab_height = 40,30
    


    1er partie:
    1- Créez une surface de rendu nommée 'Screen' dont les dimensions sont fonction de ses variables.
    2- créez une table de 5 couleurs différentes nommée 'Couleurs'.
    3- Créez un class 'Case' dont les instences seront initilisées à une couleur choisit aléatoirement dans 'couleurs'.
    4- Créez une matrice nommée 'Tableau' de taille Tab_height x Tab_width qui se lira ainsi: Tableau[colonne][ligne] = Case()
    5- Créez une fonction 'affiche_tableau' qui colorie chaque case du tableau suivant 'Tableau', en gardant un liseré noir pour faire zoli.

    voilà pour le moment ...

    vous devriez obtenir un truc de ce genre.

    Image utilisateur

    2eme partie:
    Soient 2 variables: 'Colonne' et 'Ligne', les coordonnées de la case pointée par la souris.
    Dans le 'mainloop', interceptez:
    - le kill de la fenêtre
    - la position du pointeur de souris afin de maintenir à jour 'Colonne' et 'Ligne' lorsqu'une nouvelle case est pointée.

    puis,
    soit une variable 'Zone', liste de toutes coordonnées des cases de même couleur en contact entre elles(de bord à bord); la case de référence étant, évidement, celle pointée par la souris.
    - Coder une fonction 'memes_cases' qui tiens à jour cette liste et qui 'hightlight' la zone obtenue lorsque 'Zone' contient au moins 2 coordonnées.

    vous devriez obtenir un truc de ce genre.
    Image utilisateur

    3eme partie:

    1- Interceptez le clic de souris et effacer la zone sélectionnée.

    Les cases au dessus remplacent les cases disparues
    Les colonnes à droite remplacent les colonnes manquantes
    Image utilisateur

    il faudra donc modifier le code pour tenir compte des cases noires à présent.

    2- Faire une fonction qui vérifie s'il y reste ou pas des possibilités de jouer
    Cette fonction servira aussi à vérifier en début de jeu si le tableu généré est jouable.

    3- Comptage des points.
    score += (nombre de case -1)²
    le score s'affiche dans la barre de titre.
    le score final dans la fenêtre.

    4- Essayer d'améliorer le rendu; ex:
    Image utilisateur

    Débrouillez-vous avec ça ^^
    postez vos codes.
    • Partager sur Facebook
    • Partager sur Twitter

    Python c'est bon, mangez-en. 

      25 octobre 2010 à 2:23:00

      Je me suis initié à Pygame spécialement pour cet exercice, ça peut être amusant. Bref, j'ai l'impression que mon code est un peu fouilli, je suis ouvert à tout commentaire :

      main.py
      import pygame
      from pygame.locals import *
      from random import choice
      from cell import *
      
      # Functions
      
      def show_table(screen, table, case_size):
          for y, row in enumerate(table):
              for x, col in enumerate(row):
                  cell = pygame.Surface((case_size - 1, case_size - 1))
                  cell.fill(col.color)
                  screen.blit(cell, (x*case_size, y*case_size))
      
      
      # Initialization & Variables
      
      pygame.init()
      case_size = 20
      tab_width, tab_height = 40, 30
      keep_going = 1
      colors = [(0xFF, 0x0, 0x0),
                (0x0, 0xFF, 0x0),
                (0x0, 0x0, 0xFF),
                (0xFF, 0xFF, 0x0),
                (0x0, 0xFF, 0xFF)]
      
      screen = pygame.display.set_mode((tab_width * case_size, tab_height * case_size))
      table = [[Cell(choice(colors)) for y in range(tab_width)] for x in range(tab_height)]
      
      show_table(screen, table, case_size)
      
      pygame.display.flip()
      
      while keep_going:
          for event in pygame.event.get():
              if event.type == QUIT:
                  keep_going = 0
      


      Cell.py (si ça vaut la peine de l'écrire...)
      class Cell:
          def __init__(self, color):
              self.color = color
      


      Ça donne un truc comme ça (je comprends pas pourquoi certaines cases sont décalées vers la gauche, par contre)
      Image utilisateur


      P.S. J'ai volontairement mis à 20 pixels la longueur des cases, ma résolution est seulement 1440x900.
      • Partager sur Facebook
      • Partager sur Twitter
        25 octobre 2010 à 9:17:17

        Salut. Ce topic a l'air appétissant.
        J'espère que les Zér0s suivront, parce que ça peut donner une activité communautaire vraiment excellente.

        Je te suggère de rajouter le tag [Exercice] ou [Mini-projet] à ton titre, et de penser à le référencer dans le post-it "Entraînez-vous". ;)

        Pour ma part, je participerai sûrement lorsque j'aurai un peu de temps.
        • Partager sur Facebook
        • Partager sur Twitter
        Zeste de Savoir, le site qui en a dans le citron !
          25 octobre 2010 à 10:16:38

          bonjour, et merci de votre encouragement et de votre participation.

          Citation : Fayden

          je comprends pas pourquoi certaines cases sont décalées vers la gauche, par contre



          en fait les cases ne sont pas décalées du point de vue pixel et je pense avoir compris le pourquoi de cet effet.
          au début je pensait que c'était un effet de contraste et puis je me suis rapelé du principe d'un ecran LCD.
          si tu as la posibilité de zoomer ton écran, tu vera qu'il n'y a pas de décalage.

          soit 3 pixels à la suite allumés ainsi:
          ROUGE.......NOIR......BLEU
          (255, 0, 0) ( 0, 0, 0)( 0, 0,255)

          et les 3 même dans un ordre différent:
          BLEU.........NOIR.....ROUGE
          ( 0, 0,255)( 0, 0, 0)(255, 0, 0)

          et bien le nombre de sous-pixels éteints entre 2 sous pixels allumés est plus grand dans le 1er cas ... Elémentaire mon cher watson.

          Citation : Fayden


          def show_table(screen, table, case_size):
              for y, row in enumerate(table):
                  for x, col in enumerate(row):
                      cell = pygame.Surface((case_size - 1, case_size - 1))
                      cell.fill(col.color)
                      screen.blit(cell, (x*case_size, y*case_size))
          

          ton code est cohérent, ne demande qu'à étre simplifié.
          Tu crées une surface que tu 'fill' avant de la 'blittée', alors que tu peux directement faire un 'fill' sur le screen.
          Ex:
          screen.fill(-1,(0,0,10,10))
          dessine un carré blanc de 10x10 px de la coin supérieur-gauche de screen.
          de plus, tu recrées X fois la même surface.
          cell = pygame.Surface((case_size - 1, case_size - 1))
          pouvait se trouver en dehors des boucles.
          la class Case, cell dans ton code, peut aussi être simplifié...
          Rapel: Pygame accepte des tuple,liste,int et str comme valeur de couleur. ;)
          • Partager sur Facebook
          • Partager sur Twitter

          Python c'est bon, mangez-en. 

            25 octobre 2010 à 14:30:33

            Je savais pas qu'on pouvait directement créer une autre surface sur la surface principale, c'est bien. La fonction show_grid ressemble désormais à ceci :
            def show_grid(screen, grid, case_size):
                for y, row in enumerate(grid):
                    for x, col in enumerate(row):
                        screen.fill(col.color, (x * case_size, y * case_size, case_size - 1, case_size - 1))
            


            Pour la classe, je dois avouer que je sais pas trop comment simplifier. Je n'ai pas fait beaucoup de Python, en fait.

            @quelqun_dautre : parce que c'est demandé dans l'exercice, tout simplement. On comprend bien que la classe va être améliorée plus tard.
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              25 octobre 2010 à 16:22:15

              On est obligé de suivre les indications de l'exercice?

              • Partager sur Facebook
              • Partager sur Twitter
                25 octobre 2010 à 18:38:53

                Citation : fred1599

                On est obligé de suivre les indications de l'exercice?


                c'est mieux, sauf si trouvez une meilleur méthode que celle que j'ai trouvé. J'ai jamais dit que j'avais le meilleur code, j'ai juste un code qui marche ...

                Et effectivement, la class Case va évoluer plus tard.

                Citation : fayden

                Pour la classe, je dois avouer que je sais pas trop comment simplifier. Je n'ai pas fait beaucoup de Python, en fait.


                On peut par exemple dériver la class list.


                Voici mon code, quasiment le même que celui de Fayden:
                from pygame import *
                from random import choice
                
                Tab_width,Tab_height = 40,30
                Case_size = 30
                
                screen = display.set_mode((Tab_width*Case_size,Tab_height*Case_size))
                
                colors = (164,120,12),(26,74,17),(255,0,0),(155,148,214),(66,128,200)
                
                class Case(list):
                	''
                	def __init__(self):
                		self.extend(choice(colors))
                
                tableau = [[Case() for __ in range(Tab_height)] for _ in range(Tab_width)]
                
                def affiche_tableau():
                	screen.fill(0)
                	for x,colonne in enumerate(tableau):
                		for y,couleur in enumerate(colonne):
                			screen.fill(couleur,(x*Case_size,y*Case_size,Case_size-1,Case_size-1))
                	display.flip()
                
                affiche_tableau()
                
                while True:
                	ev = event.wait()
                	if ev.type == QUIT: break
                

                j'aurai voulu dériver la class pygame.Color mais je n'y suis pas arrivé.
                • Partager sur Facebook
                • Partager sur Twitter

                Python c'est bon, mangez-en. 

                  26 octobre 2010 à 18:42:22

                  2eme partie:
                  Soient 2 variables: 'Colonne' et 'Ligne', les coordonnées de la case pointée par la souris.
                  Dans le 'mainloop', interceptez:
                  - le kill de la fenêtre
                  - la position du pointeur de souris afin de maintenir à jour 'Colonne' et 'Ligne' lorsqu'une nouvelle case est pointée.

                  puis,
                  soit une variable 'Zone', liste de toutes coordonnées des cases de même couleur en contact entre elles(de bord à bord); la case de référence étant, évidement, celle pointée par la souris.
                  - Coder une fonction 'memes_cases' qui tiens à jour cette liste et qui 'hightlight' la zone obtenue lorsque 'Zone' contient au moins 2 coordonnées.

                  vous devriez obtenir un truc de ce genre.
                  Image utilisateur
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Python c'est bon, mangez-en. 

                    26 octobre 2010 à 19:21:09

                    Idée très intéressante, mais comme d'habitude je suis incapable de pondre un code qui marche... Je suis prêt à parier que je n'ai toujours pas compris l'utilisation d' enumerate(). Si quelqu'un pouvait m'aider... :-°

                    game.py

                    import pygame
                    from pygame.locals import *
                    from case import Case
                    
                    def show_grid(screen, grid, case_size):
                        x,y = 0,0
                        for col in enumerate(grid):
                            for cell in enumerate(col):
                                case = pygame.Surface((case_size-1, case_size-1))
                                case.fill(cell.color)
                                screen.blit(case, (x, y))
                                x += case_size
                            y += case_size
                        pygame.display.flip()
                    
                    # Initialisation de la grille :
                    case_size = 30
                    grid_width, grid_height = 40,30
                    grid = []
                    for col in range(grid_width):
                        grid.append([])
                        for cell in range(grid_height):
                            grid[col].append(Case())
                    
                    # Initialisation de pygame et de la fenetre :
                    pygame.init()
                    screen = pygame.display.set_mode((grid_width*case_size, grid_height*case_size))
                    show_grid(screen, grid, case_size)
                    # Boucle du jeu :
                    while True:
                        for event in pygame.event.get():
                            if event.type == QUIT: break
                    
                    pygame.quit()
                    

                    case.py


                    from random import choice
                    
                    colors = [
                        (255, 215, 0, 255), # gold
                        (171, 171, 171, 255), # grey
                        (135, 206, 235, 255), # blue
                        (34, 139, 34, 255), # green
                        (139, 58, 58, 255) # red
                    ]
                    
                    class Case:
                        def __init__(self):
                            self.color = choice(colors)
                    

                    Mon ami le traceback


                    Traceback (most recent call last):
                      File "/Users/***/Documents/Python/Scripts_2.x/PyGame/TP_ForumSDZ/game.py", line 28, in <module>
                        show_grid(screen, grid, case_size)
                      File "/Users/***/Documents/Python/Scripts_2.x/PyGame/TP_ForumSDZ/game.py", line 10, in show_grid
                        case.fill(cell.color)
                    AttributeError: 'tuple' object has no attribute 'color'
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Anonyme
                      26 octobre 2010 à 19:30:29

                      list = ["zéro", "un", "deux", "trois", "etc."]
                      for index, value in enumerate(list):
                          print("l'élément numéro", index, "vaut :", value)
                      

                      • Partager sur Facebook
                      • Partager sur Twitter
                        26 octobre 2010 à 19:43:36

                        Ah oui, l'index, c'est vrai... >_<
                        Bon, outre le fait que je me sens bête, je peux continuer. Merci !
                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 octobre 2010 à 6:08:41

                          Voilà mon code pour a seconde partie.
                          La class Case a changée pour pouvoir marquée les cases identiques.
                          class Case(list):
                              ''
                              def __init__(self):
                                  self.extend(choice(colors))
                                  self.m = False #sert de marqueur
                          
                          def memes_cases(colonne,ligne):
                              output = [(colonne,ligne)] #la case de reference
                              couleur = tableau[colonne][ligne] #la couleur de reference
                              tableau[colonne][ligne].m = True #on marque la case
                              for colonne,ligne in output:
                                  for x,y in (0,1),(0,-1),(1,0),(-1,0): #on scan les 4 cases autour
                                      x,y = colonne+x,ligne+y
                                      # si elles ont la meme couleur
                                      if 0<=x<Tab_width and 0<=y<Tab_height and tableau[x][y]==couleur and not tableau[x][y].m:
                                          tableau[x][y].m = True # on les marques pour pas les rescanner
                                          output.append((x,y)) #et on les ajoute
                              for colonne,ligne in output: tableau[colonne][ligne].m = False #on retire la marque
                              output = sorted(output)
                              if Zone != output: #si la zone a change
                                  for colonne,ligne in Zone: #on unhightlight l'ancienne
                                      screen.fill(tableau[colonne][ligne],(colonne*Case_size,ligne*Case_size,Case_size-1,Case_size-1))
                                  if len(output)>1: #et on hightlight la nouvelle si + de 1 case
                                      for colonne,ligne in output: draw.rect(screen,(255,255,255),(colonne*Case_size,ligne*Case_size,Case_size-2,Case_size-2),2)
                                  display.flip()
                              return output
                          
                          affiche_tableau()
                          Colonne,Ligne = 0,0
                          Zone = []
                          
                          while True:
                              ev = event.wait()
                              if ev.type == QUIT: break
                              elif ev.type == MOUSEMOTION:
                                  C,L = ev.pos[0]/Case_size,ev.pos[1]/Case_size
                                  if (Colonne,Ligne) != (C,L):
                                      Colonne,Ligne = C,L
                                      Zone = memes_cases(Colonne,Ligne)
                          
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Python c'est bon, mangez-en. 

                            27 octobre 2010 à 9:19:41

                            Hahaha, j'commence à voir de quel jeu il s'agit.

                            Pas encore eu le temps de participer, malheureusement. :(
                            • Partager sur Facebook
                            • Partager sur Twitter
                            Zeste de Savoir, le site qui en a dans le citron !
                              27 octobre 2010 à 10:40:01

                              Citation : NoHaR

                              Hahaha, j'commence à voir de quel jeu il s'agit.
                              Pas encore eu le temps de participer, malheureusement. :(



                              héhé, s'il y a de la participation, dans le même genre, on fera un 'démineur' ... ^^
                              • Partager sur Facebook
                              • Partager sur Twitter

                              Python c'est bon, mangez-en. 

                                27 octobre 2010 à 14:04:42

                                Bah... on l'a déjà fait le démineur. :euh:

                                Pourquoi pas un Tetris ? :p
                                • Partager sur Facebook
                                • Partager sur Twitter
                                Zeste de Savoir, le site qui en a dans le citron !
                                  27 octobre 2010 à 15:17:30

                                  Citation : NoHaR

                                  Pourquoi pas un Tetris ? :p



                                  Un Tetris me semble une bonne idée, ça tombe bien mon Bomber-man est presque finit :p
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    27 octobre 2010 à 16:14:12

                                    Citation : NoHaR

                                    Hahaha, j'commence à voir de quel jeu il s'agit.


                                    La première image était déjà suffisante :-p

                                    Je vais probablement essayer quelque chose pour la deuxième partie, j'ai pas vraiment eu/pris le temps jusqu'à maintenant.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      27 octobre 2010 à 21:27:30

                                      Citation : NoHaR

                                      Bah... on l'a déjà fait le démineur. :euh:

                                      Pourquoi pas un Tetris ? :p



                                      Mon but est d'amener le lecteur à suivre une logique dans le développement. Je vois souvent des codes fonctionnels mais trop long, fractionnés en multiples fonctions et class, parce que le gars essaye de coder ce qu'il voit, au lieu de représenter ce qu'il code.
                                      Je pensais qu'un 'démineur' serait un bon 2eme épisode qui peut se coder en une centaines de lignes.

                                      Un 'tetris' est prévu, ainsi qu'un 'sokoban', un simple 'snake', comment faire un menu, etc ...
                                      et quelques bases comme: comment aligner des images, gerer des collisions, etc ...
                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      Python c'est bon, mangez-en. 

                                        28 octobre 2010 à 9:57:10

                                        Citation : josmiley

                                        Un 'tetris' est prévu, ainsi qu'un 'sokoban', un simple 'snake', comment faire un menu, etc ...
                                        et quelques bases comme: comment aligner des images, gerer des collisions, etc ...


                                        Très bonne initiative, je vais suivre tout ça avec intérêt :)

                                        Voici mon code de la première partie:

                                        main.py
                                        #!/usr/bin/env python
                                        
                                        import pygame
                                        from pygame.locals import *
                                        from Grid import *
                                        from define import *
                                        
                                        
                                        
                                        pygame.init()
                                        screen = pygame.display.set_mode(( WIDTH * TILE_W, HEIGHT * TILE_H ))
                                        
                                        grid = Grid()
                                        grid.populate(WIDTH, HEIGHT)
                                        
                                        onLoop = True
                                        while onLoop:
                                        	pygame.time.Clock().tick(30)
                                        	
                                        	for event in pygame.event.get():
                                        		if event.type == QUIT:
                                        			onLoop = False
                                        		if event.type == KEYDOWN:
                                        			if event.key == K_ESCAPE:
                                        				onLoop = False
                                        
                                        	grid.display(screen)
                                        	pygame.display.flip()
                                        

                                        Grid.py
                                        #!/usr/bin/env python
                                        
                                        from random import choice
                                        import pygame
                                        from pygame.locals import *
                                        from Tile import *
                                        from define import *
                                        
                                        
                                        class Grid:
                                        	def __init__(self):
                                        		self.grid = []
                                        		self.tile_w = TILE_W
                                        		self.tile_h = TILE_H
                                        
                                        	def populate(self, width=TILE_W, height=TILE_H):
                                        		self.grid = [[Tile(choice(COLORS)) for x in range(width)] for y in range(height)]
                                        
                                        	def display(self, win):
                                        		for y, row in enumerate(self.grid):
                                        			for x, cell in enumerate(row):
                                        				surf_tile = pygame.Surface((self.tile_w - 1, self.tile_h - 1))
                                        				surf_tile.fill(cell.color)
                                        				win.blit(surf_tile, (x * self.tile_w, y * self.tile_h))
                                        

                                        Tile.py
                                        #!/usr/bin/env python
                                        
                                        class Tile:
                                        	def __init__(self, color):
                                        		self.color = color
                                        

                                        define.py
                                        #!/usr/bin/env python
                                        
                                        TILE_W = 30
                                        TILE_H = 30
                                        WIDTH, HEIGHT = 40, 30
                                        
                                        COLORS = [(127, 255, 212), \
                                        		(26, 74, 17), \
                                        		(155, 148, 214), \
                                        		(164, 120, 12), \
                                        		(255, 0, 0), \
                                        		]
                                        


                                        Bon j'ai pas fait de python depuis des lustres...
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          28 octobre 2010 à 10:01:22

                                          3eme partie:

                                          1- Interceptez le clic de souris et effacer la zone sélectionnée.

                                          Les cases au dessus remplacent les cases disparues
                                          Les colonnes à droite remplacent les colonnes manquantes
                                          Image utilisateur

                                          il faudra donc modifier le code pour tenir compte des cases noires à présent.

                                          2- Faire une fonction qui vérifie s'il y reste ou pas des possibilités de jouer
                                          Cette fonction servira aussi à vérifier en début de jeu si le tableu généré est jouable.

                                          3- Comptage des points.
                                          score += (nombre de case -1)²
                                          le score s'affiche dans la barre de titre.
                                          le score final dans la fenêtre.

                                          4- Essayer d'améliorer le rendu; ex:
                                          Image utilisateur

                                          Débrouillez-vous avec ça ^^
                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Python c'est bon, mangez-en. 

                                            28 octobre 2010 à 12:43:34

                                            Voici mon code pour la 2eme partie. Comme dit plus haut, je fais pas souvent de python, ça doit être améliorable. Mais ça marche

                                            main.py
                                            #!/usr/bin/env python
                                            
                                            import pygame
                                            from pygame.locals import *
                                            from Grid import *
                                            from define import *
                                            
                                            pygame.init()
                                            screen = pygame.display.set_mode(( WIN_W, WIN_H ))
                                            
                                            grid = Grid()
                                            grid.populate(WIDTH, HEIGHT)
                                            
                                            onLoop = True
                                            while onLoop:
                                            	#pygame.time.Clock().tick(30)
                                            	
                                            	for event in pygame.event.get():
                                            		if event.type == QUIT:
                                            			onLoop = False
                                            		if event.type == KEYDOWN:
                                            			if event.key == K_ESCAPE:
                                            				onLoop = False
                                            		if event.type == MOUSEMOTION:
                                            			grid.onMouseHover(pygame.mouse.get_pos())
                                            
                                            	grid.display(screen)
                                            	pygame.display.flip()
                                            



                                            Grid.py
                                            #!/usr/bin/env python
                                            
                                            from random import choice
                                            import pygame
                                            from pygame.locals import *
                                            from Tile import *
                                            from define import *
                                            
                                            
                                            class Grid:
                                            	def __init__(self):
                                            		self.grid = []
                                            		self.tile_w = TILE_W
                                            		self.tile_h = TILE_H
                                            		self.mouse_tile = (0, 0)
                                            		self.hl_tiles = []
                                            		self._visited = []
                                            
                                            	def populate(self, width=TILE_W, height=TILE_H):
                                            		self.grid = [[Tile(choice(COLORS)) for x in range(width)] for y in range(height)]
                                            
                                            	def display(self, win):
                                            		for y, row in enumerate(self.grid):
                                            			for x, cell in enumerate(row):
                                            				surf_tile = pygame.Surface((self.tile_w - 1, self.tile_h - 1))
                                            				surf_tile.fill(cell.color)
                                            				if (x,y) in self.hl_tiles:
                                            					list = [ (0, 0), (0, self.tile_h-3), (self.tile_w-3, self.tile_h-3), (self.tile_w-3, 0) ] 
                                            					pygame.draw.lines(surf_tile, WHITE, True, list, 2)
                                            				win.blit(surf_tile, (x * self.tile_w, y * self.tile_h))
                                            
                                            	
                                            	def onMouseHover(self, coord):
                                            		mouse_tile = (coord[0] / self.tile_w, coord[1] / self.tile_h)
                                            		if mouse_tile != self.mouse_tile:
                                            			self.mouse_tile = mouse_tile
                                            			self.hl_tiles = self.__highlight(mouse_tile) + [self.mouse_tile]
                                            			self._visited = []
                                            
                                            	def __highlight(self, start):
                                            		self._visited.append(start)
                                            		pos = start
                                            		hl_tiles = []
                                            		close_tiles = self.__getCloseTiles(start)
                                            		for x, y in close_tiles:
                                            			if self.__getTileColor( start ) == self.__getTileColor( (x, y) ) and (x, y) not in self._visited:
                                            				hl_tiles.append( (x, y) )
                                            				hl_tiles += self.__highlight( (x, y) )
                                            
                                            		return hl_tiles
                                            
                                            	def __getCloseTiles(self, pos):
                                            		x, y = pos
                                            		close_tiles = []
                                            		if x - 1 >= 0:
                                            			close_tiles.append( (x - 1, y) )
                                            		if x + 1 < WIDTH:
                                            			close_tiles.append( (x + 1, y) )
                                            		if y - 1 >= 0:
                                            			close_tiles.append( (x, y - 1) )
                                            		if y + 1 < HEIGHT:
                                            			close_tiles.append( (x, y + 1) )
                                            		return close_tiles
                                            
                                            	def __getTileColor(self, id):
                                            		x, y = id
                                            		return self.grid[y][x].color
                                            



                                            Tile.py
                                            #!/usr/bin/env python
                                            
                                            class Tile:
                                            	def __init__(self, color):
                                            		self.color = color
                                            


                                            define.py
                                            #!/usr/bin/env python
                                            
                                            TILE_W = 30
                                            TILE_H = 30
                                            WIDTH, HEIGHT = 40, 30
                                            WIN_W = WIDTH * TILE_W
                                            WIN_H = HEIGHT * TILE_H
                                            
                                            COLORS = [(127, 255, 212), \
                                            		(26, 74, 17), \
                                            		(155, 148, 214), \
                                            		(164, 120, 12), \
                                            		(255, 0, 0), \
                                            		]
                                            
                                            WHITE = (255, 255, 255)
                                            BLACK = (0, 0, 0)
                                            


                                            Petit screen :

                                            Image utilisateur
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              28 octobre 2010 à 22:57:05

                                              Voilà mon code final.

                                              from pygame import *
                                              from random import choice
                                              
                                              # ---------CONSTANTES
                                              font.init()
                                              font=font.Font(font.get_default_font(),50)
                                              
                                              Tab_width,Tab_height = 20,1
                                              Case_size = 30
                                              
                                              screen = display.set_mode((Tab_width*Case_size,Tab_height*Case_size))
                                              
                                              colors = (164,120,12),(26,74,17),(255,0,0),(155,148,214),(66,128,200)
                                              #img = image.load('mask.png')
                                              
                                              # ---------CLASS
                                              class Case(list):
                                                  ''
                                                  def __init__(self):
                                                      self.extend(choice(colors))
                                                      self.m = False
                                              
                                              # ---------FONCTIONS
                                              def affiche_tableau():
                                                  screen.fill(0)
                                                  for x,colonne in enumerate(Tableau):
                                                      for y,couleur in enumerate(colonne):
                                                          if couleur:
                                                              screen.fill(couleur,(x*Case_size,y*Case_size,Case_size-1,Case_size-1))
                                                              #screen.blit(img,(x*Case_size,y*Case_size))
                                                  display.flip()
                                              
                                              def memes_cases(colonne,ligne):
                                                  output = []
                                                  if Tableau[colonne][ligne]:
                                                      couleur = Tableau[colonne][ligne]
                                                      Tableau[colonne][ligne].m = True
                                                      output.append((colonne,ligne))
                                                      # cette partie remplie la liste output en meme temps qu'elle la parcours
                                                      # avec les coordonnees des cases de meme couleur en contact
                                                      # les unes avec les autres
                                                      for colonne,ligne in output:
                                                          for x,y in (0,1),(0,-1),(1,0),(-1,0):
                                                              x,y = colonne+x,ligne+y
                                                              if 0<=x<Tab_width and 0<=y<Tab_height and Tableau[x][y]==couleur and not Tableau[x][y].m:
                                                                  Tableau[x][y].m = True
                                                                  output.append((x,y))
                                                      # sorted permet de comparer avec l'ancienne zone
                                                      # [1,2,3] == sorted([2,3,1])
                                                      # mais aussi, dans le mainloop, de supprimer proprement
                                                      # des elements de Colonne
                                                      output = sorted(output)
                                                      for colonne,ligne in output: Tableau[colonne][ligne].m = False
                                                  # Si l'ancienne et la nouvelle zone sont differentes
                                                  if Zone != output:
                                                      for colonne,ligne in Zone:
                                                          # on unhightlight l'ancienne
                                                          screen.fill(Tableau[colonne][ligne],(colonne*Case_size,ligne*Case_size,Case_size-1,Case_size-1))
                                                          #screen.blit(img,(colonne*Case_size,ligne*Case_size))
                                                      if len(output)>1:
                                                          # et on hightlight la nouvelle si besoin
                                                          for colonne,ligne in output: draw.rect(screen,(255,255,255),(colonne*Case_size,ligne*Case_size,Case_size-2,Case_size-2),2)
                                                      display.flip()
                                                  return output
                                              
                                              def jouable():
                                                  # Tableau est scanne verticalement et si necessaire horizontalement
                                                  # a la recherche de 2 cases identiques succesives
                                                  # la fonction retourne Vrai si elle en trouve
                                                  def test(tableau):
                                                      for colonne in tableau:
                                                          for e,ligne in enumerate(colonne[1:]):
                                                              if ligne and ligne == colonne[e]: return True
                                                      return False
                                                  return test(Tableau) or test(zip(*Tableau))
                                              
                                              new_tab = lambda: [[Case() for __ in range(Tab_height)] for _ in range(Tab_width)]
                                              
                                              # ---------VARIABLES ET INIT
                                              Tableau = new_tab()
                                              while not jouable(): Tableau = new_tab()
                                              affiche_tableau()
                                              Colonne,Ligne = 0,0
                                              Zone = []
                                              Score = 0
                                              cases_restantes = Tab_width*Tab_height
                                              display.set_caption('Score : 0')
                                              
                                              # ---------MAINLOOP
                                              while True:
                                                  ev = event.wait()
                                                  if ev.type == QUIT: break
                                                  elif ev.type == MOUSEMOTION:
                                                      C,L = ev.pos[0]/Case_size,ev.pos[1]/Case_size
                                                      # on ne fait quelque chose que si
                                                      # les coordonnees (en cases) changent
                                                      if (Colonne,Ligne) != (C,L):
                                                          Colonne,Ligne = C,L
                                                          Zone = memes_cases(Colonne,Ligne)
                                                  elif ev.type == MOUSEBUTTONUP and ev.button == 1 and len(Zone)>1:
                                                      for colonne,ligne in Zone:
                                                          # on supprimer les cases dans l'ordre
                                                          del(Tableau[colonne][ligne])
                                                          # en maintenant les index
                                                          Tableau[colonne].insert(0,0)
                                                      # pareil pour les colonnes
                                                      for colonne in range(Tab_width-1,-1,-1):
                                                          if not any(Tableau[colonne]):
                                                              del Tableau[colonne]
                                                              Tableau.append([0]*Tab_height)
                                                      Score += (len(Zone)-1)**2
                                                      cases_restantes -= len(Zone)
                                                      display.set_caption('Score : '+str(Score))
                                                      affiche_tableau()
                                                      # La zone etant supprimee
                                                      # on repart avec une vierge
                                                      Zone = []
                                                      Zone = memes_cases(Colonne,Ligne)
                                                      if not jouable(): break
                                              mess = font.render('Score final : '+str(Score-cases_restantes*2),1,(255,255,255))
                                              Rmess = mess.get_rect()
                                              Rmess.center = screen.get_rect().center
                                              screen.blit(mess,Rmess)
                                              display.flip()
                                              while event.wait().type != QUIT: pass
                                              


                                              Pourquoi n'y a t-il pas d'init() ?
                                              Ce n'est pas une obligation.
                                              La plupart des modules peuvent s'initaliser séparément, comme 'font': font.init()
                                              d'autres n'ont pas besoin d'être initialisé pour fonctionner comme 'display' qui possède pourtant un init()
                                              'time' ne possède pas d'init() et pourtant renverra toujours 0 si vous n'initialisez pas l'ensemble des modules.

                                              Pourquoi event.wait() et pas event.get() ?
                                              Avec un jeu de ce genre, sans animation, sans sprite, avec un fps proche du zero, inutile d'aller vite
                                              et ça économise du processuer.
                                              De même, le rendu n'a pas été optimisé.
                                              J'ai juste économisé sur la phase de calcule: action que si la souris change de case.

                                              Lorsque le fenêtre s'ouvre sous la souris, une zone s'hightlight alors que la pointeur n'a pas bougé ...
                                              Lorsque pygame crée une fenêtre, il poste un évenement qui localise la souris,
                                              un MOUSEMOTION si le pointeur se trouve sur le display, sinon un ACTIVEEVENT.

                                              Siouplè, postez des codes monoblocs, ou postez un lien vers un compressé,
                                              parce que créer un dossier + 4 fichiers et les nommer c'est désespérant. :p
                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              Python c'est bon, mangez-en. 

                                                29 octobre 2010 à 11:49:30

                                                Salut,

                                                Belle initiative que ce topic. Si d'autres suivent, ce sera super. :)

                                                Pour l'occasion, je me suis remis à Python, j'ai découvert pygame ce matin(ainsi que la prog objet avec python :-° ).

                                                Ce qui donne
                                                import pygame
                                                import random
                                                
                                                GAME_WIDTH, GAME_HEIGHT =  20, 15
                                                CELL_SIZE = 30
                                                WHITE = (255, 255, 255)
                                                BLACK = (0, 0, 0)
                                                
                                                class Cell:
                                                    def __init__(self):
                                                        colors =  (0, 255, 0), (255, 0, 0), (0, 0, 255), (169, 108, 36), (216, 157, 227), (178, 178, 32)
                                                        self.color = random.choice(colors)
                                                        self.visited = False
                                                        
                                                        
                                                    def display(self, x, y):
                                                        x, y = CELL_SIZE * x, CELL_SIZE * y
                                                        screen = pygame.display.get_surface()
                                                        screen.fill(WHITE if self.visited == True else BLACK, (x, y, CELL_SIZE, CELL_SIZE))
                                                        screen.fill(self.color, (x + 1, y + 1, CELL_SIZE - 2, CELL_SIZE - 2))
                                                
                                                
                                                class Grid:
                                                    def __init__(self, w, h):
                                                        self.w, self.h = w, h
                                                        self.grid = []
                                                        self.grid = [[Cell() for x in range(w)] for y in range(h)]
                                                        self.zone = []
                                                        
                                                        
                                                    def display(self):
                                                        for y, row in enumerate(self.grid):
                                                            for x, cell in enumerate(row):
                                                                cell.display(x, y)
                                                    
                                                    
                                                    def reset(self):
                                                        for y, row in enumerate(self.grid):
                                                            for x, cell in enumerate(row):
                                                                cell.visited = False
                                                                
                                                                
                                                    def update(self, xmouse, ymouse):
                                                        self.reset()
                                                        for y, row in enumerate(self.grid):
                                                            for x, cell in enumerate(row):
                                                               if xmouse == x and ymouse == y and cell.color != BLACK:
                                                                    self.zone = self.propage(x, y, cell.color)
                                                                
                                                                
                                                    def propage(self, x, y, color):
                                                        dir = (1, 0), (-1, 0), (0, 1), (0, -1)
                                                        if x < 0 or x >= self.w or y < 0 or y >= self.h:
                                                            return []
                                                        if self.grid[y][x].visited == True:
                                                            return []
                                                        if self.grid[y][x].color != color:
                                                            return []
                                                        
                                                        selection = [(y, x)]
                                                        self.grid[y][x].visited = True
                                                        for nxt_dir in dir:
                                                            selection += self.propage(x + nxt_dir[0], y + nxt_dir[1], color)
                                                        return selection
                                                
                                                
                                                    def clear(self):
                                                        if len(self.zone) < 2:
                                                            return
                                                        for coord in self.zone:
                                                            x = coord[1]
                                                            color = self.grid[coord[0]][x].color
                                                            while self.grid[coord[0]][x].color == color and color != BLACK:
                                                                for y in range(coord[0], 0, -1):
                                                                    self.grid[y][x].color =  self.grid[y - 1][x].color
                                                                    self.grid[y - 1][x].color = BLACK
                                                                
                                                class Game:
                                                    def __init__(self, w, h):
                                                        pygame.init()
                                                        pygame.display.set_mode((CELL_SIZE * w, CELL_SIZE * h))
                                                        self.grid = Grid(w, h)
                                                        
                                                    def run(self):
                                                        done = False
                                                        while done == False:
                                                            x, y = pygame.mouse.get_pos()
                                                            x, y = x / CELL_SIZE, y / CELL_SIZE
                                                            for event in pygame.event.get():
                                                                if event.type == pygame.QUIT:
                                                                    done = True
                                                                if event.type == pygame.MOUSEBUTTONDOWN:
                                                                    if event.button == 1:
                                                                        self.grid.clear()
                                                                        
                                                            self.update(x, y)
                                                            self.display()
                                                            
                                                            
                                                    def update(self, x, y):
                                                        self.grid.update(x, y)
                                                        
                                                        
                                                    def display(self):
                                                        self.grid.display()
                                                        pygame.display.flip()
                                                
                                                
                                                game = Game(GAME_WIDTH, GAME_HEIGHT)
                                                game.run()
                                                


                                                Il reste encore des choses à implémenter(je ne teste pas si une grille est possible.)

                                                Je prend volontier tous les commentaires en particulier sur l'allure du code Python. :-°
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                Zeste de Savoir, le site qui en a dans le citron !
                                                Anonyme
                                                  29 octobre 2010 à 12:22:33

                                                  Citation

                                                  Je prend volontier tous les commentaires en particulier sur l'allure du code Python



                                                  Ton code est très bien.

                                                  Seulement lorsque tu cliques sur la 1ère ligne ça beug, dans le jeu c'est peut-être normal, seulement le joueur ne peut plus rejouer, ça c'est plutôt gếnant ;)
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    29 octobre 2010 à 13:26:48

                                                    Citation : Fred1599


                                                    Seulement lorsque tu cliques sur la 1ère ligne ça beug, dans le jeu c'est peut-être normal, seulement le joueur ne peut plus rejouer, ça c'est plutôt gếnant ;)


                                                    Effectivement, c'est plutôt gênant!
                                                    Je pense savoir ou est le problème.(Je teste en dehors du tableau :honte: )

                                                    Je pense faire mieux sur les prochains topics de josmiley. ;)
                                                    La lib pygame est très intuitive(bon, je connais un peu la SDL, j'avoue).

                                                    Mais je trouve que le duo Python + pygame est vraiment sympa, et dans mon cas, ça peut être une motivation pour me mettre sérieusement à Python.
                                                    Je participerais aux possibles autres topics, ça ne me fera pas de mal!

                                                    :lol:
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    Zeste de Savoir, le site qui en a dans le citron !
                                                    Anonyme
                                                      29 octobre 2010 à 13:50:01

                                                      Citation

                                                      Mais je trouve que le duo Python + pygame est vraiment sympa



                                                      Je trouve aussi que pygame est très intuitif, seulement étant pas un fan de jeux, ce n'est pas pour en créer, et malheureusement ça me freine dans l'utilisation de la lib car j'en ai pas un grand intérêt.

                                                      Citation

                                                      Mais je trouve que le duo Python + pygame est vraiment sympa, et dans mon cas, ça peut être une motivation pour me mettre sérieusement à Python



                                                      Je ne pense pas que ça sera la seule raison :)

                                                      Citation

                                                      Je participerais aux possibles autres topics, ça ne me fera pas de mal



                                                      J'ai hâte de voir tes codes, je les trouve concis et bien traité.

                                                      D'ailleurs on voit une grosse base en informatique comme Nohar, Josmiley ou même Zopieux (dommage on le voit plus :( ) et pour un autodidacte comme moi, on est toujours agréablement surpris par vos codes.
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        30 octobre 2010 à 10:55:25

                                                        Citation : fred1599

                                                        J'ai hâte de voir tes codes, je les trouve concis et bien traité.


                                                        +1
                                                        c'est vachement propre.

                                                        Sinon, tout le monde a pigé le principe de 'propagation','contamination','remplissage' ? ... Appelez ça comme vous voulez.
                                                        ça va servir pour le démineur.
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter

                                                        Python c'est bon, mangez-en. 

                                                          30 octobre 2010 à 14:57:34

                                                          Ça s'appelle un "parcours en profondeur". :p
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          Zeste de Savoir, le site qui en a dans le citron !
                                                            30 octobre 2010 à 23:39:37

                                                            Citation : NoHaR

                                                            Ça s'appelle un "parcours en profondeur". :p


                                                            ça sonne bien ^^
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            Python c'est bon, mangez-en. 

                                                            [Pygame][Mini-projet] jeu surprise

                                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                            • Editeur
                                                            • Markdown