打地鼠游戏_打地鼠游戏规则及玩法学会了吗

Mark wiens

发布时间:2025-04-20

文中素材以及可执行代码可以加群:456926667,获取,这个是我创建的一个针对0基础的伙伴一个交流群,下个文章我会更新关于pycharm版本的打地鼠。

打地鼠游戏_打地鼠游戏规则及玩法学会了吗

 

如果你没有任何编程经验,而且想尝试一下学习编程开发,这个系列教程一定适合你,它将带你学习最基本的Python语法,并让你掌握小游戏的开发技巧你所需要的,就是付出一些时间和耐心来尝试这些代码和操作文中素材以及可执行代码可以加群:456926667,获取,这个是我创建的一个针对0基础的伙伴一个交流群,下个文章我会更新关于pycharm版本的打地鼠。

一、准备工作1 下载安装 python2 下载安装VS code编辑器安装时,要注意勾选 添加到path

3 安装pygame模块在VisualStudioCode的顶部菜单【Terminal-New Teminal】打开命令行终端,然后输入命令python -m pip install --upgrade pip,回车,等待完成。

然后同样输入命令pip install pygame,等待完成安装,可能需要几分钟 二、创建项目在桌面上创建一个文件夹mygame,然后在VSCode中使用菜单【File-Open Folder】,选择mygame文件夹,VSCode左侧将会出现EXPLORER导航栏。

在左侧导航栏中,【右键-New File】创建文件main.py。

- 将下面的代码粘贴到右侧`main.py`文件中 import pygame import sys pygame.display.set_mode([600,400]) while1: for

event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() 运行代码* 仍然【Terminal-New terminal】终端中输入命令

`python main.py`,这将运行我们上面的代码,看到弹出一个黑色窗口。

三、可选操作执行上面的操作的时候,VSCode的右下角会经常弹出一些提示,如果有【Install】字样,可以放心的点击它进行安装更多内容也可以从左侧栏点击图标打开【EXTENSIONS】,然后搜索@id:ms-python.python,点击找到的结果,右侧再点击【Install】按钮进行安装。

安装之后main.py文件的右上角就会出现三角形运行按钮,点击它同样可以运行代码,相当于终端中输入python main.py

image

imagepip install ...安装命令太慢Windows用户,可以从上面的网盘中下载pip.ini文件,然后在【C盘-用户-用户名】文件夹下面创建pip文件夹,再把下载的pip.ini文件拷贝进去,此后再运行pip install ...安装速度就会快很多。

对于苹果用户就麻烦很多先在终端执行cd ~切换到用户文件夹,然后执行mkdir .pip创建.pip文件夹,它是隐身的,我们打开访达,从菜单执行【前往-前往文件夹...】,前往~/.test目录,把下载的pip.conf文件粘贴进去,搞定。

pip.ini或者pip.conf文件是把原来pip默认从国外下载安装改成了从国内下载,所以速度会变快很多其中import是导入我们要使用的外部代码模块,pygame当然是必须的,sys是system系统的简写,因为我们的游戏要运行在系统(windows或者苹果macOS)上面,所以我们会用到系统的一些命令,比如下面的sys.exit()这个命令。

pyagme.display.set_mode([600,400]),这里的[600,400]是一对数字组合在一起的,叫二元数组,这里它表示宽600,高400的一个矩形整句话就是设置要弹出的窗口的大小,display显示,set设置,mode模式。

while 1:...当是1的时候,就...,1在代码里面表示正确的、真的、存在的,相反,0表示错误、假的、不存在的while 1:do something那么something就会做,如果while 0: do something那么就不会做了。

for ... sys.exit()这一段暂时可以不深究,只是固定格式只要知道它表示游戏程序运行结束的时候系统把窗口也关掉,清理好计算机不要留痕迹,exit退出游戏开发的思路游戏开发都有固定的套路,无论是打地鼠、愤怒的小鸟,还是西瓜忍者,甚至是王者荣耀这样的大型游戏,他们大致都遵循下面几个思路:。

创建一个地图场景,上面可能有些道具 比如几个地鼠洞,一些可以放小猪的木盒子,甚至非常复杂的山谷地形,上面还有很多野怪这些地图上的元素一般都是被动的,就是你不去靠近或招惹野怪的话,它们不会互相打起来自相残杀,同样,小鸟还没发射的时候,木盒子也不会自己倒塌。

创建至少一个玩家可以控制的元素,它可以和地图场景发生交互 这个可以被控制的元素我们称为玩家角色在打地鼠游戏中这个角色就是一个锤子,愤怒的小鸟中这个角色其实是弹弓,弹出的小鸟其实是个道具,在王者荣耀游戏中玩家的角色就是自己的英雄。

必须要有评判标准,用来衡量输赢胜败 玩家控制的角色和地图场景进行交互,发生反应,对应的也必须要有一个评判标准,比如计算3分钟内击中地鼠的次数,或者计算砸死的绿猪的数量,或者是打野怪获得的经验,这些规则一定要清晰而且不能互相矛盾。

大多数游戏都有输赢胜败,而胜败往往本质上只是谁的积分首先达到某个临界点可以是某个关键道具的变化,比如对战游戏中塔被摧毁,也可以是玩家角色的属性变化,比如格斗游戏中被击杀;也可以只是纯粹的某项积分评比,用排行榜代替输赢。

游戏开发的技术点要能够在窗口内绘制图形 可以是直接用代码绘制几何图形,也可以是载入图片显示内容要能用代码控制每个元素(道具和角色)的动画 动画就是一组图片不停地轮番变化要能用代码控制播放和停止每个元素的动画,还能在不同动画之间快速切换。

能够接收用户的控制,并借此影响游戏中的元素 知道用户什么时候按了键盘,什么时候点了鼠标,按了哪个按键,鼠标左键还是右键?我们经常把这些操作称之为交互事件能够对游戏中各种元素产生的有效数据进行计算和管理 玩家角色一刀砍下去,怪物的血量减少了100点,这个就是数据,而且是很有用的数据,没有这个数据的话怪物可能永远砍不死了。

