Python+pyGame 拼图游戏


欲学习基本的Python编程。

思编程语言学习与人类语言的学习类似,人类语言终究是要说的,编程语言终究也是要说的。人类语言说给人听,编程语言却是说给计算机听的。

人类学习说话,从牙牙学语,到流利交流,靠的是整天模仿与练习。编程语言也一样。

我觉得学习编程语言不是去死抠语法。就像汉语学习中除了语文考试要考病句外,我们平时说话不在乎语法一样。

所以这次学Python--一门新的编程语言,我决定尝试直接学着用,而不是去从头开始学语法。

花了一个小时浏览了一下Python语言的基本构成、关键字等,我决定开始写了--确切地说是开始抄。

抄程序的过程就像学汉语时跟着大人学学说话一样。

或抄或拷,我尝试运行了一本讲游戏的Python书。但里面的游戏多数是字符界面的,只有最后三两章用了PyGame包开发图形界面的游戏。

在大体上知道了Python和pyGame的用法后,我决定自己写个拼图游戏试试。


1.画图

[python]  view plain copy print ?
  1. import pygame, sys, random  
  2. from pygame.locals import *  
  3.   
  4.   
  5. WINDOWWIDTH = 500  
  6. WINDOWHEIGHT = 500  
  7. BACKGROUNDCOLOR = (000)  
  8. FPS = 40  
  9.   
  10.   
  11. def terminate():  
  12.     pygame.quit()  
  13.     sys.exit()  
  14.   
  15.   
  16. pygame.init()  
  17. mainClock = pygame.time.Clock()  
  18. windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))  
  19. pygame.display.set_caption('拼图')  
  20.   
  21.   
  22. gameImage = pygame.image.load('pic.bmp')  
  23. gameRect = gameImage.get_rect()  
  24.   
  25.   
  26. timeUsed = 0  
  27. moveUsed = 0  
  28. while True:  
  29.     for event in pygame.event.get():  
  30.         if event.type == QUIT:  
  31.             terminate()  
  32.     windowSurface.fill(BACKGROUNDCOLOR)  
  33.     windowSurface.blit(gameImage, gameRect)  
  34.   
  35.     pygame.display.update()  
  36.     mainClock.tick(FPS)  

Python+pyGame 拼图游戏_第1张图片

发现窗口大小不太合适。

解决办法:

先加载图片,然后根据图片的大小设置窗口大小:

[python]  view plain copy print ?
  1. import pygame, sys, random  
  2. from pygame.locals import *  
  3.   
  4. # 一些常量  
  5. WINDOWWIDTH = 500  
  6. WINDOWHEIGHT = 500  
  7. BACKGROUNDCOLOR = (000)  
  8. FPS = 40  
  9.   
  10. # 退出  
  11. def terminate():  
  12.     pygame.quit()  
  13.     sys.exit()  
  14.   
  15. # 初始化  
  16. pygame.init()  
  17. mainClock = pygame.time.Clock()  
  18.   
  19. # 加载图片  
  20. gameImage = pygame.image.load('pic.bmp')  
  21. gameRect = gameImage.get_rect()  
  22.   
  23. # 设置窗口  
  24. windowSurface = pygame.display.set_mode((gameRect.width, gameRect.height))  
  25. pygame.display.set_caption('拼图')  
  26.   
  27. # 游戏主循环  
  28. while True:  
  29.     for event in pygame.event.get():  
  30.         if event.type == QUIT:  
  31.             terminate()  
  32.     windowSurface.fill(BACKGROUNDCOLOR)  
  33.     windowSurface.blit(gameImage, gameRect)  
  34.   
  35.     pygame.display.update()  
  36.     mainClock.tick(FPS)  
Python+pyGame 拼图游戏_第2张图片

2.图像的分割

