本教程使用python3
推荐一个python基础教程
1.导入必要的模块
import numpy, random
import matplotlib.pyplot as plt
from PIL import Image, ImageDraw, ImageFont
如果你没有安装这些模块
- 使用pip安装:
pip3 install numpy
pip3 install matplotlib
pip3 install pillow
- 或使用国内镜像:
pip3 install <包名> -i https://mirrors.aliyun.com/pypi/simple
2.定义一些常量
1.我们先定义一些必要的全局变量
H = 3 # 拼图高度
W = 3 # 拼图宽度
BG_COLOR = '#000000' # 背景颜色(黑色)
mylist = [] #
iswin = False # 是否完成的标志
empty_xy = [W - 1, H - 1] # 拼图中空格的坐标
my_img = Image.open('img.jpg') # 打开图片
i_w, i_h = my_img.size # 获取图片尺寸
i_w //= W # 一格图片的宽
i_h //= H # 一格图片的高
3.定义函数
def get_xyimg(img, x, y):
'''
获取图片的某一格
:param img: 图片对象
:param x: 这一个左上角像素坐标x
:param y: 这一个左上角像素坐标y
:return: 这一格的图片对象
'''
return img.crop((x * i_w, y * i_h, x * i_w + i_w, y * i_h + i_h))
def get_nimg(img, n):
'''
获取第n块图片
:param img: 图片对象
:param n: 第n块
:return: 第n块图片对象
'''
return get_xyimg(img, n % W, n // W)
def get_img_bylist(img, list_):
'''
按照列表中的图片顺序中生成新的图片
:param img: 图片对象
:param list_: 其实就是全局变量my_list
:return: 返回新合成的图片
'''
newimg = Image.new("RGB", (img.size[0] + W, img.size[1] + H), BG_COLOR)
for n, i in enumerate(list_):
newimg.paste(get_nimg(img, i), ((n % W) * (i_w + 1), (n // W) * (i_h + 1)))
return newimg
def up_img(n):
'''
更新图片
:param n: 鼠标所点击的图片的索引
:return: 新的图片
'''
global mylist, empty_xy, iswin
x, y = n % W, n // W
empty_n = empty_xy[1] * W + empty_xy[0]
if abs(x - empty_xy[0]) + abs(y - empty_xy[1]) == 1:
mylist[empty_n], mylist[n] = mylist[n], mylist[empty_n]
empty_xy = [x, y]
for n, i in enumerate(mylist):
if n != i:
return get_img_bylist(my_img, mylist)
iswin = True
return get_img_bylist(my_img, mylist)
return
def on_calck(event):
'''
发生鼠标点击事件后执行的函数
:param event: 事件参数
:return:
'''
axtemp = event.inaxes
print(f'点击了{event.xdata},{event.ydata}')
calck_n = (event.ydata // i_h) * W + event.xdata // i_w
print(f'点击了第{calck_n}张')
new_img = up_img(int(calck_n))
if new_img:
if iswin:
print('胜利')
new_img = new_img.point(lambda p: p * 0.5)
draw = ImageDraw.Draw(new_img)
f_size = 80
font = ImageFont.truetype("C:\Windows\Fonts\msyh.ttf", f_size, encoding="unic") # 设置字体
draw.text((W * i_w // 2 - f_size // 2 * 4, H * i_h // 2 - f_size // 2), "YOU WIN", (255, 0, 0), font=font)
axtemp.imshow(
numpy.array(
new_img
),
animated=True
)
figure.canvas.draw_idle() # 绘图动作实时反映在图像上
def init():
# 初始化
global mylist, my_img
mylist = list(range(W * H)) # 新建一个顺序列表
random.shuffle(mylist) #打乱
# 将最后一块图片设为空
if W * H - 1 != mylist[-1]:
myindex = mylist.index(W * H - 1)
mylist[myindex], mylist[-1] = mylist[-1], mylist[myindex]
last_n = mylist[-1]
my_img.paste(
Image.new("RGB", (i_w, i_h), BG_COLOR),
((last_n % W) * i_w, (last_n // W) * i_h)
)
return get_img_bylist(my_img, mylist)
figure = plt.figure()
axes_image = plt.imshow(numpy.array(init()), animated=True) # 把获取的图片话在坐标轴上面
figure.canvas.mpl_connect('button_press_event', on_calck)
plt.show()