有时候这些数据要保存好,让用户下一次打开游戏的时候仍然看到自己的等级和装备都还存在有些时候这些数据要及时清理,比如新的一局又开始了,地图上的道具和角色都要恢复原样打地鼠游戏我们可以把经典的打地鼠游戏简化概括为:。

地图和道具:随机位置出现地鼠图形交互角色:控制锤子图形,点击地鼠图形使其消失积分输赢:限定时间内击中地鼠图形的次数核心玩法简化成一句话就是:点击随机出现图形绘制地鼠我们用一个蓝色的圆形代表地鼠那怎么在窗口中绘制一个圆形呢?。

可以百度【pygame 画圆圈】类似的关键字,可以查到要使用pygame.draw.circle语句,它的具体语法可以从官方说明文档中找到,英文版详细说明点这里我们查到它的语法是:pygame.draw。

.circle() circle(surface, color, center, radius) -> Rect 这表示draw.circle()需要四个参数,分别是surface表面,color颜色,center中心点,radius半径。

我们继续看surface参数的说明:surface (Surface) -- surface to draw on听上去像是画布,——先要有个画布才能在上面画圆点击Surface链接,找到更进一步说明:。

Surface((width, height), flags=0, depth=0, masks=None) -> Surface 结尾的->Surface表示Surface((width....)这句话可以生成一个Surface表面,我们可以用下面的语句捕捉到这个生成的表面:

sur=pygame.Surface((600, 400) 这样,sur就是我们生成的表面了颜色和位置再返回来看color参数:color (Color or int or tuple(int, int

, int, [int])) -- color to draw with, the alpha valueis optional ifusing a tuple (RGB[A]) 很明显它是表示画什么颜色的圆。

tuple(int, int, int, [int])表示这里需要三个整数int一起表示颜色,RGB是指red红,green绿,blue蓝,alpha透明度:clr=(0,0,255) #蓝色对于center中心位置我们也可以用同样的方法得到,这里的Vector2表示二元向量,及横向x和竖向y的位置:

pos=pygame.vector2(300,200) #窗口中央绘制圆形参数都具备了,那么就可以开始画圆了运行下面的代码:importpygameimportsyspygame.init()# 初始化。

window=pygame.display.set_mode([600,400])# 设定窗口sur=pygame.Surface([600,400])# 绘制背景容器clr=(0,0,255)pos=

(300,200)rad=100while 1:foreventinpygame.event.get():ifevent.type==pygame.QUIT:sys.exit()# 每帧循环执行的代码pygame.draw.circle(sur,

clr,pos,100# 绘制圆# 刷新画面window.blit(sur,(0,0))pygame.display.flip()注意这里最底部刷新画面的两行,其中window.blit(sur, (0, 0))表示把我们绘制好的表面sur刷新到window窗口中;pygame.display.flip()表示进行窗口刷新。

随机出现随机出现就是随机位置,我们必须确保每一次花圆的pos位置都不同,而且应该是固定的几个地鼠洞位置——别忘了我们要做打地鼠游戏假设有6个地鼠位置pos分别是[200,200],[300,200],[400,200],[200,300],[300,300],[400,300],那么如何随机取到6个中一个呢?也就是如何随机取到1~6其中的一个数字即可。

我们可以百度【python 随机数】查到需要使用random模块,这是python自带的模块,不需要再重新pip install如果搜索【python random document】可以查找到官方的语法说明,如下:。

random.randint(a, b) Return a random integer N such that a <= N <= b. Alias for randrange(a, b+1).

这是说可以随机生成a和b之间的一个数字也可以从中文的菜鸟教程网学习到这个知识新建一个test.py文件,我们进行测试:import random a = random.randint(0, 5) print

(a) 每次运行都能生成不同的数字继续测试:import random a = random.randint(0, 6) pos6=[[200,200],[300,200],[400,200],[200,300],[300,300],[400,300]]。

print(pos6[a]) 这里的pos6[a]表示pos6的六个位置中的第a个运行这个代码就会每次生成不同的位置测试成功之后我们把它拷贝到刚才的画圆代码中,得到:importpygameimport。

sysimportrandompygame.init()# 初始化window=pygame.display.set_mode([600,400])# 设定窗口sur=pygame.Surface([600,

400])# 绘制背景容器clr=(0,0,255)pos6=[[200,200],[300,200],[400,200],[200,300],[300,300],[400,300]]# !!六个位置rad

=100while 1:foreventinpygame.event.get():ifevent.type==pygame.QUIT:sys.exit()# 每帧循环执行的代码sur.fill((0,0

,0))# !!用黑色覆盖前一帧的画面,实现刷新a=random.randint(0,5)# !!随机0到5pygame.draw.circle(sur,clr,pos6[a],100)# !!使用随机位置

# 刷新画面window.blit(sur,(0,0))pygame.display.flip()注意新增了sur.fill...一行,这是用黑色(0,0,0)来清理掉上一帧的内容,避免出现多个圆隔n帧刷新。

上面的代码运行之后会看到蓝色的圆四处乱跳,太快了,我们希望改变位置之后能停一下,等我们锤它我们需要画面的圆每隔n帧再随机变换一次,而不是现在的每帧都随机变思路是这样的:我们设定一个计数器,开始是0,每帧都给它增加1,就是0,1,2,3,4...直到它增到到超过50,这时候我们就改变圆的位置并同时把计数器重置为0。

代码如下:importpygameimportsysimportrandompygame.init()# 初始化window=pygame.display.set_mode([600,400])# 设定窗口

sur=pygame.Surface([600,400])# 绘制背景容器clr=(0,0,255)pos6=[[200,200],[300,200],[400,200],[200,300],[300,

300],[400,300]]# 六个位置rad=100tick=0#!!计数器while 1:foreventinpygame.event.get():ifevent.type==pygame.QUIT:

