python基础运用
1、定义块
定义相应的块,每个方块实际就是一个按钮,所以继承Button类。每个方块的基本数据,除了方块的类型以外还有左上角的坐标,一旦确定方块的类型和坐标后,就可以确定方块对应的角色和位置了。方块左上角坐标用Point类的对象来表示,并在Block类中定义一个属性Location来表示
from tkinter import *
One=1;TowH=2;TowV=1;Four=4
class Point:
def __init__(self,x,y): #定义坐标X,Y
self.X=x
self.Y=y
class Block(Button): #块类
def __init__(self,p,blockType,master,r,bm):
Button.__init__(self,master)
self.Location=p
self.BType=blockType
self["text"]=r
self["image"]=bm
self.bind("" ,btn_MouseDown);
self.bind("" ,btn_Release);
self.place(x=self.Location.X*80,y=self.Location.Y*80)
2、定义初始坐标位置,判断条件
坐标图如下:
每个块都相应完成具体的操作,每个块功能如下:
(1) Block类中定义一个函数GetPoints来
获取该方块所占据的所有坐标位置的列表,
通过方块类型和左上角的坐标就可以得到
占据的所有坐标位置。
(2) 再定义函数 IsValid 来判断这个方块是
否在游戏区域内,如果有任何部分出界就
返回False,可以通过方块类型和左上角坐
标来判断。
(3) 函数Intersects(Block b) 用来判断一个
角色是否和另一个角色有重叠部分,如果
有则返回True,通过获取两个角色各自占
据的点来判断是否有重叠。
#定义得到游戏图片的初始位置
def getPoints(self):
pList=[]
if self.BType==One:
pList.append(self.Location)
elif self.BType==TowH:
pList.append(self.Location)
pList.append(Point(self.Location.X+1,self.Location.Y))
elif self.BType==TowV:
pList.append(self.Location)
pList.append(Point(self.Location.X,self.Location.Y+1))
elif self.BType==Four:
pList.append(self.Location)
pList.append(Point(self.Location.X,self.Location.Y+1))
pList.append(Point(self.Location.X+1,self.Location.Y))
pList.append(Point(self.Location.X+1,self.Location.Y+1))
return pList
def isValid(self,width,height): #判断移动边界条件
points=self.getPoints()
for i in points:
if i.X<0 or i.X>=width or i.Y<0 or i.Y>=height:
return False
return True
def Intersects(self,block): #判断角色是否重叠
mypoints=self.getPoints()
otherpoints=block.getPoints()
for i in mypoints:
for j in otherpoints:
if i.X==j.X and i.Y==j.Y:
return True
return False
3、 定义Game控制游戏
(1). 定义Game类并定义一些变量
首先包含场地的宽度和高度,
在华容道中宽度为4格,高度为5
格,在类中定义变量 Width=4;
Height=5类中定义一个列表保存
游戏中的所有方块,开始为空:
Blocks = [ ],类中再定义一个
变量保存结束位置坐标,变量名
和代码:finishPoint = Point(1,3)
(2). 在类中定义函数GetBlockByPos(self, p )获取指定位置方块
(3). AddBlock(self, block) 用于向列表Blocks中添加方块,
可用来编辑游戏。需要判断添加的方块是否已经在列表内,是否在有效范围内,以及是否和任何已在列表中的方块有重叠,都符合条件才允许添加,代码如有图。
(4). 定义函数MoveBlock用来移动角色的方块
MoveBlock所做的是将移动的方块先朝指
定方向移动,然后判断该方块是否出界,是否
与其他方块有重叠,如果是则保留在原来的位
置,否则进行移动更新位置。
(5). 定义函数GameWin判断游戏是否胜利
根据类的全局变量WinFlag的值来判断
游戏是否胜利。在函数MoveBlock中会判断
曹操是否移动到位置(1,3)这个坐标,如果是
则把WinFlag的值置为True。
class Game(): #控制游戏模块,
Width=4
Height=5
WinFlag=False
Blocks=[]
finishPoint=Point(1,3)
def GetBlockByPos(self,p):
for i in self.Blocks:
if i.Location.X==p.X and i.Location.Y==p.Y:
return i
return False
def AddBlock(self,block):
if block in self.Blocks:
return False
if not block.isValid(self.Width,self.Height):
return False
for i in self.Blocks:
if i.Intersects(block):
return False
self.Blocks.append(block)
return True
def MoveBlock(self,block,direction):
if block not in self.Blocks:
return
oldx=block.Location.X
oldy=block.Location.Y
if direction=="Up":
block.Location.Y-=1
elif direction=="Down":
block.Location.Y+=1
elif direction=="Left":
block.Location.X-=1
elif direction=="Right":
block.Location.X+=1
moveOK=True
if not block.isValid(self.Width,self.Height):
moveOK=False
else:
for i in self.Blocks:
if (block is not i) and block.Intersects(i):
moveOK=False
break
if moveOK==False:
block.Location=Point(oldx,oldy)
else:
if block["text"]=="曹操" and block.Location.X==1 and block.Location.Y==3:
self.WinFlag=True
return moveOK
def GameWin(self):
return self.WinFlag
oldx=0 #保存方块移动之前的x轴坐标
oldy=0 #保存方块移动之前的y轴坐标
BlockSize = 80 #方块的显示范围
mouseDownPoint=Point(0,0)#鼠标按下位置
mouseDown=False #标记鼠标是否按下
4、游戏结果处理
(1). 控制游戏的全局变量
oldx=0 #保存方块移动之前的x轴坐标
oldy=0 #保存方块移动之前的y轴坐标
BlockSize = 80 #方块的显示范围
mouseDownPoint=Point(0,0)#鼠标按下位置
mouseDown=False #标记鼠标是否按下
(2). 函数btn_MouseDown(event)
处理鼠标按下的事件,
把按下坐标值保存到各个变量。
(3). 函数btn_Realse(event)
处理鼠标松开的事件,根据鼠标拖动的水平和
垂直方向偏移量超过方格大小1/3,
则向此方向移动。
def btn_MouseDown(event):
global oldx,oldy,mouseDownPoint,mouseDown
mouseDownPoint=Point(event.x,event.y)
mouseDown=True
oldx=event.x
oldy=event.y
print(event.x,event.y)
def btn_Release(event):
global oldx,oldy,mouseDownPoint,mouseDown
if not mouseDown:
return
moveH=event.x-mouseDownPoint.X
moveV=event.y-mouseDownPoint.Y
x=int(event.widget.place_info()["x"])//80
y=int(event.widget.place_info()["y"])//80
block=game.GetBlockByPos(Point(x,y))
if moveH>=BlockSize//3:
game.MoveBlock(block,"Right")
elif moveH<=-BlockSize//3:
game.MoveBlock(block,"Left")
elif moveV>=BlockSize//3:
game.MoveBlock(block,"Down")
elif moveV<=-BlockSize//3:
game.MoveBlock(block,"Up")
else:
return
event.widget.place(x=block.Location.X*80,y=block.Location.Y*80)
if game.GameWin():
print("游戏胜利")
mouseDown=False
#win=Tk()
win=Toplevel()
win.title("华容道游戏")
win.geometry("320x400")
game=Game()
role=["曹操","关羽","黄忠","张飞","马超","赵云","兵","兵","兵","兵"]
bm=[PhotoImage(file="bmp\\%s.png"%(i)) for i in role]
block_para=[(Point(1,0),Four),(Point(1,2),TowH),(Point(3,2),TowV),(Point(0,0),TowV),
(Point(0,2),TowV),(Point(3,0),TowV),(Point(1,3),One),(Point(2,3),One),
(Point(0,4),One),(Point(3,4),One)]
for i in range(10):
b=Block(block_para[i][0],block_para[i][1],win,role[i],bm[i])
game.AddBlock(b)
win.mainloop()
参考资料链接: https://pan.baidu.com/s/1sGQFOyJpsDDCmnj68c4FFw 密码: rzqa