pygame(十五)拼圖游戲
前情提要

本節提要

內容詳情
截取目標矩形圖片
上節課,我們學到一個裁剪圖片的方法: chop()
這個方法是將原截掉一個十字形的位置,將剩下的四個矩形合并成一個新的矩形圖片.這樣非常不利于我們截取圖片.
因此,我們將這個方法進行改進,變成截取矩形位置的圖片的方法rect_chop()
代碼
def rect_chop(img:pygame.Surface, rect:pygame.Rect):
'''截取指定位置的圖形'''
result_surface = pygame.transform.chop(img, (0, 0, rect.left, rect.top))
rect = pygame.Rect(0, 0, rect.width, rect.height)
result_surface = pygame.transform.chop(result_surface, (rect.width, rect.height, result_surface.get_width(), result_surface.get_height()))
return result_surface
代碼決議
根據我們chop()方法的邏輯,任何的圖片,都是裁掉一個十字形的內容
因此,根據這個邏輯,我們先裁掉上邊與左邊
result_surface = pygame.transform.chop(img, (0, 0, rect.left, rect.top))
再將裁取的圖片,再裁掉右邊與下邊
result_surface = pygame.transform.chop(result_surface, (rect.width, rect.height, result_surface.get_width(), result_surface.get_height()))
生成子圖片
將一個游戲圖片,截成九個子圖片
代碼
def creat_imgs(image):
imgs = []
pos_rects = []
for i in range(3):
for j in range(3):
temp_rect = pygame.Rect(160 * j + 10 * j, 160 * i + 10 * i, 160, 160) # 位置矩形
imgs.append(rect_chop(image, temp_rect)) # 零亂圖
temp_rect.move_ip(0, 120)
pos_rects.append(temp_rect)
return pos_rects, imgs
代碼決議
根據原始圖片的大小:500 * 500 切割成160 大小的正方形. 多出20 剛好做為圖片與圖片之間的間矩
先生成切割位置矩形
temp_rect = pygame.Rect(160 * j + 10 * j, 160 * i + 10 * i, 160, 160) # 位置矩形
根據行列關系確定左上角坐標
然后用我們自己定義的切割函式來切割,并將結果加入到串列
imgs.append(rect_chop(image, temp_rect)) # 零亂圖
打亂順序
代碼
# 檢測生成的隨機序列是否有解
def check_can_do():
nums = [x for x in range(1, 9)]
while 1:
count = 0
shuffle(nums)
for i in range(8):
for j in range(i+1, 8):
if nums[j] < nums[i]:
count += 1
if count % 2 == 0:
return nums
代碼決議
生成的隨機序列是不一定有解的.因此要檢測是否有解.
這里有展開討論是否有解的問題.給出生成隨機序列及檢測是否有解的判斷程式

點擊回應
代碼
mouse_key = pygame.mouse.get_pressed()
if mouse_key[0]:
mouse_pos = pygame.mouse.get_pos()
for i in range(9):
# 檢測滑鼠有沒有落在矩形內
if pos_list[i].collidepoint(mouse_pos):
# 檢測該位置有沒有圖片
if not pos_list[i][1]:
move(pos_list, i) # 呼叫移動方法
代碼決議
先檢測是否點擊滑鼠左鍵
mouse_key = pygame.mouse.get_pressed()
if mouse_key[0]:
再檢測點擊位置是否是有效的圖片位置
for i in range(9):
# 檢測滑鼠有沒有落在矩形內
if pos_list[i].collidepoint(mouse_pos):
最后呼叫移動方法
移動方法
代碼:
def move(i):
l_list = [x for x in range(9) if x % 3 != 0] # 可以左移的位置
if i in l_list:
if pos_list[i - 1][1] == 0: # 可以左移
print(pos_list[i - 1][1], pos_list[i][1])
pos_list[i - 1][1] = pos_list[i][1]
pos_list[i][1] = 0
return
r_list = [x for x in range(9) if x % 3 != 2] # 可能右移0 1 3 4 6 7
if i in r_list:
if pos_list[i + 1][1] == 0: # 可以右移
pos_list[i + 1] [1] = pos_list[i][1]
pos_list[i][1] = 0
return
u_list = [x for x in range(9) if x > 2] # 可以上移 3,4,5,6,7,8
if i in u_list:
if pos_list[i - 3][1] == 0: # 可以上移
pos_list[i - 3][1] = pos_list[i][1]
pos_list[i][1] = 0
return
d_list = [x for x in range(9) if x < 6] # 可以下移 0,1,2,3,4,5
if i in d_list:
if pos_list[i + 3][1] == 0: # 可以下移
pos_list[i + 3] [1] = pos_list[i][1]
pos_list[i][1] = 0
return
分四個方向來檢測
看點的位置否可移.
如:2號位,只能進行左下兩個方向的移動
能左移的位置有:1,2,4,5, 7,8
能下移的位置有0,1,2,3,4,5
能右移的位置有0,1,3,4,6,7
能上移的位置有:3,4,5,6,7,8
顯然2號位只能左移和下移
然后相應的方向只需要要檢測相應的位置上是否是空的,如果是空的就移動去,且將原來的位置設定為0
判斷勝利
代碼
def check_game():
for i in range(9):
if pos_list[i][1] != i:
return False
return True
代碼決議
只要pos_list的序列按0-8排列,說明拼圖成功
畫圖程式
代碼
def draw():
screen.fill((0, 0, 0))
screen.blit(result_img, (200, 10))
for i in range(9):
nums = pos_list[i][1]
if nums:
screen.blit(img_list[nums], (pos_list[i][0].left, pos_list[i][0].top))
pygame.display.update()
代碼分析::
這里就簡了.只需要畫兩個圖:一個是參考圖,一個是正在游戲中的八個子圖即可
后記
拼圖游戲是一個小游戲.曾經最早出現的時候,還不是電子游戲,而是用一個板子,里面裝了8個小方塊來實作的游戲.
現在市面上已經很少見了.
但是小游戲卻充滿大智慧,想要將這個游戲玩好,還是非常考驗一個人的隨機應變能力,觀察能力及總結能力的.
因此,可以考慮加入競速模式,也可以考慮加入計步模式.
請各位自行發揮吧

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/248513.html
標籤:其他
上一篇:貪吃蛇C語言