sys.exit()# 每帧循环执行的代码iftick>50:#每50次刷新变换一次sur.fill((0,0,0))# 用黑色覆盖前一帧的画面,实现刷新a=random.randint(0,5)# 随机0到5

pygame.draw.circle(sur,clr,pos6[a],100)# 使用随机位置tick=0else:#!!不刷新变换的时候tick=tick+1#!!增加计数器# 刷新画面window.blit(sur,

(0,0))pygame.display.flip()增加交互点击当用户点击画面的时候,我们要知道它点击了哪里,是否点击到了我们画的圆上面百度搜索【pygame 点击】可以找到相关资源,也可以直接在官方说明文档中找到。

思路是我们添加对event.type事件类型的实时监测,一旦发现点击事件就获取位置坐标代码如下:importpygameimportsysimportrandomfrompygame.localsimport。

*# 引入鼠标事件类型pygame.init()# 初始化window=pygame.display.set_mode([600,400])# 设定窗口sur=pygame.Surface([600,400

])# 绘制背景容器clr=(0,0,255)pos6=[[200,200],[300,200],[400,200],[200,300],[300,300],[400,300]]# 六个位置rad=100

tick=0# !!计数器pos=pos6[0]# !!在外面记录圆的位置while 1:foreventinpygame.event.get():ifevent.type==pygame.QUIT:sys.exit()

elifevent.type==MOUSEBUTTONDOWN:# !!如果是鼠标按下事件mpos=pygame.mouse.get_pos()# !!获取鼠标位置print(mpos)# 每帧循环执行的代码

iftick>50:# 每50次刷新变换一次sur.fill((0,0,0))# 用黑色覆盖前一帧的画面,实现刷新a=random.randint(0,5)# 随机0到5pos=pos6[a]# !!更新外部记录的圆的位置

pygame.draw.circle(sur,clr,pos,100)# !!使用随机位置tick=0# 重置计数器else:# !!不刷新变换的时候tick=tick+1# !!增加计数器# 刷新画面

window.blit(sur,(0,0))pygame.display.flip()运行这个代码,任意点击屏幕上的时候就会打印出档期鼠标点击的位置距离测量知道当前圆的位置pos,也知道当前点击的位置mpos,这样我们就可以计算出两点之间的距离,距离大于圆半径的就是没有点到地鼠,距离小于半径的就是点到地鼠了。

百度搜索【pygame 两点距离】可以搜到一些计算距离的方法,我们这里使用pygame官方提供的方法,测试下面代码:import pygame a=pygame.math.Vector2.length(pygame.

math.Vector2(3,4)) print(a) 它会输出5(勾三股四玄五)这里的(3,4)是pos和mpos相减得到的差把这个思路带入原来的代码,得到:importpygameimportsys

importrandomfrompygame.localsimport*# 引入鼠标事件类型pygame.init()# 初始化window=pygame.display.set_mode([600,400

])# 设定窗口sur=pygame.Surface([600,400])# 绘制背景容器clr=(0,0,255)pos6=[[200,200],[300,200],[400,200],[200,300

],[300,300],[400,300]]# 六个位置rad=50tick=0# 计数器pos=pos6[0]# 外面记录圆的位置while 1:foreventinpygame.event.get():

ifevent.type==pygame.QUIT:sys.exit()elifevent.type==MOUSEBUTTONDOWN:# 如果是鼠标按下事件mpos=pygame.mouse.get_pos()

# 获取鼠标位置dis=pygame.math.Vector2(mpos[0]-pos[0],mpos[1]-pos[1])# !!计算坐标差len=pygame.math.Vector2.length(dis)

# !!计算距离iflen50:# 每50次刷新变换一次sur.fill((0,0,0))# 用黑色覆盖前一帧的画面,实现刷新

a=random.randint(0,5)# 随机0到5pos=pos6[a]# 更新外部记录的圆的位置pygame.draw.circle(sur,clr,pos,100)# 使用随机位置tick=0

# 重置计数器else:# 不刷新变换的时候tick=tick+1# 增加计数器# 刷新画面window.blit(sur,(0,0))pygame.display.flip()在这里我们设定如果距离长度len小于圆半径rad,那么就立即设置tick=51使它大于50,立即进行随机位置变换。

截止到这里运行上面的代码,可以实现随机出现地鼠(圆)并能够点击使它消失,这也实现了游戏的最基本逻辑功能后续我们将进一步编写更多内容,让它更完善一些记录分数计算数字增加很容易,设定一个score=0,然后击中地鼠的时候增加1就可以了。

但是,如何把它显示到屏幕上呢?可以百度搜索【pygame 显示文字】然后就可以找到大致方法,我们先进行一些测试:importpygamepygame.init()# 初始化window=pygame.display.set_mode([600,

400])# 设定窗口# 显示文字pygame.font.init()# !!初始化文字font=pygame.font.SysFont(微软雅黑,30)# !!设定字体和字号sur=font.render("Hello

World!!{}".format(999),False,(255,0,0))# !!生成w文字表面while 1:foreventinpygame.event.get():ifevent.type==

pygame.QUIT:sys.exit()window.blit(sur,(200,10))# !!增加分数表面pygame.display.flip()这段代码中可以看到pygame绘制文字分三步:

pygame.font.init()先要初始化pygame.font.SysFont(微软雅黑, 30)设定字体和字号大小font.render("Hello World!!{}".format(999), False, (255, 0, 0))生成一个Surface表面

当然,最后别忘了把表面放到窗口里window.blit(sur, (200, 10))运行上面的代码得到一个窗口如下:

image我们根据这个经验改进的代码:importpygameimportsysimportrandomfrompygame.localsimport*# 引入鼠标事件类型pygame.init()# 初始化

window=pygame.display.set_mode([600,400])# 设定窗口sur=pygame.Surface([600,400])# 绘制背景容器clr=(0,0,255)pos6

