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