本程序分为两个部分,都是由python编写而成的。一是图片切割程序,即传入图片的地址,图片的输入目录,程序会按指定的行列进行切割(采用3行3列,分成9张图片用于第二部分游戏的实现)。二是拼图游戏程序,游戏界面的正上方是一个拼图步数统计,界面左边是两个组件,上方是重新开始按钮,下方是拼图的完整原图作为拼图参考,界面右边是拼图游戏的主体,一个正方形再分成3行3列9个小正方块,用于存放8张切割好的图片,一个空白块,空白快用于实现四周小图片的移动。游戏成功会有弹窗提示游戏结束。
自从20世纪90年代初Python语言诞生至今, Python已经成为最受欢迎的程序设计语言之一。自从2004年以后,python的使用率呈线性增长。它被TIOBE编程语言排行榜评为2010年度语言。 拼图游戏是广受欢迎的一种智力游戏,它不仅可以帮助家长锻炼儿童的动手动脑能力,还可帮助扩展儿童的思维,加强还原能力,提高记忆力;同时也可促进家长与孩子之间的互动。
本程序主要意义有扩展思维,加强还原能力,提高记忆力,也可以用来打发时间
输入指定的图片地址,输入输出的保存目录,输入行列数,程序将指定图片按照指定行列数进行切割,并保存到指定目录。
第一个程序切割好的3*3=9张小图像块会在运行程序时载入(如果不用第一个程序分割图片,则需要自己准备9张指定大小的小图片按照指定名字放置在指定位置下)。
运行程序会有拼图游戏的界面。如 图1—拼图界面 所示。 右上角是拼图游戏的标题。
步数用于统计用户拼图的步数,每次图像移动后步数+1,点击重新开始可重置步数。
重新开始按钮可以重置游戏,包括重新打乱拼图和重置步数。
鼠标点击的图像块四周存在空白块,则移动图像块,并且步数+1,所有块移动到指定的位置则游戏结束,弹出“你成功了”弹窗。
图1-拼图界面:
图片裁剪基本原理如 图2—图片切割原理 所示:
图2—图片切割原理:
图片切割流程图如 图3—图片切割流程图 所示:
图3—图片切割流程图 :
拼图显示原理如 图4—拼图显示流程图 所示:
图4—拼图显示流程图: 鼠标点击移动拼图块原理如 图5—拼图块移动原理 所示:
图5—拼图块移动原理: 拼图游戏实现流程图如 图6—游戏流程图 所示:
图6—游戏流程图 :
居中并且带尺寸的图片: 当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
导包及定义常量:
from tkinter import* from tkinter.messagebox import* import random from PIL import Image,ImageTk #本程序images目录下已经有用1.图片分解切出的9张小图片 #可以用自己喜欢的图片进行替换(大小:450*450) #定义常量 #画布的尺寸 WIDTH=450 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('拼图1702-171110058') root.title("171110058-陈嘉锐-拼图")载入外部9个小图片:
#载入外部事先生成的9个小图像块 Pics=[] for i in range(9): filename=r"images/1702-171110058"+str(i)+".png" Pics.append(PhotoImage(file=filename))Square类将图像块图片绘制到Canvas上:
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)打乱图像块,按编号生成对应的图像块到board列表:
def init_board():#打乱图像块 L=list(range(9))#L列表中[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 orderID=L[idx] if orderID is 8: #8号拼块不显示,所以存为None board[i][j]=None else: board[i][j]=Square(orderID)绘制出图像块:
def drawBoard(canvas): canvas.create_polygon((0,0,WIDTH,0,WIDTH,HEIGHT,0,HEIGHT), width=1,outline='White',fill='White') #画所有图像块 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) 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 #print(board) 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 return True游戏重置及重新开始按钮:
def play_game() : global steps steps=0 init_board() def callBack2(): print("重新开始") play_game() cv.delete('all') #清除画布上的内容 drawBoard(cv)主程序:
path="/Users/xiaoyao/Desktop/python期末作业/images/1.png" image1=Image.open(path)#通过Image=photo设置要展示的图片 photo1=ImageTk.PhotoImage(image1)#创建tkinter兼容的图片 cv=Canvas(root,bg='green',width=WIDTH,height=HEIGHT) bl=Button(root,text="重新开始",command=callBack2,width=28) b2=Label(root,image=photo1,width=200) label1=Label(root,text="步数:"+str(steps),fg="red",width=40) label1.pack() cv.bind("<Button-1>",mouseclick) cv.pack(side='right') bl.pack() #b2.pack() b2.place(y = 150,width = 200,height = 200) play_game() drawBoard(cv) root.mainloop()
Python语言功能强大,但是因为自己的能力不足,实现这么是一个小小的程序却也用了很多时间,英语水平太差,python掌握得不是很多,实现一个小小的功能最后可能要在各大网站找资料,最后虽然基本上能达到了预期的目标。但是因为时间又能,能力也一般,程序还存在许多不足之处,只能等以后继续完善。