Memory Puzzle by Pygame 含源码

用pygame实现的一个类似于翻翻看的游戏,你需要安装python2.7(http://www.python.org/download/)和pygame(http://www.pygame.org/)才能运行它。代码受《Making Games with Python and Pygame》启发很大(http://inventwithpython.com/pygame/index.html)。

程序第一个版本是基于过程的,第二个版本基本上按照面向对象设计,但感觉boxs的设计不是很好,需要后续优化,另外一些Animiation做的不是很流畅,有锯齿的感觉,希望可以有人不吝赐教。

贴上主要源码,并附上下载链接:http://files.cnblogs.com/sayhellototheworld/MemoryPuzzle.rar

  1 #coding=utf-8
  2 from pygame.locals import *
  3 from pygame import Surface
  4 import pygame
  5 import sys
  6 import random
  7 from memorypuzzle_constants import *
  8 '''
  9 Things learned: 
 10 1. a surface rect's top and left value are the relative numbers to the surface on which it is blitted 
 11 '''
 12 class Game():
 13     BASICFONT = None
 14     FPSCLOCK = None
 15     boxs = None
 16     lives = None
 17     @staticmethod
 18     def font_init():
 19         Game.BASICFONT = pygame.font.Font(FONTPATH, BASICFONTSIZE)
 20     @staticmethod
 21     def clock_init():
 22         Game.FPSCLOCK = pygame.time.Clock()
 23     @staticmethod
 24     def boxs_init():
 25         Game.boxs = [] 
 26         for i in range(NUMBOXHORIZONTAL):
 27             vert_boxs = []
 28             x = BOXMARGINWIDTH
 29             x += i * (BOXWIDTH + GAPBETBOXS)
 30             for j in range(NUMBOXVERTIVAL):
 31                 y = BOXMARGINHEIGHT
 32                 y += j * (BOXHEIGHT + GAPBETBOXS)
 33                 box = Box(x,y,BOXWIDTH,BOXHEIGHT)
 34                 box.boxx = i
 35                 box.boxy = j                      
 36                 vert_boxs.append(box)
 37             Game.boxs.append(vert_boxs)
 38         
 39         
 40     @staticmethod
 41     def game_init():
 42         pygame.init()
 43         Game.font_init()
 44         Game.clock_init()
 45         Game.boxs_init()
 46         Game.lives = LIVES
 47         
 48     @staticmethod    
 49     def shuffle_boxs_color():
 50         global ALLCOLORS
 51         num_colors_need = NUMBOXHORIZONTAL * NUMBOXVERTIVAL / 2
 52         assert num_colors_need == NUMBOXHORIZONTAL * NUMBOXVERTIVAL / 2.0
 53         colors = ALLCOLORS[:]
 54         random.shuffle(colors)
 55         colors = colors[:num_colors_need]
 56         colors = colors * 2
 57         random.shuffle(colors)
 58         for i in range(NUMBOXHORIZONTAL):
 59             for j in range(NUMBOXVERTIVAL):
 60                 Game.boxs[i][j].color = colors[0]
 61                 Game.boxs[i][j].surf.fill(colors[0])
 62                 del colors[0]
 63     @staticmethod
 64     def draw_boxs(DISPLAYSURF):
 65         for i in range(NUMBOXHORIZONTAL):
 66             for j in range(NUMBOXVERTIVAL):
 67                 if Game.boxs[i][j].is_revealed == True:
 68                     DISPLAYSURF.blit(Game.boxs[i][j].surf,(XRBW(Game.boxs[i][j].x),YRBW(Game.boxs[i][j].y)))
 69     @staticmethod
 70     def draw_covers(DISPLAYSURF,coverage):
 71         for i in range(NUMBOXHORIZONTAL):
 72             for j in range(NUMBOXVERTIVAL):
 73                 if Game.boxs[i][j].is_revealed == False:
 74                     Game.boxs[i][j].set_surf_color(COVERCOLOR)
 75                     DISPLAYSURF.blit(Game.boxs[i][j].surf,(XRBW(Game.boxs[i][j].x),YRBW(Game.boxs[i][j].y)))  
 76     @staticmethod
 77     def anim_reveal(surface,boxx,boxy):
 78         i = boxx
 79         j = boxy
 80         Game.boxs[i][j].set_surf_color(Game.boxs[i][j].color)
 81         for coverage in range(BOXWIDTH, -1, -REVEALSPEED):
 82             if coverage >=0: 
 83                 draw_a_cover(surface,Game.boxs, boxx, boxy, coverage)
 84     @staticmethod
 85     def anim_cover(surface,first_select,boxx,boxy):
 86         for coverage in range(0, BOXWIDTH+1, REVEALSPEED):
 87             if coverage >=0: 
 88                 draw_a_cover(surface,Game.boxs, first_select.boxx, first_select.boxy, coverage)
 89                 draw_a_cover(surface,Game.boxs, boxx, boxy, coverage)
 90     @staticmethod
 91     def reset():
 92         Game.lives = LIVES
 93         for i in range(NUMBOXHORIZONTAL):
 94             for j in range(NUMBOXVERTIVAL):   
 95                 Game.boxs[i][j].is_revealed = False
 96     @staticmethod
 97     def wait(msec):
 98         pygame.time.wait(msec)
 99                                   
100 class GameSurface(pygame.Surface):
101     def __init__(self,width,height,left,top,color):
102         super(GameSurface,self).__init__((width,height))
103         self.left = left
104         self.top = top        
105         self.color = color
106     def set_lefttop(self,left,top):
107         self.left = left
108         self.top = top
109     def get_lefttop(self):
110         return self.left, self.top
111     def draw_on(self,surface):
112         self.fill(self.color)
113         surface.blit(self,self.get_lefttop())
114     def update(self):
115         Screen.update()
116 
117 class Text():
118     def __init__(self,text, color, bgcolor, left, top,BASICFONT):
119         self.text = text; self.color = color; self.bgcolor = bgcolor; self.top = top; self.left = left; self.BASICFONT = BASICFONT
120         self.text_surf = self.BASICFONT.render(self.text,True,self.color,self.bgcolor)
121         self.text_rect = self.text_surf.get_rect()
122     def make_text(self):
123         self.text_rect.topleft = (self.left,self.top)
124         return self.text_surf, self.text_rect
125     def change_text(self,new_text):
126         self.text = new_text
127         self.text_surf = self.BASICFONT.render(self.text,True,self.color,self.bgcolor) 
128     def draw_on(self,surface):
129         surface.blit(self.text_surf,(self.left,self.top))
130 
131 class BarSurface(GameSurface):
132     dict_texts = {}
133     def add_text(self,text):
134         self.dict_texts[id(text)]=text.make_text()
135     def draw_on(self,surface):
136         self.fill(self.color)
137         for key in self.dict_texts:
138             self.blit(self.dict_texts[key][0],self.dict_texts[key][1])
139         surface.blit(self,self.get_lefttop())
140   
141 
142 class Screen(GameSurface):
143     def __init__(self):
144         pass
145     @staticmethod
146     def get_screen():
147         return pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT))
148     @staticmethod
149     def update():
150         pygame.display.update()
151 
152 class Box:
153     def __init__(self,x,y,width=BOXWIDTH,height=BOXHEIGHT,image=None):
154         self.x = x
155         self.y = y
156         self.width = width
157         self.height = height
158         self.image = image
159         self.surf = Surface((self.width,self.height))
160         self.color = WHITE 
161         self.surf.fill(self.color)
162         self.is_revealed = False
163         self.cover_color = COVERCOLOR
164         self.boxx = 0
165         self.boxy = 0
166 
167     def set_cord(self,x,y):
168         self.x = x
169         self.y = y
170     
171     def set_image(self,image):
172         self.image = image
173     
174     def set_surf(self,surf):
175         self.surf = surf
176     def set_surf_color(self,color):
177         self.surf.fill(color)
178     
179     
180 def x_relative_board_to_window(x):
181     return x + BOARDLEFT
182 
183 def y_relative_board_to_window(y):
184     return y + BOARDTOP
185 
186 def XRBW(x):
187     return x_relative_board_to_window(x)
188 def YRBW(y):
189     return y_relative_board_to_window(y)
190 
191 def draw_boxs(DISPLAYSURF,BOARD,boxs):
192     for i in range(NUMBOXHORIZONTAL):
193         for j in range(NUMBOXVERTIVAL):
194             if boxs[i][j].is_revealed == True:
195                 DISPLAYSURF.blit(boxs[i][j].surf,(XRBW(boxs[i][j].x),YRBW(boxs[i][j].y)))
196                 
197 
198 def get_box_pixel_topleft(boxs,mousex,mousey):
199     for i in range(NUMBOXHORIZONTAL):
200         for j in range(NUMBOXVERTIVAL):
201             box_rect = pygame.Rect(XRBW(boxs[i][j].x),YRBW(boxs[i][j].y),BOXWIDTH,BOXHEIGHT)
202             if box_rect.collidepoint(mousex,mousey):
203                 return box_rect.top,box_rect.left
204     return None,None
205 
206 def get_box_x_y(boxs,mousex,mousey):
207     for i in range(NUMBOXHORIZONTAL):
208         for j in range(NUMBOXVERTIVAL):
209             box_rect = pygame.Rect(XRBW(boxs[i][j].x),YRBW(boxs[i][j].y),BOXWIDTH,BOXHEIGHT)
210             if box_rect.collidepoint(mousex,mousey):
211                 return (i,j)
212     return (None,None)
213 
214 def anim_highlight_box(DISPLAYSURF,boxs,box_pixel_topleft):
215     top = box_pixel_topleft[0]
216     left = box_pixel_topleft[1]
217     pygame.draw.rect(DISPLAYSURF, HIGHLIGHTCOLOR, (left - 5, top - 5, BOXWIDTH + 10, BOXHEIGHT + 10), 4)
218 
219 
220 
221 def init_boxs_pixel_x_y_relative_BOARD():
222     boxs = [] 
223     for i in range(NUMBOXHORIZONTAL):
224         vert_boxs = []
225         x = BOXMARGINWIDTH
226         x += i * (BOXWIDTH + GAPBETBOXS)
227         for j in range(NUMBOXVERTIVAL):
228             y = BOXMARGINHEIGHT
229             y += j * (BOXHEIGHT + GAPBETBOXS)
230             box = Box(x,y,BOXWIDTH,BOXHEIGHT)
231             box.boxx = i
232             box.boxy = j                      
233             vert_boxs.append(box)
234         boxs.append(vert_boxs)
235     return boxs
236 
237 def draw_covers(DISPLAYSURF,BOARD,boxs,coverage):
238     for i in range(NUMBOXHORIZONTAL):
239         for j in range(NUMBOXVERTIVAL):
240             if boxs[i][j].is_revealed == False:
241                 boxs[i][j].set_surf_color(COVERCOLOR)
242                 DISPLAYSURF.blit(boxs[i][j].surf,(XRBW(boxs[i][j].x),YRBW(boxs[i][j].y)))
243 
244 
245     
246 def draw_a_cover(surface,boxs,boxx,boxy,coverage):
247     #要有动画效果的话,底层总是要先画一下
248     pygame.draw.rect(surface, boxs[boxx][boxy].color, (XRBW(boxs[boxx][boxy].x), YRBW(boxs[boxx][boxy].y), BOXWIDTH, BOXHEIGHT))
249     pygame.draw.rect(surface, COVERCOLOR, (XRBW(boxs[boxx][boxy].x), YRBW(boxs[boxx][boxy].y), coverage, BOXHEIGHT))   
250     Screen.update()
251     Game.FPSCLOCK.tick(FPS)
252        
253                 
254 def anim_reveal(surface,boxs,boxx,boxy):
255     i = boxx
256     j = boxy
257     boxs[i][j].set_surf_color(boxs[i][j].color)
258     for coverage in range(BOXWIDTH, -1, -REVEALSPEED):
259         if coverage >=0: 
260             draw_a_cover(surface,boxs, boxx, boxy, coverage)
261 
262 def anim_cover(surface,boxs,first_select,boxx,boxy):
263     for coverage in range(0, BOXWIDTH+1, REVEALSPEED):
264         if coverage >=0: 
265             draw_a_cover(surface,boxs, first_select.boxx, first_select.boxy, coverage)
266             draw_a_cover(surface,boxs, boxx, boxy, coverage)
267 
268 
269 def is_won(boxs):
270     for i in range(NUMBOXHORIZONTAL):
271         for j in range(NUMBOXVERTIVAL): 
272             if boxs[i][j].is_revealed == False:
273                 return False
274     return True   
275 
276 
277 def main():  
278     Game.game_init()
279     DISPLAYSURF = Screen.get_screen()
280     BOARD = GameSurface(BOARDWIDTH,BOARDHEIGHT,BOARDLEFT,BOARDTOP,GRAY)
281     BAR = BarSurface(BARWIDTH,BARHEIGHT,BARLEFT,BARTOP,BLACK)
282     LIVES_text = Text('LIVES:', GREEN, BLUE,20,0,Game.BASICFONT) #20 is a relative number cus the text is blit on BOARD,not DISPLAYSURF
283     BAR.add_text(LIVES_text)
284     lives_text = Text(str(Game.lives), GREEN, BLUE,80,0,Game.BASICFONT)
285     BAR.add_text(lives_text)
286     BAR.draw_on(DISPLAYSURF)  
287     Game.shuffle_boxs_color()   
288     mousex,mousey = 0,0
289     first_select = None   
290     
291     youwon_text =  Text("You won", GREEN, BLUE,WINDOWWIDTH/2,WINDOWHEIGHT/2,Game.BASICFONT)
292     youlose_text = Text("You lose", GREEN, BLUE,WINDOWWIDTH/2,WINDOWHEIGHT/2,Game.BASICFONT)
293     
294     while True:
295         BOARD.draw_on(DISPLAYSURF)
296         mouse_clicked = False
297         for event in pygame.event.get():
298             if event.type == QUIT:
299                 pygame.quit()
300                 sys.exit()
301             elif event.type == MOUSEMOTION:
302                 mousex, mousey = event.pos
303             elif event.type == MOUSEBUTTONUP:
304                 mousex, mousey = event.pos
305                 mouse_clicked = True
306         box_pixel_topleft = get_box_pixel_topleft(Game.boxs,mousex,mousey)
307         if box_pixel_topleft != (None,None):
308             anim_highlight_box(DISPLAYSURF,Game.boxs,box_pixel_topleft)
309         (boxx,boxy) = get_box_x_y(Game.boxs,mousex,mousey)           
310         Game.draw_boxs(DISPLAYSURF)  
311         Game.draw_covers(DISPLAYSURF,0)
312         if mouse_clicked == True and (boxx,boxy) !=  (None,None):
313             if Game.boxs[boxx][boxy].is_revealed != True:
314                 Game.lives -= 1
315                 lives_text.change_text(str(Game.lives))
316                 BAR.add_text(lives_text)
317                 BAR.draw_on(DISPLAYSURF)
318                 if first_select == None:
319                     Game.boxs[boxx][boxy].is_revealed = True
320                     first_select = Game.boxs[boxx][boxy]
321                     Game.anim_reveal(DISPLAYSURF,boxx,boxy)
322                 else:
323                     Game.anim_reveal(DISPLAYSURF,boxx,boxy)
324                     if first_select.color == Game.boxs[boxx][boxy].color:
325                         Game.boxs[boxx][boxy].is_revealed = True
326                     else:
327                         Game.anim_cover(DISPLAYSURF,first_select,boxx,boxy)
328                         first_select.is_revealed = False
329                         Game.boxs[boxx][boxy].is_revealed = False
330                     first_select = None
331         if is_won(Game.boxs):
332             youwon_text.draw_on(DISPLAYSURF)
333             Screen.update()
334             lives_text.change_text(str(LIVES))
335             BAR.add_text(lives_text)
336             BAR.draw_on(DISPLAYSURF)
337             Game.wait(1000)
338             Game.reset()
339         if Game.lives <1:
340             youlose_text.draw_on(DISPLAYSURF)
341             Screen.update()
342             lives_text.change_text(str(LIVES))
343             BAR.add_text(lives_text)
344             BAR.draw_on(DISPLAYSURF)
345             Game.wait(1000)
346             Game.reset()
347         Screen.update()
348         Game.FPSCLOCK.tick(FPS)
349             
350 if __name__ == '__main__':
351     main()

转载于:https://www.cnblogs.com/sayhellototheworld/archive/2012/08/12/2635507.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值