[python]  view plain copy print ?
  1. import pygame, sys, random  
  2. from pygame.locals import *  
  3.   
  4. # 一些常量  
  5. WINDOWWIDTH = 500  
  6. WINDOWHEIGHT = 500  
  7. BACKGROUNDCOLOR = (000)  
  8. FPS = 40  
  9.   
  10. VHNUMS = 3  
  11. CELLNUMS = VHNUMS*VHNUMS  
  12.   
  13. # 随机生成游戏盘面  
  14. def newGameBoard():  
  15.     board = []  
  16.     for i in range(CELLNUMS):  
  17.         board.append(i)  
  18.   
  19.     print(board)  
  20.     random.shuffle(board)  
  21.     print(board)  
  22.     return board  
  23.       
  24.   
  25.   
  26. # 退出  
  27. def terminate():  
  28.     pygame.quit()  
  29.     sys.exit()  
  30.   
  31. # 初始化  
  32. pygame.init()  
  33. mainClock = pygame.time.Clock()  
  34.   
  35. # 加载图片  
  36. gameImage = pygame.image.load('pic.bmp')  
  37. gameRect = gameImage.get_rect()  
  38.       
  39.   
  40. # 设置窗口  
  41. windowSurface = pygame.display.set_mode((gameRect.width, gameRect.height))  
  42. pygame.display.set_caption('拼图')  
  43.   
  44. cellWidth = int(gameRect.width / VHNUMS)  
  45. cellHeight = int(gameRect.height / VHNUMS)  
  46.   
  47.   
  48. gameBoard = newGameBoard()  
  49.   
  50.   
  51. cellImage = pygame.transform.chop(gameImage, (100100200200))  
  52.   
  53.   
  54. # 游戏主循环  
  55. while True:  
  56.     for event in pygame.event.get():  
  57.         if event.type == QUIT:  
  58.             terminate()  
  59.     windowSurface.fill(BACKGROUNDCOLOR)  
  60.     windowSurface.blit(gameImage, pygame.Rect(00, cellWidth, cellHeight), pygame.Rect(100100, cellWidth, cellHeight))  
  61.     for i in range(CELLNUMS):  
  62.         rowDst = int(i / VHNUMS)  
  63.         colDst = int(i % VHNUMS)  
  64.         rectDst = pygame.Rect(colDst*cellWidth, rowDst*cellHeight, cellWidth, cellHeight)  
  65.   
  66.         rowArea = int(gameBoard[i] / VHNUMS)  
  67.         colArea = int(gameBoard[i] % VHNUMS)  
  68.         rectArea = pygame.Rect(colArea*cellWidth, rowArea*cellHeight, cellWidth, cellHeight)  
  69.         windowSurface.blit(gameImage, rectDst, rectArea)  
  70.   
  71.     pygame.display.update()  
  72.     mainClock.tick(FPS)  


然后实现空白图像块,及保证能拼起来的随机打乱图像块算法。

随机打乱算法为实现左、右、上、下移动的算法后,随机移动若干步,则可以保证用这若干步的逆步骤使图像重新拼起来:

[python]  view plain copy print ?
  1. # 随机生成游戏盘面  
  2. def newGameBoard():  
  3.     board = []  
  4.     for i in range(CELLNUMS):  
  5.         board.append(i)  
  6.     blackCell = CELLNUMS-1  
  7.     board[blackCell] = -1  
  8.   
  9.     for i in range(MAXRANDTIME):  
  10.         direction = random.randint(03)  
  11.         if (direction == 0):  
  12.             blackCell = moveLeft(board, blackCell)  
  13.         elif (direction == 1):  
  14.             blackCell = moveRight(board, blackCell)  
  15.         elif (direction == 2):  
  16.             blackCell = moveUp(board, blackCell)  
  17.         elif (direction == 3):  
  18.             blackCell = moveDown(board, blackCell)  
  19.     return board, blackCell  
  20.   
  21. # 若空白图像块不在最左边,则将空白块左边的块移动到空白块位置    
  22. def moveRight(board, blackCell):  
  23.     if blackCell % VHNUMS == 0:  
  24.         return blackCell  
  25.     board[blackCell-1], board[blackCell] = board[blackCell], board[blackCell-1]  
  26.     return blackCell-1  
  27.   
  28. # 若空白图像块不在最右边,则将空白块右边的块移动到空白块位置    
  29. def moveLeft(board, blackCell):  
  30.     if blackCell % VHNUMS == VHNUMS-1:  
  31.         return blackCell  
  32.     board[blackCell+1], board[blackCell] = board[blackCell], board[blackCell+1]  
  33.     return blackCell+1  
  34.   
  35. # 若空白图像块不在最上边,则将空白块上边的块移动到空白块位置    
  36. def moveDown(board, blackCell):  
  37.     if blackCell < VHNUMS:  
  38.         return blackCell  
  39.     board[blackCell-VHNUMS], board[blackCell] = board[blackCell], board[blackCell-VHNUMS]  
  40.     return blackCell-VHNUMS  
  41.       
  42. # 若空白图像块不在最下边,则将空白块下边的块移动到空白块位置    
  43. def moveUp(board, blackCell):  
  44.     if blackCell >= CELLNUMS-VHNUMS:  
  45.         return blackCell  
  46.     board[blackCell+VHNUMS], board[blackCell] = board[blackCell], board[blackCell+VHNUMS]  
  47.     return blackCell+VHNUMS  