=[[200,200],[300,200],[400,200],[200,300],[300,300],[400,300]]# 六个位置rad=50tick=0# 计数器pos=pos6[0]# 外面记录圆的位置

# 分数score=0# !!分数计数pygame.font.init()# !!初始化文字score_font=pygame.font.SysFont(微软雅黑,30)# !!设定字体和字号score_sur

=score_font.render(str(score),False,(255,0,0))# !!生成计数表面while 1:foreventinpygame.event.get():ifevent.type

==pygame.QUIT:sys.exit()elifevent.type==MOUSEBUTTONDOWN:# 如果是鼠标按下事件mpos=pygame.mouse.get_pos()# 获取鼠标位置

dis=pygame.math.Vector2(mpos[0]-pos[0],mpos[1]-pos[1])# 计算坐标差len=pygame.math.Vector2.length(dis)# 计算距离

iflen50:# 每50次刷新变换一次score_sur=score_font.render(

str(score),False,(255,0,0))# !!重新生成分数文字表面sur.fill((0,0,0))# 用黑色覆盖前一帧的画面,实现刷新a=random.randint(0,5)# 随机0到5

pos=pos6[a]# 更新外部记录的圆的位置pygame.draw.circle(sur,clr,pos,50)# 使用随机位置tick=0# 重置计数器else:# 不刷新变换的时候tick=tick+1

# 增加计数器# 刷新画面window.blit(sur,(0,0))window.blit(score_sur,(200,10))# !!增加分数表面pygame.display.flip()运行上面的代码,可以用鼠标点击跳动的蓝色圆,每次击中就能获得1分,实时显示在顶部。

关于文字的更多内容可以参考官方文档说明鼠标指针变锤子现在窗口中显示的仍然是鼠标,而不是锤子,下面我们来看如何把鼠标变为一个特定的图形pygame关于鼠标控制的模块是pygame.mouse,官方说明文档看这里。

我们可以用pygame.mouse.set_visible(False)来隐藏鼠标,但这样一来我们就看不到鼠标无法操作了不过不要紧,我们之前还记得当鼠标点击的时候有一个mpos = pygame.mouse.get_pos()可以获取当前鼠标的位置,同样我们可以在鼠标移动的时候获取鼠标的位置,然后在这个位置上画一个红色圆圈代表鼠标。

测试下面的代码:importpygamefrompygame.localsimport*pygame.init()window=pygame.display.set_mode([600,400])pygame.mouse.set_visible(False)

# 隐藏鼠标sur=pygame.Surface([600,400])mpos=[300,200]# 记录鼠标位置while 1:foreventinpygame.event.get():ifevent.type

==pygame.QUIT:sys.exit()elifevent.type==MOUSEMOTION:# 当鼠标移动的时候mpos=pygame.mouse.get_pos()# 更新鼠标位置sur.fill((0,

0,0))# 填充黑色pygame.draw.circle(sur,(255,0,0),mpos,10)# 在鼠标位置画红色圆window.blit(sur,(0,0))pygame.display.flip()

运行这个代码将,当鼠标划到窗口上面的时候就会有一个红点跟着鼠标移动,红点代替了原来的指针我们把这个红点鼠标代码放入到游戏中,得到下面的代码:importpygameimportsysimportrandom。

frompygame.localsimport*# 引入鼠标事件类型pygame.init()# 初始化window=pygame.display.set_mode([600,400])# 设定窗口sur

=pygame.Surface([600,400])# 绘制背景容器clr=(0,0,255)pos6=[[200,200],[300,200],[400,200],[200,300],[300,300

],[400,300]]# 六个位置rad=50tick=0# 计数器pos=pos6[0]# 外面记录圆的位置# 分数score=0# 分数计数pygame.font.init()# 初始化文字score_font

=pygame.font.SysFont(微软雅黑,30)# !!设定字体和字号score_sur=score_font.render(str(score),False,(255,0,0))# !!生成计数表面

# 鼠标pygame.mouse.set_visible(False)# !!隐藏鼠标mpos=[300,200]# !!记录鼠标位置while 1:foreventinpygame.event.get():

ifevent.type==pygame.QUIT:sys.exit()elifevent.type==MOUSEBUTTONDOWN:# 如果是鼠标按下事件mpos=pygame.mouse.get_pos()

# 获取鼠标位置dis=pygame.math.Vector2(mpos[0]-pos[0],mpos[1]-pos[1])# 计算坐标差len=pygame.math.Vector2.length(dis)

# 计算距离iflen

# !!更新鼠标位置# 每帧循环执行的代码iftick>50:# 每50次刷新变换一次score_sur=score_font.render(str(score),False,(255,0,0))# 重新生成分数文字表面

a=random.randint(0,5)# 随机0到5pos=pos6[a]# 更新外部记录的圆的位置 tick=0# 重置计数器else:# 不刷新变换的时候tick=tick+1# 增加计数器

# 绘制鼠标sur.fill((0,0,0))# !用黑色覆盖前一帧的画面,实现刷新pygame.draw.circle(sur,clr,pos,50)# !使用随机位置画地鼠pygame.draw.circle(sur,

(255,0,0),mpos,10)# !!在鼠标位置画红色圆# 刷新画面window.blit(sur,(0,0))window.blit(score_sur,(200,10))# 增加分数表面pygame.display.flip()

主义者了把sur.fill和原来画地鼠蓝圆的代码移到了下面,和画鼠标红点的代码放在了一起,这样把绘图内容放在一起更加合理限定每局时间我们有很多办法限定每局的长度,比如计时限定1分钟,或者限定地鼠跳出总计100次。

我们这里使用第二种限制,跳出100次就结束并统计分数添加一个计数器times=0,然后每次随机位置都给它增加1,当times>100的时候,我们就结束游戏并显示结束画面统计战果具体的代码没有新的内容,不多解释,直接上结果:。

importpygameimportsysimportrandomfrompygame.localsimport*# 引入鼠标事件类型pygame.init()# 初始化window=pygame.display.set_mode([600,

