迎中秋,我用Python开发了一款月饼拼图游戏,快来看看你要几步完成挑战吧
大家好,我是才哥。
马上中秋了,不得不说,已经感受到了浓浓的中秋气氛,大家吃月饼都快吃“吐
”了,毕竟公司之间月饼送来送去的。。
那么,今天才哥带大家玩点不一样的,咱们用Python
写个益智的拼图游戏
,咱自己拼个月饼出来,顺便比拼一下IQ
,看看最少几步搞定(欢迎留言区 留言)!
先看效果:(点击播放)
接下来,我们介绍一下开发过程。
目录:
1. 图片资源准备
2. 拼图逻辑梳理
3. 功能开发
1. 图片资源准备
案例中我们采用的是3×3
的拼图结构,需要准备一张月饼图,建议是正方形的尺寸(当然大家学会后可以任意尺寸其实),然后将图片裁剪成3×3=9
张。
这里采用的是PIL
库的操作方法,关于该库的更多操作技巧大家可以参考此前推文《Python基础模块:图像处理模块@PIL(批量分类处理图片及添加水印)》。
from PIL import Image
img = Image.open(r'月饼.png')
# 设置裁剪的 分割
n = 3
# 重置 尺寸
img = img.resize((520, 520))
w, h = img.size
for i in range(n):
for j in range(n):
# 设置裁剪的 区域(左上及右下坐标)
box = (h/n * i, h/n * j, w/n * (i+1), w/n * (j+1))
# 裁剪
region = img.crop(box)
# 保存裁剪后的图片
region.save(f'{i+3*j}.png')
2. 拼图逻辑梳理
这里我们将采取TK
库进行游戏制作,基于此我们梳理拼图逻辑。
先构建一个画布区域 然后将画布区域分为9份(本案例中),从左到右从上到下依次编号为0-8 初始情况下,随机在每个区域填充一份月饼区域图(第1步中裁剪的,除了第8张),其中有一个区域为空 点击月饼区域图,如果和空区域相邻则互换,每次互换则步数加1 当画布区域和月饼区域一一对应,则成功
接下来,我们实现以上功能。
3. 功能开发
先构建画布区域和月饼区域图列表
import random
from tkinter.messagebox import *
from tkinter import *
# 画布区域(这里就是图片尺寸)
w = w
h = h
# 月饼区域图的边长
img_w = w // 3
img_h = h // 3
# 游戏的行列数
ROWS = 3
COLS = 3
# 移动步数
steps = 0
# 保存所有月饼区域图的列表
board = [[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]
root = Tk('月饼拼图')
root.title("月饼拼图@可以叫我才哥")
# 载入月饼区域图9张(编号0-8)
Pics = []
for i in range(9):
filename = f"{i}.png"
Pics.append(PhotoImage(file=filename))
再定义一个月饼区域图的类
这个类包含编号和填充图的方法,create_image
是在指定位置创建一张图
class Square:
def __init__(self, orderID):
self.orderID = orderID
def draw(self, canvas, board_pos):
img = Pics[self.orderID]
canvas.create_image(board_pos, image=img)
初始化
就是随机打乱编号
def initBoard():
# 创建 0-8 的数字列表
L = list(range(9))
# 打乱列表顺序
random.shuffle(L)
# 为每个月饼区域块分配编号(随机)
for i in range(ROWS):
for j in range(COLS):
idx = i * ROWS+j
orderID = L[idx]
# 8号就是左下角,这里需要空出来
if orderID == 8:
board[i][j] = None
else:
board[i][j] = Square(orderID)
填充画布区域块
用月饼区域图填充对应位置
def drawBoard(canvas):
canvas.create_polygon((0, 0, w, 0, w, h, 0, h), width=1, outline='white')
for i in range(ROWS):
for j in range(COLS):
if board[i][j] != None:
board[i][j].draw(canvas, (img_w*(j+0.5), img_h*(i+0.5)))
操作逻辑
鼠标点击判断,根据点击的区域块与空白块相邻关系决定互换逻辑(上下左右)
def mouseClick(pos):
global steps
r = int(pos.y // img_h)
c = int(pos.x // img_w)
if r < 3 and c < 3:
if board[r][c] is None:
return
else:
current_square = board[r][c]
if r-1 >= 0 and board[r-1][c] is None:
board[r][c] = None
board[r-1][c] = current_square
steps += 1
elif c+1 <= 2 and board[r][c+1] is None:
board[r][c] = None
board[r][c+1] = current_square
steps += 1
elif r+1 <= 2 and board[r+1][c] is None:
board[r][c] = None
board[r+1][c] = current_square
steps += 1
elif c-1 >= 0 and board[r][c-1] is None:
board[r][c] = None
board[r][c-1] = current_square
steps += 1
lb["text"] = f"累计使用步数:{steps}"
cv.delete('all')
drawBoard(cv)
if win():
showinfo(title="提示", message="挑战成功!")
成功判断
当区域块和月饼区域块一一对应,则拼图挑战成功
def win():
for i in range(ROWS):
for j in range(COLS):
if board[i][j] != None and board[i][j].orderID !=i * ROWS + j:
return False
return True
开始游戏与重置
def playGame():
global steps
steps = 0
initBoard()
def rePlay():
print("重新开始")
playGame()
# 清除canvas画布上的内容
cv.delete('all')
# 累计步数清零
lb["text"] = "累计使用步数:0"
drawBoard(cv)
执行语句
显示当前累计步数预计重置游戏按钮
if __name__ == "__main__":
cv = Canvas(root, bg = 'white', width = w, height = h)
b1=Button(root,bg = 'yellow', text="重新开始",font = 20, command=rePlay,width=20,height=2)
lb=Label(root, text=f"累计使用步数:{steps}" ,fg="red", width=30, height=2, font=12)
lb.pack()
cv.bind("<Button-1>", mouseClick)
cv.find
cv.pack()
b1.pack()
playGame()
drawBoard(cv)
root.mainloop()
基于以上几步,我们就完成了本次的拼图游戏。
大家后台回复955
,可以在迎中秋
文件夹领取 拼图游戏 exe可执行文件进行体验。
如果你喜欢的话,还希望点赞+在看,在看
达到20
个,可添加作者微信领取 完整代码!
推荐阅读
2021-08-24
2021-09-12
2021-09-07
2021-09-10
扫描二维码添加
才哥个人微信
可以叫我才哥