0%

利用pygame开发一款游戏:「跳跳兔」(八)

处理私事,拖更许久,抱歉抱歉。

前言

在第七节中,实现了玩家对象的动画效果以及平台的图片化。

本节将细节优化一下,然后加上相应的配音。

细节优化

如果你有仔细的试玩第七节实现的跳跳兔,会发现一些瑕疵,这里简单修改一下。

瑕疵1:跳跳兔会平移。

造成该现象的代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# main.py/Game

def update(self):
self.all_sprites.update()
# # 玩家在界面中时(y>0),进行碰撞检测,检测玩家是否碰撞到平台
if self.player.vel.y > 0:
hits = pg.sprite.spritecollide(self.player, self.platforms, False)

# 会产生平移效果
if hits:
self.player.pos.y = hits[0].rect.top
self.player.vel.y = 0

...# 省略其他无关代码

在update()方法检查碰撞检测时,如果发生了碰撞,就直接将hits列表中第一个元素赋值给player玩家对象,从而造成了跳跳兔本身没有跳跃,只是碰到了平台周围,就瞬移到上一个平台的效果。

代码进行如下修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# main.py/Game

def update(self):
self.all_sprites.update()
# # 玩家在界面中时(y>0),进行碰撞检测,检测玩家是否碰撞到平台
if self.player.vel.y > 0:
hits = pg.sprite.spritecollide(self.player, self.platforms, False)

if hits:
lowest = hits[0]
for hit in hits:
if hit.rect.bottom > lowest.rect.bottom:
lowest = hit # 保存最小的值
# 避免平移效果 - 兔子最底部没有小于碰撞检测中的最小值,则不算跳跃到平台上
if self.player.pos.y < lowest.rect.centery:
self.player.pos.y = lowest.rect.top
self.player.vel.y = 0
self.player.jumping = False

...# 省略其他无关代码

发送碰撞时,要进一步判断,先获得碰撞时,碰撞对象hit底部的最小值,然后判断此时玩家对象的位置y轴坐标是否要小于lowest对象的中心位置,如果小于,则说明玩家对象在lowest之上,此时才移动玩家对象。

瑕疵2:跳跃太高,可玩性低

简单点击空格,跳跳兔就可以跳很高,让游戏变得简单无趣,这里加多些逻辑,实现短跳与长跳。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# sprites.py/Player

# 短跳
def jump_cut(self):
if self.jumping:
if self.vel.y < -3:
self.vel.y = -3

def jump(self):
# 跳跃到其他平台 - 玩家对象x加减1,为了做碰撞检测,只有站立在平台上,才能实现跳跃
self.rect.y += 2
hits = pg.sprite.spritecollide(self, self.game.platforms, False)
self.rect.y -= 2
if hits and not self.jumping:
self.jumping = True
self.vel.y = -20

通过self.jumping判断当前是否在跳跃状态,如果在跳跃状态,就将y轴速度砍到3。此外jump()方法也做了修改,通过y轴来判断是否产生碰撞检测,如果发生了碰撞而且又是没有跳跃的状态,这说明跳跳兔在平台上,可以进行跳跃,将self.jumping跳跃标志设为True。

你可能会疑惑,不慌,结合下面代码一起看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# main.py/Game

# 事件处理
def events(self):
for event in pg.event.get():
# 关闭
if event.type == pg.QUIT:
if self.playing:
self.playing = False
self.running = False
# 跳跃
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
self.player.jump()
# 按钮抬起,减小跳跃速度,从而实现,快速点击,短跳,长按,长跳的效果
if event.type == pg.KEYUP:
if event.key == pg.K_SPACE:
self.player.jump_cut()

简单而言,如果长按空格键进行跳跃,就只会有jump()方法的效果,跳跃快结束时,才松开空格,此时jump_cut()方法已经没有明显的作用了。

如果简单快击空格键,此时跳跃还未完成,jump_cut()又被调用,跳跳兔y轴速度会被减弱,从而实现短跳的效果。

增加背景音乐

在pygame中,操作音乐是非常简单的,无论多大的音乐文件都可以被pygame以流的形式读入并播放。

跳跳兔游戏在不同的状态要播放不同状态的音乐。

在Game/load_data()方法中加载音频文件夹。

1
2
3
4
5
6
7
8
9
# main.py/Game

def load_data(self): # 加载数据
...
# 加载精灵图片
self.spritesheet = Spritesheet(os.path.join(img_dir, SPRITESHEET))
# 加载音乐
self.snd_dir = os.path.join(self.dir, 'snd')
self.jump_sound = pg.mixer.Sound(os.path.join(self.snd_dir, 'Jump33.wav')) # 玩家对象跳跃时的音乐

新建游戏时,加载游戏初始音乐,此外游戏结束时,也使用同样的音乐,逻辑如下。

1
2
3
4
5
6
7
8
9
10
11
# main.py/Game

# 开始游戏的钩子函数
def show_start_screen(self):
# 加载音乐
pg.mixer.music.load(os.path.join(self.snd_dir, 'Yippee.ogg'))
# 重复播放
pg.mixer.music.play(loops=-1)
... # 其他逻辑,省略
# 退出音乐
pg.mixer.music.fadeout(500)

通过pygame.mixer.music.load()方法可以将音乐加载到磁盘中,然后调用play()方法播放,其中loops参数用于指定循环播放次数,-1表示一直循环播放,当需要退出音乐时,滴啊用fadeout()方法,退出音乐,fadeout(time)设置音乐淡出的时间,该方法会阻塞到音乐消失。

游戏结束方法逻辑与show_start_screen()一致,不再展示代码分析。

游戏的过程中以同样的方式加载音乐作为游戏的背景音乐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def new(self):
...
# 游戏初始时音乐
pg.mixer.music.load(os.path.join(self.snd_dir, 'Happy Tune.ogg'))
self.run()

def run(self):
# loops表示循环次数,-1表示音乐将无限播放下去
pg.mixer.music.play(loops=-1)
self.playing = True
while self.playing:
self.clock.tick(FPS)
self.events()
self.update()
self.draw()
# 退出后停止音乐,fadeout(time)设置音乐淡出的时间,该方法会阻塞到音乐消失
pg.mixer.music.fadeout(500)

最后,为跳跃动作加上相应的音乐。

1
2
3
4
5
6
7
8
9
10
11
# sprites.py/Player

def jump(self):
# 跳跃到其他平台 - 玩家对象x加减1,为了做碰撞检测,只有站立在平台上,才能实现跳跃
self.rect.y += 2
hits = pg.sprite.spritecollide(self, self.game.platforms, False)
self.rect.y -= 2
if hits and not self.jumping:
self.game.jump_sound.play() # 播放跳跃的声音
self.jumping = True
self.vel.y = -20

在本节中,我们对「跳跳兔」进行了简单的优化,然后为游戏中不同的状态添加不同的音乐。

因为考虑到篇幅,文中没有给出完整的代码,但为了方便大家理解,我将相应的代码上传到了github,图片资源与音乐资源也在github上。

https://github.com/ayuLiao/jumprabbit

如果文章对你有帮助或你觉得有点意思,点击「在看」支持作者一波。