400])# 设定窗口sur=pygame.Surface([600,400])# 绘制背景容器clr=(0,0,255)pos6=[[200,200],[300,200],[400,200],[200

,300],[300,300],[400,300]]# 六个位置rad=50tick=0# 计数器pos=pos6[0]# 外面记录圆的位置# 分数score=0# 分数计数pygame.font.init()

# 初始化文字score_font=pygame.font.SysFont(微软雅黑,30)# !!设定字体和字号score_sur=score_font.render(str(score),False

,(255,0,0))# !!生成计数表面# 鼠标pygame.mouse.set_visible(False)# !!隐藏鼠标mpos=[300,200]# !!记录鼠标位置times=0# 地鼠跳出的次数

times_max=10#最多次数tick_max=15#地鼠每次跳多少帧while 1:foreventinpygame.event.get():ifevent.type==pygame.QUIT:sys.exit()

elifevent.type==MOUSEBUTTONDOWN:# 如果是鼠标按下事件mpos=pygame.mouse.get_pos()# 获取鼠标位置dis=pygame.math.Vector2(

mpos[0]-pos[0],mpos[1]-pos[1])# 计算坐标差len=pygame.math.Vector2.length(dis)# 计算距离iflen

score=score+1# 计分增加elifevent.type==MOUSEMOTION:# !!当鼠标移动的时候mpos=pygame.mouse.get_pos()# !!更新鼠标位置iftimes

>times_max:# 显示结束画面sur.fill((0,0,0))pygame.mouse.set_visible(True)sur.fill((0,0,0))end_font=pygame.font.SysFont(微软雅黑,

80)# !!设定字体和字号end_sur=score_font.render("YourScoreis:{}/{}!".format(score,times_max),False,(255,0,0))

# !!生成计数表面window.blit(sur,(0,0))window.blit(end_sur,(100,100))# 增加分数表面pygame.display.flip()else:# 每帧循环执行的代码

iftick>tick_max:# 每50次刷新变换一次times=times+1#增加计次score_sur=score_font.render(str(score),False,(255,0,0))

# 重新生成分数文字表面 a=random.randint(0,5)# 随机0到5pos=pos6[a]# 更新外部记录的圆的位置 tick=0# 重置计数器else:# 不刷新变换的时候

tick=tick+1# 增加计数器# 绘制鼠标sur.fill((0,0,0))# !用黑色覆盖前一帧的画面,实现刷新pygame.draw.circle(sur,clr,pos,50)# !使用随机位置画地鼠

pygame.draw.circle(sur,(255,0,0),mpos,10)# !!在鼠标位置画红色圆# 刷新画面window.blit(sur,(0,0))window.blit(score_sur,

(200,10))# 增加分数表面pygame.display.flip()运行这个代码,用鼠标点击蓝圆,蓝圆跳动10次之后结束,然后显示击中的次数你可以通过调整tick_max的数字让圆跳动的更快或更慢,调整times_max=100来让地鼠跳动100次后再结束。

现在我们的地鼠游戏已经有些模样了,但还都是蓝色红色的圆圈和圆点,下一篇我们来改变成为图片中文字体在上一节中我们只使用了英文字体,怎么显示中文字体呢?直接下载网盘里面的文件,放在你的main.py一起,将原来的。

score_font = pygame.font.SysFont(微软雅黑, 30) 修改为:score_font = pygame.font.Font(MicrosoftYaqiHeiLight-2.ttf

, 30) 然后在render里面使用中文就可以正常显示了:end_sur = score_font.render("你的得分:{}/{}!".format(score,times_max), False

, (255, 0, 0))

image另外,也可以使用系统的中文字体,但是我们不清楚系统里面到底装了哪些字体,可以用print(pygame.font.get_fonts())将所有系统字体都打印出来,然后只能从名字猜出哪些是中文字体了,注意系统字体还是要用font.SysFont而不只是font.Font。

显示背景图片这是我们的背景图片dds-map.jpg:

image我们可以用map=pygame.image.load(dds-map.jpg)把图片读取到代码里面更多官方关于图片的操作说明看这里注意pygame.image.load()得到的是一个表面surface,我们可以直接把它blit到窗口wind,也可以把它blit到。

这里是完整代码:importpygameimportsysimportrandomfrompygame.localsimport*# 引入鼠标事件类型pygame.init()# 初始化window=pygame.display.set_mode([600,

400])# 设定窗口sur=pygame.Surface([600,400])# 绘制背景容器clr=(0,0,255)posAll=[[100,150],[300,150],[500,150],[200

,300],[400,300]]# 六个位置rad=50tick=0# 计数器pos=posAll[0]# 外面记录圆的位置# 分数score=0# 分数计数pygame.font.init()# 初始化文字

score_font=pygame.font.Font(MicrosoftYaqiHeiLight-2.ttf,30)# !!设定字体和字号score_sur=score_font.render(str(score),

False,(255,0,0))# !!生成计数表面# 鼠标pygame.mouse.set_visible(False)# !!隐藏鼠标mpos=[300,200]# !!记录鼠标位置times=0# 地鼠跳出的次数

times_max=10#最多次数tick_max=30#地鼠每次跳多少帧map=pygame.image.load(dds-map.jpg)#!!读取图片while 1:foreventinpygame.event.get():

ifevent.type==pygame.QUIT:sys.exit()elifevent.type==MOUSEBUTTONDOWN:# 如果是鼠标按下事件dis=pygame.math.Vector2(

mpos[0]-pos[0],mpos[1]-pos[1])# 计算坐标差len=pygame.math.Vector2.length(dis)# 计算距离iflen

score=score+1# 计分增加elifevent.type==MOUSEMOTION:# 当鼠标移动的时候mpos=pygame.mouse.get_pos()# 更新鼠标位置 if

