欢迎关注我的专栏( つ•̀ω•́)つ【人工智能通识】
素材文件,百度网盘下载链接 密码:y1cp
中文字体
在上一节中我们只使用了英文字体,怎么显示中文字体呢?
直接下载网盘里面的文件,放在你的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))
另外,也可以使用系统的中文字体,但是我们不清楚系统里面到底装了哪些字体,可以用
print(pygame.font.get_fonts())
将所有系统字体都打印出来,然后只能从名字猜出哪些是中文字体了,注意系统字体还是要用font.SysFont
而不只是font.Font
。
显示背景图片
这是我们的背景图片dds-map.jpg
:
我们可以用map=pygame.image.load('dds-map.jpg')
把图片读取到代码里面。
更多官方关于图片的操作说明看这里
注意pygame.image.load()
得到的是一个表面surface
,我们可以直接把它blit
到窗口wind
,也可以把它blit
到。
这里是完整代码:
import pygame
import sys
import random
from pygame.locals import * # 引入鼠标事件类型
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 = 50
tick = 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:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == MOUSEBUTTONDOWN: # 如果是鼠标按下事件
dis = pygame.math.Vector2(
mpos[0]-pos[0], mpos[1]-pos[1]) # 计算坐标差
len = pygame.math.Vector2.length(dis) # 计算距离
if len < rad:
tick = 1000 # 立即变换位置
score = score+1 # 计分增加
elif event.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)) #!!添加背景图片
# 每帧循环执行的代码
if tick > tick_max: # 每50次刷新变换一次
times=times+1 #增加计次
score_sur = score_font.render(
"分数:{}/{}!".format(score,times), False, (255, 0, 0)) # 重新生成分数文字表面
a = random.randint(0, 4) # 随机0到4
pos = 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() #刷新画面
注意我们先把图片读取,然后在每帧里面决定是否使用。运行后如下图:
使用动态图片
地鼠和锤子各有两个状态,正常的地鼠和被击打的地鼠,正常的锤子和砸下的锤子,如下图所示(下图无法直接使用,请从网盘下载):
我们可以先把四个图片都load
读取进来成为rat1,rat2,ham1,ham2
,然后我们使用ratsur
和hamsur
表示真正要使用的表面,当鼠标按下的时候我们设定hamsur=ham2
是砸下图片,当鼠标点击位置距离地鼠小于地鼠半径的时候我们使用ratsur=rat2
被砸中的图片。最后我们再分别把地鼠和锤头blit
到sur
上面。
改造后的代码如下:
import pygame
import sys
import random
from pygame.locals import * # 引入鼠标事件类型
import time
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 = 50
tick = 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=ham1
ratsur=rat1
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.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) # 计算距离
if len < rad:
tick = 1000 # 立即变换位置
score = score+1 # 计分增加
ratsur=rat2 #!!使用被砸地鼠
elif event.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)) #添加背景图片
# 每帧循环执行的代码
if tick > tick_max: # 每50次刷新变换一次
times=times+1 #增加计次
score_sur = score_font.render(
"分数:{}/{}!".format(score,times), False, (255, 0, 0)) # 重新生成分数文字表面
a = random.randint(0, 4) # 随机0到4
pos = 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)
。
运行之后的样子如下图:
让游戏重新开始
每次显示最终成绩之后,能不能让游戏3秒后重新开始呢?
我们设定一个gameover=0
,游戏结束后每帧都增加这个数字,如果gameover>100
,就是过了100帧,那么我们就重新开始。
重新开始必须意味着各种数据(分数,计时什么的)和画面都要重置到原来的状态。
修改后的整体代码如下:
import pygame
import sys
import random
from pygame.locals import * # 引入鼠标事件类型
import time
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 = 50
tick = 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 = ham1
ratsur = rat1
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.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) # 计算距离
if len < rad:
tick = 1000 # 立即变换位置
score = score + 1 # 计分增加
ratsur = rat2 # !!使用被砸地鼠
elif event.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)
) # !!生成计数表面
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)) # 增加分数表面
if tick > tick_max: # 每50次刷新变换一次
times = times + 1 # 增加计次
a = random.randint(0, 4) # 随机0到4
pos = posAll[a] # 更新外部记录的圆的位置
tick = 0 # 重置计数器
else: # 不刷新变换的时候
tick = tick + 1 # 增加计数器
if tick > 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) # !!保持画面一点时间
# !!重置游戏
if gameover > gameover_max:
pygame.mouse.set_visible(False)
times = 0
score = 0
gameover = 0
运行这个代码就能反复玩游戏了。
到这里游戏看上去好了很多,但是还没有背景音乐,打地鼠的时候也没有音效,下一节我们继续添加声音。
<未完待续>
欢迎关注我的专栏( つ•̀ω•́)つ【人工智能通识】
每个人的智能新时代
如果您发现文章错误,请不吝留言指正;
如果您觉得有用,请点喜欢;
如果您觉得很有用,欢迎转载~
END