借助第三方图片处理库pillow,处理图片。
1.将原图片分割为9个组成图片的文件,并命名。
import os from PIL import Image def splitimage(src, rownum, colnum, dstpath): # 源文件、分为几行、分为几列,目标路径 img = Image.open(src) w, h = img.size if rownum <= h and colnum <= w: print('原始图片信息:%sx%s, %s,%s ' % (w, h, img.format, img.mode)) print('开始切割图片,请稍候..') s = os.path.split(src) if dstpath == '': # 没输入路径 dstpath = s[0] # 使用原图片目录 fn = s[1].split('.') # s[1]为图片文件名 basename = fn[0] # 主文件名 ext = fn[-1] # 图片扩展名 num = 0 rowheight = h // rownum # 每个块的高度 colwidth = w // colnum # 每块的宽度 for r in range(rownum): for c in range(colnum): box = (c * colwidth, r * rowheight, (c + 1) * colwidth, (r + 1) * rowheight) img.crop(box).save(os.path.join(dstpath, basename + '_' + str(num) + '.' + ext)) # 分割并重命名 num += 1 print('图片处理完毕,共生成%s张图片' % num) else: print('不合法的切割参数') src = input('请输入文件路径:') if os.path.isfile(src): dstpath = input('请输入图片输出目录:(不输入路径则表示使用源路径)') if dstpath == '' or os.path.exists(dstpath): row = int(input('请输入切割行数:')) col = int(input('请输入切割列数:')) if row > 0 and col > 0: splitimage(src, row, col, dstpath) else: print('无效的行列切割数') else: print('图片输入目录%s不存在' % dstpath) else: print('图片文件%s不存在!' % src)
2.游戏逻辑的实现,注意Pics.append(PhotoImage(file=filename)),只能处理gif格式文件
# -*- coding: utf-8 -*- # @Time : 2020/12/14 13:49 # @Author : Zhenghui Lyu # @File : luoji.py # @Software: PyCharm from tkinter import * from tkinter.messagebox import * from tkinter import ttk import random WIDTH = 312 HEIGHT = 450 # 画布大小 IMAGE_WIDTH = WIDTH // 3 IMAGE_HEIGHT = HEIGHT // 3 # 每个图片块大小 ROWS = 3 COLS = 3 # 三行三列 steps = 0 board = [[0, 1, 2], [3, 4, 5], [6, 7, 8]] root = Tk('拼图游戏') root.title('美女拼图') Pics = [] for i in range(9): filename = 'woman_' + str(i) + '.gif' Pics.append(PhotoImage(file=filename)) # 图片填入Pics列表中,PhotoImage的图片检查只看图片本身的类型,与图片名称后缀无关。 class Square: def __init__(self, orderID): self.orderID = orderID # orderID是每个图像块对应的编号 def draw(self, canvas, board_pos): img = Pics[self.orderID] # 根据编号对应图片 canvas.create_image(board_pos, image=img) # draw函数根据board_pos位置画出对应的图片 def init_board(): L = list(range(9)) # [0,1,2,3,4,5,6,7,8] random.shuffle(L) for i in range(ROWS): for j in range(COLS): idx = i * ROWS + j # 0~2,3~5,6~8 orderID = L[idx] # 获得L值 if orderID == 8: board[i][j] = None # 8序号时不画 else: board[i][j] = Square(orderID) # 画出图块,效果为随机块 def drawBoard(canvas): canvas.create_polygon((0, 0, WIDTH, 0, WIDTH, HEIGHT, 0, HEIGHT), width=1, outline='Black') # 绘制边框 for i in range(ROWS): for j in range(COLS): if board[i][j] is not None: board[i][j].draw(canvas, (IMAGE_WIDTH * (j + 0.5), IMAGE_HEIGHT * (i + 0.5))) # 对每个图像块画边框 def mouseclick(pos): """定义图像块被点击后的事件""" global steps r = int(pos.y // IMAGE_HEIGHT) c = int(pos.x // IMAGE_WIDTH) # r,c为棋盘坐标 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 label1['text'] = '步数:' + str(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] is not None and board[i][j].orderID != i * ROWS + j: return False # 如果不是有序的,返回False return True def play_game(): global steps steps = 0 init_board() def callback2(): print('重新开始') play_game() cv.delete('all') drawBoard(cv) cv = Canvas(root, bg='green', width=WIDTH, height=HEIGHT) b1 = ttk.Button(root, text='重新开始', command=callback2, width=20) label1 = Label(root, text='步数:' + str(steps), fg='red', width=20) label1.pack() cv.bind('<Button-1>', mouseclick) # cv.find() cv.pack() b1.pack() play_game() drawBoard(cv) root.mainloop()
浙公网安备 33010602011771号