times>=times_max:# 显示结束画面sur.fill((0,0,0))#!!结束时候仍然用黑色清空画面pygame.mouse.set_visible(True)end_font=pygame.font.Font(MicrosoftYaqiHeiLight-2.ttf,48)

# !!设定字体和字号end_sur=score_font.render("你的分数是:{}/{}!".format(score,times_max),True,(255,0,0))# !!生成计数表面

window.blit(sur,(0,0))window.blit(end_sur,(100,100))# 增加分数表面else:sur.blit(map,(0,0))#!!添加背景图片# 每帧循环执行的代码

iftick>tick_max:# 每50次刷新变换一次times=times+1#增加计次score_sur=score_font.render("分数:{}/{}!".format(score,times),

False,(255,0,0))# 重新生成分数文字表面 a=random.randint(0,4)# 随机0到4pos=posAll[a]# 更新外部记录的圆的位置 tick

=0# 重置计数器else:# 不刷新变换的时候tick=tick+1# 增加计数器 # 绘制鼠标pygame.draw.circle(sur,clr,pos,50)# 使用随机位置画地鼠

pygame.draw.circle(sur,(255,0,0),mpos,10)# !在鼠标位置画红色圆# 刷新画面 window.blit(sur,(0,0))window.blit(score_sur,

(200,10))# 增加分数表面pygame.display.flip()#刷新画面注意我们先把图片读取,然后在每帧里面决定是否使用。运行后如下图:

image使用动态图片地鼠和锤子各有两个状态,正常的地鼠和被击打的地鼠,正常的锤子和砸下的锤子,如下图所示(下图无法直接使用,请从网盘下载):

image我们可以先把四个图片都load读取进来成为rat1,rat2,ham1,ham2,然后我们使用ratsur和hamsur表示真正要使用的表面,当鼠标按下的时候我们设定hamsur=ham2是砸下图片,当鼠标点击位置距离地鼠小于地鼠半径的时候我们使用ratsur=rat2被砸中的图片。

最后我们再分别把地鼠和锤头blit到sur上面改造后的代码如下:importpygameimportsysimportrandomfrompygame.localsimport*# 引入鼠标事件类型import

timepygame.init()# 初始化window=pygame.display.set_mode([600,400])# 设定窗口sur=pygame.Surface([600,400])# 绘制背景容器

clr=(0,0,255)posAll=[[100,150],[300,150],[500,150],[200,300],[400,300]]# 六个位置rad=50tick=0# 计数器pos=posAll[0]

# 外面记录圆的位置# 分数score=0# 分数计数pygame.font.init()# 初始化文字score_font=pygame.font.Font(MicrosoftYaqiHeiLight-2.ttf,

30)# !!设定字体和字号score_sur=score_font.render(str(score),False,(255,0,0))# !!生成计数表面# 鼠标pygame.mouse.set_visible(False)

# !!隐藏鼠标mpos=[300,200]# !!记录鼠标位置times=0# 地鼠跳出的次数times_max=10#最多次数tick_max=30#地鼠每次跳多少帧map=pygame.image.load(dds-map.jpg)#!!读取图片

rat1=pygame.image.load(rat1.png)#!!读取地鼠图片rat2=pygame.image.load(rat2.png)#!!读取被砸地鼠图片ham1=pygame.image.load(hammer1.png)#!!读取锤子图片

ham2=pygame.image.load(hammer2.png)#!!读取砸下锤子图片while 1:hamsur=ham1ratsur=rat1foreventinpygame.event.get():

ifevent.type==pygame.QUIT:sys.exit()elifevent.type==MOUSEBUTTONDOWN:# 如果是鼠标按下事件hamsur=ham2#!!使用下落锤子mpos

=pygame.mouse.get_pos()# 获取鼠标位置dis=pygame.math.Vector2(mpos[0]-pos[0],mpos[1]-pos[1])# 计算坐标差len=pygame.math.Vector2.length(dis)

# 计算距离iflen

mpos=pygame.mouse.get_pos()# 更新鼠标位置 iftimes>=times_max:# 显示结束画面sur.fill((0,0,0))#结束时候仍然用黑色清空画面

pygame.mouse.set_visible(True)end_font=pygame.font.Font(MicrosoftYaqiHeiLight-2.ttf,48)# !!设定字体和字号end_sur

=score_font.render("你的分数是:{}/{}!".format(score,times_max),True,(255,0,0))# !!生成计数表面window.blit(sur,(0,

0))window.blit(end_sur,(100,100))# 增加分数表面else:sur.blit(map,(0,0))#添加背景图片# 每帧循环执行的代码iftick>tick_max:# 每50次刷新变换一次

times=times+1#增加计次score_sur=score_font.render("分数:{}/{}!".format(score,times),False,(255,0,0))# 重新生成分数文字表面

a=random.randint(0,4)# 随机0到4pos=posAll[a]# 更新外部记录的圆的位置 tick=0# 重置计数器else:# 不刷新变换的时候tick=tick+1

# 增加计数器sur.blit(ratsur,(pos[0]-50,pos[1]-70))#绘制地鼠sur.blit(hamsur,(mpos[0]-50,mpos[1]-100))#绘制锤头# 刷新画面

window.blit(sur,(0,0))window.blit(score_sur,(200,10))# 增加分数表面pygame.display.flip()#刷新画面time.sleep(0.04)

#!!保持画面一点时间注意这里的import time和time.sleep(0.04)这是让每一帧停留一点点时间,0.04秒,每秒25帧(假设每帧画图不需要时间的话)另外我们再blit的时候使用了(pos[0]-50,pos[1]-50)这样的偏移,因为图片总是用左上角作为位置的起点,这样偏移之后就变到了图片中心,实际上我们又故意让地鼠和锤子更高一些,就使用了(pos[0]-50,pos[1]-70)。

运行之后的样子如下图:

image让游戏重新开始每次显示最终成绩之后,能不能让游戏3秒后重新开始呢?我们设定一个gameover=0,游戏结束后每帧都增加这个数字,如果gameover>100,就是过了100帧,那么我们就重新开始。

