欢迎光临
我们一直在努力

Tkinter模块GUI界面化编程实战(五)

上期回顾Tkinter模块GUI界面化编程实战(四)——随机点名小程序

这篇博客介绍了如何用Python Tkinter模块编写一个界面化的大鱼吃小鱼游戏,在博客下面有完整的源码,源码中有超详细的注释,帮助大家理解代码(最后还有附件可以免费下载

【注:下载文件100%可以运行,因为下载文件中包含打包了的Python程序(exe文件)!】


用Tkinter模块编写一个大鱼吃小鱼游戏

【先来看看效果图】

【玩家有3条生命,在右上角的红色方块显示】

Tkinter模块GUI界面化编程实战(五)

【初始时,有一个帮助对话框(画出来的)】

Tkinter模块GUI界面化编程实战(五)

【玩家是中间那个小黑鱼,白色的圆形是鱼眼(比较简陋,勿喷)】

——玩家:这鱼怎么这么丑,方方正正的,《我的世界》里的鱼都比这“玩意儿”好看!

——小鱼:你礼貌吗?

Tkinter模块GUI界面化编程实战(五)

【新鱼刷新时间随机,颜色随机,大小随机,速度随机,位置随机,朝向随机,鱼眼大小随机】

Tkinter模块GUI界面化编程实战(五)

【玩家扣血后会有1秒无敌时间】

Tkinter模块GUI界面化编程实战(五)

【死亡界面,胜利界面就不展示了(我玩了半天也没胜利 ToT)】

【有胜利的伙伴们可以在评论区留言哟!】

【不妨看看编写思路】

程序实现功能清单

游戏任务:大鱼吃小鱼游戏

游戏规则:玩家3条命;扣血之后一秒无敌

分数增加:吃掉鱼的长宽之和

碰撞检测:产生碰撞时,比较玩家和碰撞鱼的面积大小,以此进行死亡和加分判断

Tkinter模块GUI界面化编程实战(五)

【再来看看源代码】

【源码中几乎每行后都有详细注释,方便大家理解】

from tkinter import *#引入界面化编程模块 from random import *#引入随机数模块 game = Tk()#创建窗口 game.geometry('960x480+150+100')#设置窗口大小及位置 game.resizable(0,0)#设置窗口大小为不可更改 class Game0:#定义Game类,方便重置游戏 def __init__(self): self.pw,self.ph,self.px,self.py=40,20,455,250#玩家的初始位置 self.pf=15#玩家鱼眼大小 self.count=0#死亡计数器 self.god=False#无敌标识 self.score=0#得分 self.RGBcolorlist = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']#RGB码所有颜色字符 self.Score=IntVar()#分数显示变量 self.Score.set(self.score)#设置界面化中的分数为初始分数 self.Game = Frame(game)#定义框架,方便删除 self.Game.place(width=960,height=480) self.main = Frame(self.Game)#定义框架,方便删除 self.main.place(width=960,height=480) self.player = Label(self.Game,bg='black',fg='white',font=('consolas',self.pf),text='O',anchor='w')#画出玩家(其实就是个黑色矩形) self.player.place(width=self.pw,height=self.ph,y=self.py,x=self.px)#放置玩家的位置 Label(self.Game,bg='lightgreen',textvariable=self.Score,font=('华文新魏',20)).place(width=960,height=40)#背景 for i in range(3):Label(self.Game,bg='red').place(width=30,height=30,y=5,x=925-35*i)#命数显示 self.life = Label(self.Game,bg='lightgreen') self.life.place(height=40,x=845,width=0) Button(self.Game,bd=0,bg='orange',text='退出',font=('华文新魏',15),command=lambda:self.fishquit()).place(width=100,height=30,y=5,x=5)#退出按钮 Button(self.Game,bd=0,bg='orange',text='重置',font=('华文新魏',15),command=lambda:self.fishagain()).place(width=100,height=30,y=5,x=110)#重置按钮 self.Gamestart()#执行Gamestart函数 game.mainloop()#窗口进入消息事件循环 def Gamestart(self): Gamehelp = Frame(self.Game)#帮助对话框 Gamehelp.place(width=600,height=360,y=60,x=180) Label(Gamehelp,text='帮助',bg='grey',font=('华文新魏',15)).place(width=600,height=30)#帮助对话框标题 Label(Gamehelp,bg='lightgreen',font=('华文新魏',20),text='按‘w’、‘s’、‘a’和‘d’进行移动!\n4000分胜利!\n祝你好运!').place(width=600,height=300,y=30)#帮助对话框主体 Label(Gamehelp,bg='grey').place(width=600,height=30,y=330) Button(Gamehelp,bg='lightgreen',text='确定',bd=0,font=('华文新魏',12),command=lambda:start()).place(width=80,height=20,y=335,x=510)#确定按钮 def start():#游戏开始 game.bind('<Any-KeyPress>',lambda event:self.playmove(event.char))#键盘关联 self.randomfish()#开始随机产生鱼 Gamehelp.destroy()#摧毁帮助对话框,释放内存 def fishagain(self):#重置函数 self.pw,self.ph,self.px,self.py=40,20,455,250#重设玩家位置 self.pf=15#重设玩家鱼眼大小 self.count=0#重设死亡计数器 self.score=0#重设分数 self.Game.destroy()#摧毁之前的界面,释放内存 Game0()#重置游戏,重新实例化类 def fishquit(self):game.quit()#退出游戏 def victory(self):#胜利设定 if self.score >= 4000:#4000分胜利 Label(self.Game,bg='lightyellow',font=('华文新魏',100),text='- Victory -',fg='orange').place(width=960,height=440,y=40)#设置并显示胜利界面 self.main.destroy()#摧毁被覆盖的界面,释放内存 def death(self):#死亡设定 self.count+=1#死亡次数加一 if self.count <3:#死亡次数小于3 self.god = True if self.god == False else False#切换无敌模式的开关 self.life.place(height=40,x=845,width=self.count*40) else:#3条命都已用完 self.life.place(height=40,x=845,width=120) self.main.destroy()#摧毁之前的界面,释放内存 Label(self.Game,bg='lightyellow',font=('华文新魏',100),text='- You Dead -',fg='orange').place(width=960,height=440,y=40) if self.god == True:#打开无敌模式 self.count-=1#死亡减一(与前面的死亡次数加一抵消) self.Game.after(1000,self.death)#1000ms后关闭无敌模式 def eattest(self,fish,rw,rh,ry,rx):#碰撞检测 if self.god == False:#没有无敌模式的时候进行碰撞检测 pxw = self.px+self.pw pyh = self.py+self.ph rxw = rx+rw ryh = ry+rh #判断是否有碰撞(矩形有重合部分) test = True if (self.px<rx<pxw or self.px<rxw<pxw or rx<self.px<rxw or rx<pxw<rxw) and (self.py<ry<pyh or self.py<ryh<pyh or ry<self.py<ryh or ry<pyh<ryh) else False if test == True:#发生碰撞 if self.pw*self.ph > rw*rh:#玩家成功吃掉猎物 fish.destroy()#将吃掉的鱼摧毁,释放内存 self.score+=rw+rh#加分 self.Score.set(self.score)#更新分数 #玩家体积更新 self.pw=self.score//40+40 self.ph=self.score//80+20 self.pf=self.score//100+15 self.player.config(font=('consolas',self.pf))#玩家鱼眼大小更新 self.victory()#执行胜利检测函数 else:#玩家体积太小无法吃掉猎物,则扣血 self.death()#执行死亡函数 def fishmove(self,fish,speed,rway,rw,rh,ry,rx):#鱼的移动 rx += speed if rway == 'e' else -1*speed#鱼每10ms的横坐标方向位移 fish.place(width=rw,height=rh,y=ry,x=rx)#放置鱼 self.eattest(fish,rw,rh,ry,rx)#碰撞检测 if rx >960 or rx+rw <0:fish.destroy()#鱼游出了屏幕,摧毁它,释放内存 else:self.main.after(10,self.fishmove,fish,speed,rway,rw,rh,ry,rx)#重复移动该鱼 def randomfish(self,rcolor='#'):#随机刷新鱼 for _ in range(6):rcolor+=choice(self.RGBcolorlist)#新鱼的颜色 speed = randint(10,100+self.score//100)*0.01#新鱼的速度 rway = choice(['w','e'])#新鱼的朝向 rh = randint(self.ph//4,self.ph*2)#新鱼的高 while 1:#新鱼的宽 rw = randint(self.pw//4,self.pw*2) if rw > 1.2*rh:break rx = -1*rw if rway == 'e' else 960#新鱼的初始横坐标 ry = randint(40,480-rh)#新鱼的初始纵坐标 rf = rh//2#新鱼的鱼眼大小 fish = Label(self.main,bg=rcolor,font=('consolas',rf),text='O',anchor=rway)#创建新鱼 fish.place(width=rw,height=rh,y=ry,x=rx)#放置新鱼 self.fishmove(fish,speed,rway,rw,rh,ry,rx)#让产生的新鱼移动 self.main.after(randint(1000,3000),self.randomfish)#每1000ms到3000ms内随机产生一条新鱼 def playmove(self,way):#玩家移动 #计算玩家位置 if way == 'w' and self.py>40:#按下w键 self.py-=10 elif way == 's' and self.py<=470-self.ph:#按下s键 self.py+=10 elif way == 'a' and self.px>0:#按下a键 self.px-=10 self.player.config(anchor='w')#设置鱼头朝向 elif way == 'd' and self.px<=955-self.pw:#按下d键 self.px+=10 self.player.config(anchor='e')#设置鱼头朝向 self.player.place(width=self.pw,height=self.ph,y=self.py,x=self.px)#移动玩家位置 Game0()#实例化该类

其实是可以用一个类来实现鱼的随机产生的,但是我这里用的是函数,通过函数的传参来实现于类相似的功能,这里要注意的难点应该就是函数的传参了

说明:关于这个鱼的样式,我没有特别地去进行美化,大家可以用Label控件的image参数来给鱼贴上贴图美化它们,我这里只是写个框架,细节可以由大家自由发挥


原创不易,大家都看到这里了,点个赞,分个享,收个藏应该很简单呀!

完整程序及源码下载链接【蓝奏云】:fish.zip【密码:9s4d

下期预告:Python Tkinter编写超级游戏盒子】【下期链接超级游戏盒子

  • 海报
海报图正在生成中...
赞(0) 打赏
声明:
1、本博客不从事任何主机及服务器租赁业务,不参与任何交易,也绝非中介。博客内容仅记录博主个人感兴趣的服务器测评结果及一些服务器相关的优惠活动,信息均摘自网络或来自服务商主动提供;所以对本博客提及的内容不作直接、间接、法定、约定的保证,博客内容也不具备任何参考价值及引导作用,访问者需自行甄别。
2、访问本博客请务必遵守有关互联网的相关法律、规定与规则;不能利用本博客所提及的内容从事任何违法、违规操作;否则造成的一切后果由访问者自行承担。
3、未成年人及不能独立承担法律责任的个人及群体请勿访问本博客。
4、一旦您访问本博客,即表示您已经知晓并接受了以上声明通告。
文章名称:《Tkinter模块GUI界面化编程实战(五)》
文章链接:https://www.456zj.com/37375.html
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址