绘制分割线:

[python]  view plain copy print ?
  1. for i in range(VHNUMS+1):  
  2.         pygame.draw.line(windowSurface, BLACK, (i*cellWidth, 0), (i*cellWidth, gameRect.height))  
  3.     for i in range(VHNUMS+1):  
  4.         pygame.draw.line(windowSurface, BLACK, (0, i*cellHeight), (gameRect.width, i*cellHeight))  



3.实现鼠标键盘事件

[python]  view plain copy print ?
  1. if event.type == KEYDOWN:  
  2.             if event.key == K_LEFT or event.key == ord('a'):  
  3.                 blackCell = moveLeft(gameBoard, blackCell)  
  4.             if event.key == K_RIGHT or event.key == ord('d'):  
  5.                 blackCell = moveRight(gameBoard, blackCell)  
  6.             if event.key == K_UP or event.key == ord('w'):  
  7.                 blackCell = moveUp(gameBoard, blackCell)  
  8.             if event.key == K_DOWN or event.key == ord('s'):  
  9.                 blackCell = moveDown(gameBoard, blackCell)  
  10.         if event.type == MOUSEBUTTONDOWN and event.button == 1:  
  11.             x, y = pygame.mouse.get_pos()  
  12.             col = int(x / cellWidth)  
  13.             row = int(y / cellHeight)  
  14.             index = col + row*VHNUMS  
  15.             if (index == blackCell-1 or index == blackCell+1 or index == blackCell-VHNUMS or index == blackCell+VHNUMS):  
  16.                 gameBoard[blackCell], gameBoard[index] = gameBoard[index], gameBoard[blackCell]  
  17.                 blackCell = index  


4.判断胜利

[python]  view plain copy print ?
  1. # 是否完成  
  2. def isFinished(board, blackCell):  
  3.     for i in range(CELLNUMS-1):  
  4.         if board[i] != i:  
  5.             return False  
  6.     return True  

5.完整代码