重新开始必须意味着各种数据(分数,计时什么的)和画面都要重置到原来的状态修改后的整体代码如下:importpygameimportsysimportrandomfrompygame.localsimport。

*# 引入鼠标事件类型importtimepygame.init()# 初始化window=pygame.display.set_mode([600,400])# 设定窗口sur=pygame.Surface([600,

400])# 绘制背景容器clr=(0,0,255)posAll=[[100,150],[300,150],[500,150],[200,300],[400,300]]# 六个位置rad=50tick=

0# 计数器pos=posAll[0]# 外面记录圆的位置# 分数score=0# 分数计数pygame.font.init()# 初始化文字score_font=pygame.font.Font("MicrosoftYaqiHeiLight-2.ttf",

30)# !!设定字体和字号score_sur=score_font.render(str(score),False,(255,0,0))# !!生成计数表面# 鼠标pygame.mouse.set_visible(False)

# !!隐藏鼠标mpos=[300,200]# !!记录鼠标位置times=0# 地鼠跳出的次数times_max=10# 最多次数tick_max=30# 地鼠每次跳多少帧map=pygame.image.load("dds-map.jpg")

# !!读取图片rat1=pygame.image.load("rat1.png")# !!读取地鼠图片rat2=pygame.image.load("rat2.png")# !!读取被砸地鼠图片ham1

=pygame.image.load("hammer1.png")# !!读取锤子图片ham2=pygame.image.load("hammer2.png")# !!读取砸下锤子图片gameover=

0#!!结束计时gameover_max=100#!!结束计时最大值,超过这个值就重新开始while 1:hamsur=ham1ratsur=rat1foreventinpygame.event.get():

ifevent.type==pygame.QUIT:sys.exit()elifevent.type==MOUSEBUTTONDOWN:# 如果是鼠标按下事件hamsur=ham2# !!使用下落锤子mpos

=pygame.mouse.get_pos()# 获取鼠标位置dis=pygame.math.Vector2(mpos[0]-pos[0],mpos[1]-pos[1])# 计算坐标差len=pygame.math.Vector2.length(dis)

# 计算距离iflen

# 当鼠标移动的时候mpos=pygame.mouse.get_pos()# 更新鼠标位置iftimes>=times_max:# 显示结束画面sur.fill((0,0,0))# 结束时候仍然用黑色清空画面

pygame.mouse.set_visible(True)end_font=pygame.font.Font("MicrosoftYaqiHeiLight-2.ttf",48)# !!设定字体和字号end_sur

=score_font.render("你的分数是:{}/{}!".format(score,times_max),True,(255,0,0))# !!生成计数表面sur.blit(end_sur,(100,

150))cd=int((gameover_max-gameover)/10)cd_sur=score_font.render("重新开始倒计时{}".format(cd),True,(255,0,0)

)# !!生成计数表面sur.blit(cd_sur,(100,200))# 增加分数表面gameover=gameover+1#!!增加结束计时else:sur.blit(map,(0,0))# 添加背景图片

score_sur=score_font.render("分数:{}/{}!".format(score,times+1),False,(255,0,0))# 重新生成分数文字表面sur.blit(score_sur,

(200,10))# 增加分数表面iftick>tick_max:# 每50次刷新变换一次times=times+1# 增加计次a=random.randint(0,4)# 随机0到4pos=posAll[a]

# 更新外部记录的圆的位置tick=0# 重置计数器else:# 不刷新变换的时候tick=tick+1# 增加计数器iftick>5:# 开始几帧不显示地鼠sur.blit(ratsur,(pos[0]

-50,pos[1]-70))# 绘制地鼠sur.blit(hamsur,(mpos[0]-50,mpos[1]-100))# 绘制锤头# 刷新画面window.blit(sur,(0,0))pygame.display.flip()

# 刷新画面time.sleep(0.04)# !!保持画面一点时间# !!重置游戏ifgameover>gameover_max:pygame.mouse.set_visible(False)times

=0score=0gameover=0运行这个代码就能反复玩游戏了到这里游戏看上去好了很多,但是还没有背景音乐,打地鼠的时候也没有音效,下一节我们继续添加声音添加音效游戏里面的声音分为两种,一种叫音乐music,另一种叫音效sound。

背景音乐是music,游戏里面的击打声点击声都是音效同一时间播放的音乐一般只有一个,但音效可以有很多个同时播放pygame可以使用pygame.mixer.music.load(bg.mp3)来载入foo.mp3音乐,然后pygame.mixer.music.play(0)就可以播放,这里0表示播放1次,如果要无限次的播放则要改为-1.

但是如果要播放音效sound,那么pygame里面只能使用wav格式(并且不支持32位深,只支持16位深)载入音效的方法是sd=pygame.mixer.Sound("hit.wav"),播放是sd.play(0),这里0也是1次,一般音效不需要连续播放。

我们在游戏一开始就可以播放背景音乐了,但只有在点击鼠标event.type == MOUSEBUTTONDOWN的时候才播放锤子的声音,只有在击中地鼠的时候才播放地鼠的叫声修改之后的代码如下:import。

pygameimportsysimportrandomfrompygame.localsimport*# 引入鼠标事件类型importtimepygame.init()# 初始化window=pygame.display.set_mode([600,

400])# 设定窗口sur=pygame.Surface([600,400])# 绘制背景容器clr=(0,0,255)posAll=[[100,150],[300,150],[500,150],[200,

300],[400,300]]# 六个位置rad=50tick=0# 计数器pos=posAll[0]# 外面记录圆的位置# 分数score=0# 分数计数pygame.font.init()# 初始化文字

score_font=pygame.font.Font("MicrosoftYaqiHeiLight-2.ttf",30)# !!设定字体和字号score_sur=score_font.render(str(score),

