重做一波之前的 flappybird
导语
因为疫情无奈只能在家宅了好多天,随手玩了下自己以前做的一些小游戏,说真的,有几个游戏做的是真的劣质,譬如 flappybird 真的让我难以忍受,于是重做了一波分享给大家~
日常题外话:目前这情况小伙伴们一定要好好的呀,分享张图给你们~
开发工具
Python 版本: 3.6.4
相关模块:
pygame 模块;
以及一些 python 自带的模块
环境搭建
安装 Python 并添加到环境变量,pip 安装需要的相关模块即可。
先睹为快
在 cmd 窗口运行如下命令即可:
python Game6.py
原理简介
因为是重写的,所以就重新介绍一下实现原理呗。
首先,我们来写个开始界面,让他看起来更像个游戏一些。效果大概是这样的:
原理也简单,关键点有三个:(1)下方深绿浅绿交替的地板不断往左移动来制造小鸟向前飞行的假象;(2)每过几帧切换一下小鸟的图片来实现小鸟翅膀扇动的效果:
(3)有规律地改变小鸟竖直方向上的位置来实现上下移动的效果。
具体而言,代码实现如下:
python
'''显示开始界面'''
def startGame(screen, sounds, bird_images, other_images, backgroud_image, cfg):
base_pos = [0, cfg.SCREENHEIGHT*0.79]
base_diff_bg = other_images['base'].get_width() - backgroud_image.get_width()
msg_pos = [(cfg.SCREENWIDTH-other_images['message'].get_width())/2, cfg.SCREENHEIGHT*0.12]
bird_idx = 0
bird_idx_change_count = 0
bird_idx_cycle = itertools.cycle([0, 1, 2, 1])
bird_pos = [cfg.SCREENWIDTH*0.2, (cfg.SCREENHEIGHT-list(bird_images.values())[0].get_height())/2]
bird_y_shift_count = 0
bird_y_shift_max = 9
shift = 1
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE or event.key == pygame.K_UP:
return {'bird_pos': bird_pos, 'base_pos': base_pos, 'bird_idx': bird_idx}
sounds['wing'].play()
bird_idx_change_count += 1
if bird_idx_change_count % 5 == 0:
bird_idx = next(bird_idx_cycle)
bird_idx_change_count = 0
base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg)
bird_y_shift_count += 1
if bird_y_shift_count == bird_y_shift_max:
bird_y_shift_max = 16
shift = -1 * shift
bird_y_shift_count = 0
bird_pos[-1] = bird_pos[-1] + shift
screen.blit(backgroud_image, (0, 0))
screen.blit(list(bird_images.values())[bird_idx], bird_pos)
screen.blit(other_images['message'], msg_pos)
screen.blit(other_images['base'], base_pos)
pygame.display.update()
clock.tick(cfg.FPS)
点击空格键或者 ↑ 键进入主程序。对于主程序,在进行了必要的初始化工作之后,在游戏开始界面中实现的内容的基础上,主要还需要实现的内容有以下几个部分:
(1) 管道和深绿浅绿交替的地板不断往左移来实现小鸟向前飞行的效果;
(2) 按键检测,当玩家点击空格键或者 ↑ 键时,小鸟向上做加速度向下的均减速直线运动直至向上的速度衰减为 0,否则小鸟做自由落体运动(实现时为了方便,可以认为在极短的时间段内小鸟的运动方式为匀速直线运动);
(3) 碰撞检测,当小鸟与管道/游戏边界碰撞到时,游戏失败并进入游戏结束界面。注意,为了碰撞检测更精确,我们使用:
pygame.sprite.collide_mask
来代替之前的:
pygame.sprite.collide_rect
(4) 进入游戏后,随机产生两对管道,并不断左移,当最左边的管道快要因为到达游戏界面的左边界而消失时,重新生成一对管道(注意不要重复生成);
(5) 当小鸟穿越一个上下管道之间的缺口时,游戏得分加一(注意不要重复记分)。
这里简单贴下主程序的源代码吧:
```python
进入主游戏
score = 0 bird_pos, base_pos, bird_idx = list(game_start_info.values()) base_diff_bg = other_images['base'].get_width() - backgroud_image.get_width() clock = pygame.time.Clock()
--管道类
pipe_sprites = pygame.sprite.Group() for i in range(2): pipe_pos = Pipe.randomPipe(cfg, pipe_images.get('top')) pipe_sprites.add(Pipe(image=pipe_images.get('top'), position=(cfg.SCREENWIDTH+200+i cfg.SCREENWIDTH/2, pipe_pos.get('top')[-1]))) pipe_sprites.add(Pipe(image=pipe_images.get('bottom'), position=(cfg.SCREENWIDTH+200+i cfg.SCREENWIDTH/2, pipe_pos.get('bottom')[-1])))
--bird类
bird = Bird(images=bird_images, idx=bird_idx, position=bird_pos)
--是否增加pipe
is_add_pipe = True
--游戏是否进行中
is_game_running = True while is_game_running: for event in pygame.event.get(): if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE or event.key == pygame.K_UP: bird.setFlapped() sounds['wing'].play() # --碰撞检测 for pipe in pipe_sprites: if pygame.sprite.collide_mask(bird, pipe): sounds['hit'].play() is_game_running = False # --更新小鸟 boundary_values = [0, base_pos[-1]] is_dead = bird.update(boundary_values, float(clock.tick(cfg.FPS))/1000.) if is_dead: sounds['hit'].play() is_game_running = False # --移动base实现小鸟往前飞的效果 base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg) # --移动pipe实现小鸟往前飞的效果 flag = False for pipe in pipe_sprites: pipe.rect.left -= 4 if pipe.rect.centerx < bird.rect.centerx and not pipe.used_for_score: pipe.used_for_score = True score += 0.5 if '.5' in str(score): sounds['point'].play() if pipe.rect.left < 5 and pipe.rect.left > 0 and is_add_pipe: pipe_pos = Pipe.randomPipe(cfg, pipe_images.get('top')) pipe_sprites.add(Pipe(image=pipe_images.get('top'), position=pipe_pos.get('top'))) pipe_sprites.add(Pipe(image=pipe_images.get('bottom'), position=pipe_pos.get('bottom'))) is_add_pipe = False elif pipe.rect.right < 0: pipe_sprites.remove(pipe) flag = True if flag: is_add_pipe = True # --绑定必要的元素在屏幕上 screen.blit(backgroud_image, (0, 0)) pipe_sprites.draw(screen) screen.blit(other_images['base'], base_pos) showScore(screen, score, number_images) bird.draw(screen) pygame.display.update() clock.tick(cfg.FPS) ```
游戏结束后,进入游戏界面。没找到对应的游戏素材,所以只是让游戏界面静止了,然后小鸟做自由落体运行直到掉到地面上。代码实现如下:
```python
'''游戏结束界面''' def endGame(screen, sounds, showScore, score, number_images, bird, pipe_sprites, backgroud_image, other_images, base_pos, cfg): sounds['die'].play() clock = pygame.time.Clock() while True: for event in pygame.event.get(): if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE or event.key == pygame.K_UP: return boundary_values = [0, base_pos[-1]] bird.update(boundary_values, float(clock.tick(cfg.FPS))/1000.) screen.blit(backgroud_image, (0, 0)) pipe_sprites.draw(screen) screen.blit(other_images['base'], base_pos) showScore(screen, score, number_images) bird.draw(screen) pygame.display.update() clock.tick(cfg.FPS) ```
再点击一下空格键或者 ↑ 键即可重新开始游戏。
All done ~完整源代码详见相关文件~
代码截止 2020-01-27 测试无误。
参考文献
- 豆玩手机游戏平台的设计与实现(吉林大学·李天明)
- 基于J2EE的协同益智游戏的研究(华北电力大学(北京)·郭晶晶)
- 豆玩手机游戏平台的设计与实现(吉林大学·李天明)
- 网页游戏平台的管理与设计(哈尔滨师范大学·苏润泽)
- 基于轻量级J2EE的网络游戏虚拟物品交易系统的设计与实现(北京邮电大学·曹鹃)
- 基于轻量级J2EE的网络游戏虚拟物品交易系统的设计与实现(北京邮电大学·曹鹃)
- 豆玩手机游戏平台的设计与实现(吉林大学·李天明)
- 网页游戏平台的管理与设计(哈尔滨师范大学·苏润泽)
- 基于.NET自定义控件的社区网站系统研究与实现(武汉理工大学·刘亚)
- 基于Virtools的四则运算三维教育游戏的设计与开发(四川师范大学·马泽)
- 基于B/S结构的实盘训练营系统的设计与实现(华中科技大学·刘喆)
- 网页游戏平台的管理与设计(哈尔滨师范大学·苏润泽)
- 基于B/S结构的实盘训练营系统的设计与实现(华中科技大学·刘喆)
- 基于SSH架构的个人空间交友网站的设计与实现(北京邮电大学·隋昕航)
- 基于B/S架构的酷跑社区系统的设计与实现(内蒙古大学·张晓乐)
本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:源码工坊 ,原文地址:https://bishedaima.com/yuanma/36045.html