建造自己的网站,外国企业网站模板免费下载,网站建设需要多少个人,锦绣江南网站建设文章目录 连连看小游戏#xff1a;用Python Tkinter打造的精彩游戏体验游戏简介技术背景MainWindow类:职责:方法:Point类: 主执行部分:完整代码#xff1a;总结#xff1a; 连连看小游戏#xff1a;用Python Tkinter打造的精彩游戏体验 
在丰富多彩的游戏世界中#xff0c… 文章目录 连连看小游戏用Python Tkinter打造的精彩游戏体验游戏简介技术背景MainWindow类:职责:方法:Point类: 主执行部分:完整代码总结  连连看小游戏用Python Tkinter打造的精彩游戏体验 
在丰富多彩的游戏世界中连连看作为一种经典的解谜游戏一直备受欢迎。连连看的玩法简单却富有挑战性通过消除相同图标的配对玩家可以不断地挑战自己的观察力和反应速度。  
游戏简介 
连连看是一种考验玩家眼力和逻辑思维的益智游戏也是一种常见的休闲娱乐方式。游戏的基本规则是通过连接两个相同图标的路径消除所有的图标。路径连接可以是直线、一次拐弯或两次拐弯。只有在路径不被其他图标遮挡的情况下连接才会有效。 
技术背景 
本次实现采用了Python编程语言并利用Tkinter库作为图形用户界面的构建工具。Tkinter是Python内建的GUI工具包它提供了创建窗口、按钮、菜单等常见GUI元素的功能极大地简化了图形界面的开发过程。通过结合Python的易读性和Tkinter的灵活性我们可以迅速实现一个简单而有趣的连连看小游戏。 
MainWindow类: 
职责: 
代表游戏的主窗口。使用Tkinter处理GUI元素。管理游戏的初始化、地图绘制、处理用户点击以及检查游戏结束条件。 
代码示例 
class MainWindow():# ... (其他代码)def __init__(self):self.root  tk.Tk()# ... (其他初始化代码)def __addComponets(self):self.menubar  tk.Menu(self.root, bglightgrey, fgblack)# ... (其他菜单初始化代码)self.canvas  tk.Canvas(self.root, bgwhite, width450, height450)self.canvas.pack(sidetk.TOP, pady5)self.canvas.bind(Button-1, self.clickCanvas)# ... (其他画布初始化代码)def centerWindow(self, width, height):# ... (屏幕居中代码)def file_new(self, eventNone):# ... (新游戏初始化代码)def clickCanvas(self, event):# ... (处理画布点击事件的代码)# ... (其他方法)方法: 
__init__: 初始化主窗口并设置组件。__addComponets: 添加组件如菜单和画布到窗口。centerWindow: 将窗口居中于屏幕。file_new: 初始化并开始新游戏。clickCanvas: 处理游戏画布上的鼠标点击。isGameEnd: 检查游戏是否结束。extractSmallIconList: 从较大的图像中加载并提取小图标。iniMap: 使用随机图标初始化游戏地图。drawMap: 在画布上绘制游戏地图。 
包含用于坐标计算、绘制选定区域、清除连接块以及检查地图中空白区域的各种辅助方法。 
Point类: 
表示游戏网格上的二维点。提供用于检查有用性、相等性、克隆和更改坐标的方法。 
class Point():def __init__(self, x, y):self.x  xself.y  ydef isUserful(self):return self.x  0 and self.y  0def isEqual(self, point):return self.x  point.x and self.y  point.ydef clone(self):return Point(self.x, self.y)def changeTo(self, point):self.x  point.xself.y  point.y方法: 
__init__: 使用x和y坐标初始化点。isUserful: 检查点的坐标是否为非负数。isEqual: 检查两个点是否相等。clone: 创建点的克隆。changeTo: 更改点的坐标以匹配另一个点。 
主执行部分: 
创建MainWindow类的实例以启动游戏。 
MainWindow()完整代码 
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Date    : 2017-10-02 15:19:24
# Author  : Salamander	(1906747819qq.com)
# Link    : http://blog.51lucy.comimport os, random
import tkinter as tk
import tkinter.messagebox
from PIL import Image, ImageTkclass MainWindow():__gameTitle  连连看游戏__windowWidth  700__windowHeigth  500__icons  []__gameSize  10 # 游戏尺寸__iconKind  __gameSize * __gameSize / 4 # 小图片种类数量__iconWidth  40__iconHeight  40__map  [] # 游戏地图__delta  25__isFirst  True__isGameStart  False__formerPoint  NoneEMPTY  -1NONE_LINK  0STRAIGHT_LINK  1ONE_CORNER_LINK  2TWO_CORNER_LINK  3def __init__(self):self.root  tk.Tk()self.root.title(self.__gameTitle)self.centerWindow(self.__windowWidth, self.__windowHeigth)self.root.minsize(460, 460)self.__addComponets()self.extractSmallIconList()self.root.mainloop()def __addComponets(self):self.menubar  tk.Menu(self.root, bglightgrey, fgblack)self.file_menu  tk.Menu(self.menubar, tearoff0, bglightgrey, fgblack)self.file_menu.add_command(label新游戏, commandself.file_new, acceleratorCtrlN)self.menubar.add_cascade(label游戏, menuself.file_menu)self.root.configure(menuself.menubar)self.canvas  tk.Canvas(self.root, bg  white, width  450, height  450)self.canvas.pack(sidetk.TOP, pady  5)self.canvas.bind(Button-1, self.clickCanvas)def centerWindow(self, width, height):screenwidth  self.root.winfo_screenwidth()screenheight  self.root.winfo_screenheight()size  %dx%d%d%d % (width, height, (screenwidth - width)/2, (screenheight - height)/2)self.root.geometry(size)def file_new(self, eventNone):self.iniMap()self.drawMap()self.__isGameStart  Truedef clickCanvas(self, event):if self.__isGameStart:point  self.getInnerPoint(Point(event.x, event.y))# 有效点击坐标if point.isUserful() and not self.isEmptyInMap(point):if self.__isFirst:self.drawSelectedArea(point)self.__isFirst Falseself.__formerPoint  pointelse:if self.__formerPoint.isEqual(point):self.__isFirst  Trueself.canvas.delete(rectRedOne)else:linkType  self.getLinkType(self.__formerPoint, point)if linkType[type] ! self.NONE_LINK:# TODO Animationself.ClearLinkedBlocks(self.__formerPoint, point)self.canvas.delete(rectRedOne)self.__isFirst  Trueif self.isGameEnd():tk.messagebox.showinfo(You Win!, Tip)self.__isGameStart  Falseelse:self.__formerPoint  pointself.canvas.delete(rectRedOne)self.drawSelectedArea(point)# 判断游戏是否结束def isGameEnd(self):for y in range(0, self.__gameSize):for x in range(0, self.__gameSize):if self.__map[y][x] ! self.EMPTY:return Falsereturn True提取小头像数组def extractSmallIconList(self):root_dir  os.getcwd()imagePath  os.path.join(root_dir, images, NARUTO.png)imageSouce  Image.open(imagePath)for index in range(0, int(self.__iconKind)):region  imageSouce.crop((self.__iconWidth * index, 0, self.__iconWidth * index  self.__iconWidth - 1, self.__iconHeight - 1))self.__icons.append(ImageTk.PhotoImage(region))初始化地图 存值为0-24def iniMap(self):self.__map  [] # 重置地图tmpRecords  []records  []for i in range(0, int(self.__iconKind)):for j in range(0, 4):tmpRecords.append(i)total  self.__gameSize * self.__gameSizefor x in range(0, total):index  random.randint(0, total - x - 1)records.append(tmpRecords[index])del tmpRecords[index]# 一维数组转为二维y为高维度for y in range(0, self.__gameSize):for x in range(0, self.__gameSize):if x  0:self.__map.append([])self.__map[y].append(records[x  y * self.__gameSize])根据地图绘制图像def drawMap(self):self.canvas.delete(all)for y in range(0, self.__gameSize):for x in range(0, self.__gameSize):point  self.getOuterLeftTopPoint(Point(x, y))im  self.canvas.create_image((point.x, point.y), imageself.__icons[self.__map[y][x]], anchornw, tags  im%d%d % (x, y))获取内部坐标对应矩形左上角顶点坐标def getOuterLeftTopPoint(self, point):return Point(self.getX(point.x), self.getY(point.y))获取内部坐标对应矩形中心坐标def getOuterCenterPoint(self, point):return Point(self.getX(point.x)  int(self.__iconWidth / 2), self.getY(point.y)  int(self.__iconHeight / 2))def getX(self, x):return x * self.__iconWidth  self.__deltadef getY(self, y):return y * self.__iconHeight  self.__delta获取内部坐标def getInnerPoint(self, point):x  -1y  -1for i in range(0, self.__gameSize):x1  self.getX(i)x2  self.getX(i  1)if point.x  x1 and point.x  x2:x  ifor j in range(0, self.__gameSize):j1  self.getY(j)j2  self.getY(j  1)if point.y  j1 and point.y  j2:y  jreturn Point(x, y)选择的区域变红point为内部坐标def drawSelectedArea(self, point):pointLT  self.getOuterLeftTopPoint(point)pointRB  self.getOuterLeftTopPoint(Point(point.x  1, point.y  1))self.canvas.create_rectangle(pointLT.x, pointLT.y, pointRB.x - 1, pointRB.y - 1, outline  red, tags  rectRedOne)消除连通的两个块def ClearLinkedBlocks(self, p1, p2):self.__map[p1.y][p1.x]  self.EMPTYself.__map[p2.y][p2.x]  self.EMPTYself.canvas.delete(im%d%d % (p1.x, p1.y))self.canvas.delete(im%d%d % (p2.x, p2.y))地图上该点是否为空def isEmptyInMap(self, point):if self.__map[point.y][point.x]  self.EMPTY:return Trueelse:return False获取两个点连通类型def getLinkType(self, p1, p2):# 首先判断两个方块中图片是否相同if self.__map[p1.y][p1.x] ! self.__map[p2.y][p2.x]:return { type: self.NONE_LINK }if self.isStraightLink(p1, p2):return {type: self.STRAIGHT_LINK}res  self.isOneCornerLink(p1, p2)if res:return {type: self.ONE_CORNER_LINK,p1: res}res  self.isTwoCornerLink(p1, p2)if res:return {type: self.TWO_CORNER_LINK,p1: res[p1],p2: res[p2]}return {type: self.NONE_LINK}直连def isStraightLink(self, p1, p2):start  -1end  -1# 水平if p1.y  p2.y:# 大小判断if p2.x  p1.x:start  p2.xend  p1.xelse:start  p1.xend  p2.xfor x in range(start  1, end):if self.__map[p1.y][x] ! self.EMPTY:return Falsereturn Trueelif p1.x  p2.x:if p1.y  p2.y:start  p2.yend  p1.yelse:start  p1.yend  p2.yfor y in range(start  1, end):if self.__map[y][p1.x] ! self.EMPTY:return Falsereturn Truereturn Falsedef isOneCornerLink(self, p1, p2):pointCorner  Point(p1.x, p2.y)if self.isStraightLink(p1, pointCorner) and self.isStraightLink(pointCorner, p2) and self.isEmptyInMap(pointCorner):return pointCornerpointCorner  Point(p2.x, p1.y)if self.isStraightLink(p1, pointCorner) and self.isStraightLink(pointCorner, p2) and self.isEmptyInMap(pointCorner):return pointCornerdef isTwoCornerLink(self, p1, p2):for y in range(-1, self.__gameSize  1):pointCorner1  Point(p1.x, y)pointCorner2  Point(p2.x, y)if y  p1.y or y  p2.y:continueif y  -1 or y  self.__gameSize:if self.isStraightLink(p1, pointCorner1) and self.isStraightLink(pointCorner2, p2):return {p1: pointCorner1, p2: pointCorner2}else:if self.isStraightLink(p1, pointCorner1) and self.isStraightLink(pointCorner1, pointCorner2) and self.isStraightLink(pointCorner2, p2) and self.isEmptyInMap(pointCorner1) and self.isEmptyInMap(pointCorner2):return {p1: pointCorner1, p2: pointCorner2}# 横向判断for x in range(-1, self.__gameSize  1):pointCorner1  Point(x, p1.y)pointCorner2  Point(x, p2.y)if x  p1.x or x  p2.x:continueif x  -1 or x  self.__gameSize:if self.isStraightLink(p1, pointCorner1) and self.isStraightLink(pointCorner2, p2):return {p1: pointCorner1, p2: pointCorner2}else:if self.isStraightLink(p1, pointCorner1) and self.isStraightLink(pointCorner1, pointCorner2) and self.isStraightLink(pointCorner2, p2) and self.isEmptyInMap(pointCorner1) and self.isEmptyInMap(pointCorner2):return {p1: pointCorner1, p2: pointCorner2}class Point():def __init__(self, x, y):self.x  xself.y  ydef isUserful(self):if self.x  0 and self.y  0:return Trueelse:return False判断两个点是否相同def isEqual(self, point):if self.x  point.x and self.y  point.y:return Trueelse:return False克隆一份对象def clone(self):return Point(self.x, self.y)改为另一个对象def changeTo(self, point):self.x  point.xself.y  point.yMainWindow()总结 
在这个充满创造力和乐趣的项目中我们不仅实现了一个简单的连连看小游戏更体验了Python和Tkinter在游戏开发领域的强大潜力。可以作为初学者学习Python GUI编程和游戏开发的绝佳实例。希望这个项目能够激发更多人对编程和游戏开发的兴趣开启一个全新的学习之旅。