False,(255,0,0))# !!生成计数表面# 鼠标pygame.mouse.set_visible(False)# !!隐藏鼠标mpos=[300,200]# !!记录鼠标位置times=0# 地鼠跳出的次数

times_max=10# 最多次数tick_max=30# 地鼠每次跳多少帧map=pygame.image.load("dds-map.jpg")# !!读取图片rat1=pygame.image.load("rat1.png")

# !!读取地鼠图片rat2=pygame.image.load("rat2.png")# !!读取被砸地鼠图片ham1=pygame.image.load("hammer1.png")# !!读取锤子图片

ham2=pygame.image.load("hammer2.png")# !!读取砸下锤子图片gameover=0# !!结束计时gameover_max=100# !!结束计时最大值,超过这个值就重新开始

# 音乐和音效pygame.mixer.music.load("bg.mp3")# !!载入背景音乐pygame.mixer.music.play(-1)# !!无限播放背景音乐hitsound=pygame.mixer.Sound("hit.wav")

# !!载入击打声音hurtsound=pygame.mixer.Sound("aiyo2.wav")# !!载入地鼠叫声while 1:hamsur=ham1ratsur=rat1foreventin

pygame.event.get():ifevent.type==pygame.QUIT:sys.exit()elifevent.type==MOUSEBUTTONDOWN:# 如果是鼠标按下事件hamsur

=ham2# 使用下落锤子hitsound.play()# !!播放击打声音mpos=pygame.mouse.get_pos()# 获取鼠标位置dis=pygame.math.Vector2(mpos[0]

-pos[0],mpos[1]-pos[1])# 计算坐标差len=pygame.math.Vector2.length(dis)# 计算距离iflen

=score+1# 计分增加ratsur=rat2# 使用被砸地鼠hurtsound.play()# !!播放地鼠声音elifevent.type==MOUSEMOTION:# 当鼠标移动的时候mpos

=pygame.mouse.get_pos()# 更新鼠标位置iftimes>=times_max:# 显示结束画面sur.fill((0,0,0))# 结束时候仍然用黑色清空画面pygame.mouse.set_visible(True)

end_font=pygame.font.Font("MicrosoftYaqiHeiLight-2.ttf",48)# 设定字体和字号end_sur=score_font.render("你的分数是:{}/{}!"

.format(score,times_max),True,(255,0,0))# 生成计数表面sur.blit(end_sur,(100,150))cd=int((gameover_max-gameover)

/10)cd_sur=score_font.render("重新开始倒计时{}".format(cd),True,(255,0,0))# 生成计数表面sur.blit(cd_sur,(100,200))

# 增加分数表面gameover=gameover+1# !!增加结束计时else:sur.blit(map,(0,0))# 添加背景图片score_sur=score_font.render("分数:{}/{}!"

.format(score,times+1),False,(255,0,0))# 重新生成分数文字表面sur.blit(score_sur,(200,10))# 增加分数表面iftick>tick_max:

# 每50次刷新变换一次times=times+1# 增加计次a=random.randint(0,4)# 随机0到4pos=posAll[a]# 更新外部记录的圆的位置tick=0# 重置计数器else:

# 不刷新变换的时候tick=tick+1# 增加计数器iftick>5:# 开始几帧不显示地鼠sur.blit(ratsur,(pos[0]-50,pos[1]-70))# 绘制地鼠sur.blit(hamsur,

(mpos[0]-50,mpos[1]-100))# 绘制锤头# 刷新画面window.blit(sur,(0,0))pygame.display.flip()# 刷新画面time.sleep(0.04)

# 保持画面一点时间# 重置游戏ifgameover>gameover_max:pygame.mouse.set_visible(False)times=0score=0gameover=0运行上面的代码,可以听到欢快的背景音乐,点击鼠标时候会有捶地声音,打中地鼠会有哎呦的叫声。

发布软件我们写的代码目前只能在自己的电脑上运行,因为我们先要安装python,然后还要安装pygame才行,这和我们平常下载的软件不同,下载的软件可以直接运行(或者安装自身后运行)Python给我们提供了自动把代码打包成软件的工具,Windows下推荐使用auto-py-to-exe工具。

同样先安装pip install auto-py-to-exe,然后只要执行auto-py-to-exe就会打开一个窗口基本设置如下:

image注意几个地方:Script Location要指向你的主要.py文件,这里是main.pyOnefile选One Directory,这会把生产的所有文件放在一个文件夹中Console Window选Console Based,因为我们的pygame是基于控制台的

Icon图标,你可以在网上下载.ico文件,比如easyicon有很多,网盘里面有一个地鼠图标icon.icoAdditional Files附加文件,点击Add Files按钮要把全部用到的字体、图片、声音都选择

CONVERT .PY TO .EXE点击这个按钮进行生成,生成后会变为两个蓝色按钮

image点击OPEN OUTPUT FOLDER打开生产的软件目录(默认在你的代码文件夹下面的output文件夹内),找到那个和你的Script Location同名的文件,点击它就可以运行游戏了

image也可以把这个MAIN.exe复制然后在桌面上粘贴快捷方式,以后只要点这个快捷方式就可以了。

image在网盘文件中包含一个main.rar文件,下载它然后解压就可以得到我打包生成的软件了关于Mac苹果电脑下面生成软件的方法暂时遇到一点麻烦,搞定之后再更新,敬请关注第一个小游戏似乎开发完成了,但是还有很多内容,我们的代码也有很多不合理的地方,下一篇我们一起来回顾和整理,并且继续介绍更多小游戏的开发方法。

添加音效游戏里面的声音分为两种,一种叫音乐music,另一种叫音效sound背景音乐是music,游戏里面的击打声点击声都是音效同一时间播放的音乐一般只有一个,但音效可以有很多个同时播放本文的文字及图片来源于网络加上自己的想法,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

免责声明:本站所有信息均搜集自互联网,并不代表本站观点,本站不对其真实合法性负责。如有信息侵犯了您的权益,请告知,本站将立刻处理。联系QQ:1640731186