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


目录
相关文章
|
3月前
|
数据采集 自然语言处理 Python
Python 制作微博抓取 GUI 程序
vPython 制作微博抓取 GUI 程序
|
11月前
|
数据可视化 Android开发
XMind 2021 v11.1.2破解版使用方法
XMind 2021 v11.1.2破解版使用方法
175 0
|
3月前
|
开发工具 Python Windows
基于Python开发的飞机大战小游戏彩色版(源码+可执行程序exe文件+程序配置说明书+程序使用说明书)
基于Python开发的飞机大战小游戏彩色版(源码+可执行程序exe文件+程序配置说明书+程序使用说明书)
|
3月前
|
NoSQL 开发工具 数据库
基于Python开发的五子棋小游戏(源码+可执行程序exe文件+程序配置说明书+程序使用说明书)
基于Python开发的五子棋小游戏(源码+可执行程序exe文件+程序配置说明书+程序使用说明书)
|
11月前
|
C++ Python
Python+Qt抽奖点名工具源码窗体程序
Python+Qt抽奖点名工具源码窗体程序
125 0
Python+Qt抽奖点名工具源码窗体程序
|
11月前
|
Linux Python
Python3,1行代码,制作GUI图形界面,果然被种草了。
Python3,1行代码,制作GUI图形界面,果然被种草了。
65 0
|
小程序 Python
Tkinter模块GUI界面化编程实战(四)——随机点名小程序(含详解及完整源码、完整程序下载链接)
Tkinter模块GUI界面化编程实战(四)——随机点名小程序(含详解及完整源码、完整程序下载链接)
214 0
Tkinter模块GUI界面化编程实战(四)——随机点名小程序(含详解及完整源码、完整程序下载链接)
|
存储 人工智能 算法
Tkinter模块GUI界面化编程实战(七)——人机对战五子棋(含超详解及完整源码、完整程序免费下载链接)
Tkinter模块GUI界面化编程实战(七)——人机对战五子棋(含超详解及完整源码、完整程序免费下载链接)
173 0
Tkinter模块GUI界面化编程实战(七)——人机对战五子棋(含超详解及完整源码、完整程序免费下载链接)
|
Python
Tkinter模块GUI界面化编程实战(三)——2048小游戏(含详解及完整源码、完整程序下载链接)
Tkinter模块GUI界面化编程实战(三)——2048小游戏(含详解及完整源码、完整程序下载链接)
170 0
|
前端开发 索引 Python
Tkinter模块GUI图形化编程实战(八)——中国象棋(含超详解及完整源码、完整程序免费下载链接)
Tkinter模块GUI图形化编程实战(八)——中国象棋(含超详解及完整源码、完整程序免费下载链接)
148 0