Tkinter模块GUI界面化编程实战(五)——大鱼吃小鱼游戏(含超详解及完整源码、完整程序免费下载链接)

简介: Tkinter模块GUI界面化编程实战(五)——大鱼吃小鱼游戏(含超详解及完整源码、完整程序免费下载链接)

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

【先来看看效果图】

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

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

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

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

——小鱼:你礼貌吗?

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

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

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

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

【不妨看看编写思路】

程序实现功能清单

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

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

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

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

【再来看看源代码】

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

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参数来给鱼贴上贴图美化它们,我这里只是写个框架,细节可以由大家自由发挥


目录
相关文章
|
安全 Cloud Native Linux
CMake Install:深度解析与实践(二)
CMake Install:深度解析与实践
517 0
|
算法 Unix API
指数退避(Exponential backoff)在网络请求中的应用
## 一、背景 最近做云服务 API 测试项目的过程中,发现某些时候会大批量调用 API,从而导致限流的报错。在遇到这种报错时,传统的重试策略是每隔一段时间重试一次。但由于是固定的时间重试一次,重试时又会有大量的请求在同一时刻涌入,会不断地造成限流。 这让我回想起两年前在查阅[Celery Task 文档](http://docs.celeryproject.org/en/latest
14631 1
|
5月前
|
Java 数据库连接 微服务
Java高效学习指南:从入门到精通的科学路径与实践方法
本文系统梳理Java从入门到精通的科学学习路径,涵盖基础语法、面向对象、集合框架、并发编程、JVM原理、主流框架(Spring/Spring Boot/MyBatis)及项目实战,结合高效学习方法与优质资源推荐,助力开发者构建扎实技术体系,少走弯路,快速进阶。
|
移动开发 数据挖掘 开发者
服务器发送事件(SSE)在现代Web开发中的关键作用
服务器发送事件(SSE)是HTML5标准协议,用于服务器主动向客户端推送实时数据,适合单向通信场景。相比WebSocket,SSE更简洁高效,基于HTTP协议,具备自动重连、事件驱动等特性。常见应用场景包括实时通知、新闻推送、数据分析等。通过Apipost等工具可轻松调试SSE,助力开发者构建高效实时Web应用。示例中,电商平台利用SSE实现秒杀活动通知,显著减少延迟并简化架构。掌握SSE技术,能大幅提升用户体验与开发效率。
|
10月前
|
安全 开发工具 开发者
仓颉编程语言(Cangjie)正式发布1.0.0 LTS版本,附安装配置教程
仓颉编程语言首个长期支持版本于2025年7月1日发布,定位为面向全场景应用开发的下一代语言。其特点包括多后端支持、简明语法、多范式编程、类型与内存安全、高效并发及丰富内置库。支持与C语言互操作,并提供元编程能力,助力UI开发。当前仅提供CJNative后端SDK,配套VS Code插件便于开发。安装包已规范命名,可在官网下载并按指导完成配置。
1816 1
仓颉编程语言(Cangjie)正式发布1.0.0 LTS版本,附安装配置教程
|
自然语言处理 机器人
一款基于大模型的金融分析工具Finpilot
【2月更文挑战第11天】一款基于大模型的金融分析工具Finpilot
607 1
一款基于大模型的金融分析工具Finpilot
|
存储 数据可视化 大数据
大数据平台架构设计与实施
【7月更文挑战第3天】本文探讨了大数据平台的关键技术,包括数据采集(如Kafka、Flume)、存储(HDFS、HBase、Cassandra)、处理(Hadoop、Spark)、分析挖掘及可视化工具。架构设计涉及数据收集、存储、处理、分析和应用层,强调各层次的协同与扩展性。实施步骤涵盖需求分析、技术选型、架构设计、系统部署、数据迁移、应用开发测试及上线运维,旨在为企业决策提供强有力的数据支持。
1219 3
|
人工智能 JavaScript IDE
使用Coze工作流(二)
使用Coze工作流(二)
3640 0
|
机器学习/深度学习 计算机视觉
YOLOv5改进 | 卷积篇 | 通过RFAConv重塑空间注意力(深度学习的前沿突破)
YOLOv5改进 | 卷积篇 | 通过RFAConv重塑空间注意力(深度学习的前沿突破)
742 0
|
Web App开发 数据采集 Python
让ChromeDriver 125顺利运行:解决找不到chromedriver.exe的技巧
本文介绍了如何解决Selenium使用ChromeDriver时遇到的版本不匹配问题,以及如何设置环境变量。同时,文章提供了示例代码,展示如何在Python中配置Selenium使用代理IP、设定User-Agent和Cookie进行网页抓取,以提高爬虫的效率和成功率。确保ChromeDriver与Chrome浏览器版本一致,将`chromedriver.exe`添加到环境变量,然后使用`Options`和`Proxy`类配置代理和浏览器选项,最后通过`webdriver.Chrome()`启动浏览器并执行抓取任务。
1347 0
让ChromeDriver 125顺利运行:解决找不到chromedriver.exe的技巧

热门文章

最新文章