当前位置:   article > 正文

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

大鱼吃小鱼游戏源码

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

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

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


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

【先来看看效果图】 

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

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

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

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

——小鱼:你礼貌吗?

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

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

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

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

【不妨看看编写思路】

程序实现功能清单

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

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

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

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

【再来看看源代码】

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

  1. from tkinter import *#引入界面化编程模块
  2. from random import *#引入随机数模块
  3. game = Tk()#创建窗口
  4. game.geometry('960x480+150+100')#设置窗口大小及位置
  5. game.resizable(0,0)#设置窗口大小为不可更改
  6. class Game0:#定义Game类,方便重置游戏
  7. def __init__(self):
  8. self.pw,self.ph,self.px,self.py=40,20,455,250#玩家的初始位置
  9. self.pf=15#玩家鱼眼大小
  10. self.count=0#死亡计数器
  11. self.god=False#无敌标识
  12. self.score=0#得分
  13. self.RGBcolorlist = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']#RGB码所有颜色字符
  14. self.Score=IntVar()#分数显示变量
  15. self.Score.set(self.score)#设置界面化中的分数为初始分数
  16. self.Game = Frame(game)#定义框架,方便删除
  17. self.Game.place(width=960,height=480)
  18. self.main = Frame(self.Game)#定义框架,方便删除
  19. self.main.place(width=960,height=480)
  20. self.player = Label(self.Game,bg='black',fg='white',font=('consolas',self.pf),text='O',anchor='w')#画出玩家(其实就是个黑色矩形)
  21. self.player.place(width=self.pw,height=self.ph,y=self.py,x=self.px)#放置玩家的位置
  22. Label(self.Game,bg='lightgreen',textvariable=self.Score,font=('华文新魏',20)).place(width=960,height=40)#背景
  23. for i in range(3):Label(self.Game,bg='red').place(width=30,height=30,y=5,x=925-35*i)#命数显示
  24. self.life = Label(self.Game,bg='lightgreen')
  25. self.life.place(height=40,x=845,width=0)
  26. Button(self.Game,bd=0,bg='orange',text='退出',font=('华文新魏',15),command=lambda:self.fishquit()).place(width=100,height=30,y=5,x=5)#退出按钮
  27. Button(self.Game,bd=0,bg='orange',text='重置',font=('华文新魏',15),command=lambda:self.fishagain()).place(width=100,height=30,y=5,x=110)#重置按钮
  28. self.Gamestart()#执行Gamestart函数
  29. game.mainloop()#窗口进入消息事件循环
  30. def Gamestart(self):
  31. Gamehelp = Frame(self.Game)#帮助对话框
  32. Gamehelp.place(width=600,height=360,y=60,x=180)
  33. Label(Gamehelp,text='帮助',bg='grey',font=('华文新魏',15)).place(width=600,height=30)#帮助对话框标题
  34. Label(Gamehelp,bg='lightgreen',font=('华文新魏',20),text='按‘w’、‘s’、‘a’和‘d’进行移动!\n4000分胜利!\n祝你好运!').place(width=600,height=300,y=30)#帮助对话框主体
  35. Label(Gamehelp,bg='grey').place(width=600,height=30,y=330)
  36. Button(Gamehelp,bg='lightgreen',text='确定',bd=0,font=('华文新魏',12),command=lambda:start()).place(width=80,height=20,y=335,x=510)#确定按钮
  37. def start():#游戏开始
  38. game.bind('<Any-KeyPress>',lambda event:self.playmove(event.char))#键盘关联
  39. self.randomfish()#开始随机产生鱼
  40. Gamehelp.destroy()#摧毁帮助对话框,释放内存
  41. def fishagain(self):#重置函数
  42. self.pw,self.ph,self.px,self.py=40,20,455,250#重设玩家位置
  43. self.pf=15#重设玩家鱼眼大小
  44. self.count=0#重设死亡计数器
  45. self.score=0#重设分数
  46. self.Game.destroy()#摧毁之前的界面,释放内存
  47. Game0()#重置游戏,重新实例化类
  48. def fishquit(self):game.quit()#退出游戏
  49. def victory(self):#胜利设定
  50. if self.score >= 4000:#4000分胜利
  51. Label(self.Game,bg='lightyellow',font=('华文新魏',100),text='- Victory -',fg='orange').place(width=960,height=440,y=40)#设置并显示胜利界面
  52. self.main.destroy()#摧毁被覆盖的界面,释放内存
  53. def death(self):#死亡设定
  54. self.count+=1#死亡次数加一
  55. if self.count <3:#死亡次数小于3
  56. self.god = True if self.god == False else False#切换无敌模式的开关
  57. self.life.place(height=40,x=845,width=self.count*40)
  58. else:#3条命都已用完
  59. self.life.place(height=40,x=845,width=120)
  60. self.main.destroy()#摧毁之前的界面,释放内存
  61. Label(self.Game,bg='lightyellow',font=('华文新魏',100),text='- You Dead -',fg='orange').place(width=960,height=440,y=40)
  62. if self.god == True:#打开无敌模式
  63. self.count-=1#死亡减一(与前面的死亡次数加一抵消)
  64. self.Game.after(1000,self.death)#1000ms后关闭无敌模式
  65. def eattest(self,fish,rw,rh,ry,rx):#碰撞检测
  66. if self.god == False:#没有无敌模式的时候进行碰撞检测
  67. pxw = self.px+self.pw
  68. pyh = self.py+self.ph
  69. rxw = rx+rw
  70. ryh = ry+rh
  71. #判断是否有碰撞(矩形有重合部分)
  72. 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
  73. if test == True:#发生碰撞
  74. if self.pw*self.ph > rw*rh:#玩家成功吃掉猎物
  75. fish.destroy()#将吃掉的鱼摧毁,释放内存
  76. self.score+=rw+rh#加分
  77. self.Score.set(self.score)#更新分数
  78. #玩家体积更新
  79. self.pw=self.score//40+40
  80. self.ph=self.score//80+20
  81. self.pf=self.score//100+15
  82. self.player.config(font=('consolas',self.pf))#玩家鱼眼大小更新
  83. self.victory()#执行胜利检测函数
  84. else:#玩家体积太小无法吃掉猎物,则扣血
  85. self.death()#执行死亡函数
  86. def fishmove(self,fish,speed,rway,rw,rh,ry,rx):#鱼的移动
  87. rx += speed if rway == 'e' else -1*speed#鱼每10ms的横坐标方向位移
  88. fish.place(width=rw,height=rh,y=ry,x=rx)#放置鱼
  89. self.eattest(fish,rw,rh,ry,rx)#碰撞检测
  90. if rx >960 or rx+rw <0:fish.destroy()#鱼游出了屏幕,摧毁它,释放内存
  91. else:self.main.after(10,self.fishmove,fish,speed,rway,rw,rh,ry,rx)#重复移动该鱼
  92. def randomfish(self,rcolor='#'):#随机刷新鱼
  93. for _ in range(6):rcolor+=choice(self.RGBcolorlist)#新鱼的颜色
  94. speed = randint(10,100+self.score//100)*0.01#新鱼的速度
  95. rway = choice(['w','e'])#新鱼的朝向
  96. rh = randint(self.ph//4,self.ph*2)#新鱼的高
  97. while 1:#新鱼的宽
  98. rw = randint(self.pw//4,self.pw*2)
  99. if rw > 1.2*rh:break
  100. rx = -1*rw if rway == 'e' else 960#新鱼的初始横坐标
  101. ry = randint(40,480-rh)#新鱼的初始纵坐标
  102. rf = rh//2#新鱼的鱼眼大小
  103. fish = Label(self.main,bg=rcolor,font=('consolas',rf),text='O',anchor=rway)#创建新鱼
  104. fish.place(width=rw,height=rh,y=ry,x=rx)#放置新鱼
  105. self.fishmove(fish,speed,rway,rw,rh,ry,rx)#让产生的新鱼移动
  106. self.main.after(randint(1000,3000),self.randomfish)#每1000ms到3000ms内随机产生一条新鱼
  107. def playmove(self,way):#玩家移动
  108. #计算玩家位置
  109. if way == 'w' and self.py>40:#按下w键
  110. self.py-=10
  111. elif way == 's' and self.py<=470-self.ph:#按下s键
  112. self.py+=10
  113. elif way == 'a' and self.px>0:#按下a键
  114. self.px-=10
  115. self.player.config(anchor='w')#设置鱼头朝向
  116. elif way == 'd' and self.px<=955-self.pw:#按下d键
  117. self.px+=10
  118. self.player.config(anchor='e')#设置鱼头朝向
  119. self.player.place(width=self.pw,height=self.ph,y=self.py,x=self.px)#移动玩家位置
  120. Game0()#实例化该类

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

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


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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/230030
推荐阅读
相关标签
  

闽ICP备14008679号