[python]  view plain copy print ?
  1. import pygame, sys, random  
  2. from pygame.locals import *  
  3.   
  4. # 一些常量  
  5. WINDOWWIDTH = 500  
  6. WINDOWHEIGHT = 500  
  7. BACKGROUNDCOLOR = (255255255)  
  8. BLUE = (00255)  
  9. BLACK = (000)  
  10. FPS = 40  
  11.   
  12. VHNUMS = 3  
  13. CELLNUMS = VHNUMS*VHNUMS  
  14. MAXRANDTIME = 100  
  15.   
  16. # 退出  
  17. def terminate():  
  18.     pygame.quit()  
  19.     sys.exit()  
  20.       
  21. # 随机生成游戏盘面  
  22. def newGameBoard():  
  23.     board = []  
  24.     for i in range(CELLNUMS):  
  25.         board.append(i)  
  26.     blackCell = CELLNUMS-1  
  27.     board[blackCell] = -1  
  28.   
  29.     for i in range(MAXRANDTIME):  
  30.         direction = random.randint(03)  
  31.         if (direction == 0):  
  32.             blackCell = moveLeft(board, blackCell)  
  33.         elif (direction == 1):  
  34.             blackCell = moveRight(board, blackCell)  
  35.         elif (direction == 2):  
  36.             blackCell = moveUp(board, blackCell)  
  37.         elif (direction == 3):  
  38.             blackCell = moveDown(board, blackCell)  
  39.     return board, blackCell  
  40.   
  41. # 若空白图像块不在最左边,则将空白块左边的块移动到空白块位置    
  42. def moveRight(board, blackCell):  
  43.     if blackCell % VHNUMS == 0:  
  44.         return blackCell  
  45.     board[blackCell-1], board[blackCell] = board[blackCell], board[blackCell-1]  
  46.     return blackCell-1  
  47.   
  48. # 若空白图像块不在最右边,则将空白块右边的块移动到空白块位置    
  49. def moveLeft(board, blackCell):  
  50.     if blackCell % VHNUMS == VHNUMS-1:  
  51.         return blackCell  
  52.     board[blackCell+1], board[blackCell] = board[blackCell], board[blackCell+1]  
  53.     return blackCell+1  
  54.   
  55. # 若空白图像块不在最上边,则将空白块上边的块移动到空白块位置    
  56. def moveDown(board, blackCell):  
  57.     if blackCell < VHNUMS:  
  58.         return blackCell  
  59.     board[blackCell-VHNUMS], board[blackCell] = board[blackCell], board[blackCell-VHNUMS]  
  60.     return blackCell-VHNUMS  
  61.       
  62. # 若空白图像块不在最下边,则将空白块下边的块移动到空白块位置    
  63. def moveUp(board, blackCell):  
  64.     if blackCell >= CELLNUMS-VHNUMS:  
  65.         return blackCell  
  66.     board[blackCell+VHNUMS], board[blackCell] = board[blackCell], board[blackCell+VHNUMS]  
  67.     return blackCell+VHNUMS  
  68.   
  69. # 是否完成  
  70. def isFinished(board, blackCell):  
  71.     for i in range(CELLNUMS-1):  
  72.         if board[i] != i:  
  73.             return False  
  74.     return True  
  75.   
  76. # 初始化  
  77. pygame.init()  
  78. mainClock = pygame.time.Clock()  
  79.   
  80. # 加载图片  
  81. gameImage = pygame.image.load('pic.bmp')  
  82. gameRect = gameImage.get_rect()  
  83.       
  84.   
  85. # 设置窗口  
  86. windowSurface = pygame.display.set_mode((gameRect.width, gameRect.height))  
  87. pygame.display.set_caption('拼图')  
  88.   
  89. cellWidth = int(gameRect.width / VHNUMS)  
  90. cellHeight = int(gameRect.height / VHNUMS)  
  91.   
  92. finish = False  
  93.   
  94. gameBoard, blackCell = newGameBoard()  
  95.   
  96.   
  97. # 游戏主循环  
  98. while True:  
  99.     for event in pygame.event.get():  
  100.         if event.type == QUIT:  
  101.             terminate()  
  102.         if finish:  
  103.             continue  
  104.         if event.type == KEYDOWN:  
  105.             if event.key == K_LEFT or event.key == ord('a'):  
  106.                 blackCell = moveLeft(gameBoard, blackCell)  
  107.             if event.key == K_RIGHT or event.key == ord('d'):  
  108.                 blackCell = moveRight(gameBoard, blackCell)  
  109.             if event.key == K_UP or event.key == ord('w'):  
  110.                 blackCell = moveUp(gameBoard, blackCell)  
  111.             if event.key == K_DOWN or event.key == ord('s'):  
  112.                 blackCell = moveDown(gameBoard, blackCell)  
  113.         if event.type == MOUSEBUTTONDOWN and event.button == 1:  
  114.             x, y = pygame.mouse.get_pos()  
  115.             col = int(x / cellWidth)  
  116.             row = int(y / cellHeight)  
  117.             index = col + row*VHNUMS  
  118.             if (index == blackCell-1 or index == blackCell+1 or index == blackCell-VHNUMS or index == blackCell+VHNUMS):  
  119.                 gameBoard[blackCell], gameBoard[index] = gameBoard[index], gameBoard[blackCell]  
  120.                 blackCell = index  
  121.   
  122.     if (isFinished(gameBoard, blackCell)):  
  123.         gameBoard[blackCell] = CELLNUMS-1  
  124.         finish = True  
  125.       
  126.     windowSurface.fill(BACKGROUNDCOLOR)  
  127.       
  128.     for i in range(CELLNUMS):  
  129.         rowDst = int(i / VHNUMS)  
  130.         colDst = int(i % VHNUMS)  
  131.         rectDst = pygame.Rect(colDst*cellWidth, rowDst*cellHeight, cellWidth, cellHeight)  
  132.   
  133.         if gameBoard[i] == -1:  
  134.             continue  
  135.   
  136.         rowArea = int(gameBoard[i] / VHNUMS)  
  137.         colArea = int(gameBoard[i] % VHNUMS)  
  138.         rectArea = pygame.Rect(colArea*cellWidth, rowArea*cellHeight, cellWidth, cellHeight)  
  139.         windowSurface.blit(gameImage, rectDst, rectArea)  
  140.   
  141.     for i in range(VHNUMS+1):  
  142.         pygame.draw.line(windowSurface, BLACK, (i*cellWidth, 0), (i*cellWidth, gameRect.height))  
  143.     for i in range(VHNUMS+1):  
  144.         pygame.draw.line(windowSurface, BLACK, (0, i*cellHeight), (gameRect.width, i*cellHeight))  
  145.   
  146.     pygame.display.update()  
  147.     mainClock.tick(FPS)  

Python+pyGame 拼图游戏_第3张图片
本文转载自:http://blog.csdn.net/guzhou_diaoke/article/details/8197186

你可能感兴趣的:(Python+pyGame 拼图游戏)