pygame(十五)拼图游戏

pygame(十五)拼图游戏

前情提要

pygame(十五)拼图游戏_第1张图片

本节提要

pygame(十五)拼图游戏_第2张图片

内容详情

截取目标矩形图片

上节课,我们学到一个裁剪图片的方法: 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

代码解析

生成的随机序列是不一定有解的.因此要检测是否有解.
这里有展开讨论是否有解的问题.给出生成随机序列及检测是否有解的判断程序

pygame(十五)拼图游戏_第3张图片

点击响应

代码

 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个小方块来实现的游戏.
现在市面上已经很少见了.
但是小游戏却充满大智慧,想要将这个游戏玩好,还是非常考验一个人的随机应变能力,观察能力及总结能力的.
因此,可以考虑加入竞速模式,也可以考虑加入计步模式.
请各位自行发挥吧

你可能感兴趣的