前言

在之前的代码中,我们已经实现了一个用Pygame搭建FlappyBird的基本框架,其最终生成效果如下:

【FlappyBird小游戏】编写游戏逻辑(三)——添加Bird和Pipe【源码】_游戏开发

现在我们添加继续添加Bird和Pipe对象,让该游戏看起来更加完整。


1、添加Pipe对象

(1)初始化

在Flappy_Bird_Env的init中添加如下变量的初始化:

    # 管道图片相关设置
    self.pipeVelX = -4 # 管道移动速度
    self.PIPEGAPSIZE = 100  # 上下管道之间的间距
    self.PIPE_WIDTH = self.IMAGES['pipe'][0].get_width()
    self.PIPE_HEIGHT = self.IMAGES['pipe'][0].get_height()

(2)重置

获取一个随机管道的位置信息:

    def getRandomPipe(self):
        """随机获取一个管道的x和y的参数"""
        # 随机获取一个管道间距距离
        gapYs = [20, 30, 40, 50, 60, 70, 80, 90] #上管道的y坐标
        index = random.randint(0, len(gapYs) - 1)
        gapY = gapYs[index]
 
        gapY += int(self.BASEY * 0.2)
        pipeX = SCREENWIDTH + 10
 
        return [
            {'x': pipeX, 'y': gapY - self.PIPE_HEIGHT},  # 上管道
            {'x': pipeX, 'y': gapY + self.PIPEGAPSIZE},  # 下管道
        ]

在reset函数中继续写管道的初始信息,reset被Flappy_Bird_Env的init调用:

    def reset(self):
        # 获取2个新的pipes
        newPipe1 = self.getRandomPipe()
        newPipe2 = self.getRandomPipe()
        # 屏幕显示的上管道列表
        self.upperPipes = [
            {'x': SCREENWIDTH, 'y': newPipe1[0]['y']}, # 屏幕上第1个管道
            {'x': SCREENWIDTH + (SCREENWIDTH / 2), 'y': newPipe2[0]['y']},# 屏幕上第2个管道
        ]
        # 屏幕显示的下管道列表
        self.lowerPipes = [
            {'x': SCREENWIDTH, 'y': newPipe1[1]['y']},
            {'x': SCREENWIDTH + (SCREENWIDTH / 2), 'y': newPipe2[1]['y']},
        ]

(3)帧渲染

首先计算每个管道的位置:

# 计算上下管道的x坐标
        for uPipe, lPipe in zip(self.upperPipes, self.lowerPipes):
            uPipe['x'] += self.pipeVelX
            lPipe['x'] += self.pipeVelX
 
        # 如果第一个管道的x坐标小于5但是大于0时提前生成一个新管道到列表中
        if 0 < self.upperPipes[0]['x'] < 5:
            newPipe = self.getRandomPipe()
            self.upperPipes.append(newPipe[0])
            self.lowerPipes.append(newPipe[1])
 
        # 如果第一个管道的x坐标完全离开管道时就将其移除
        if self.upperPipes[0]['x'] < -self.PIPE_WIDTH:
            self.upperPipes.pop(0)
            self.lowerPipes.pop(0)

渲染管道图片,注意渲染顺序:

        # 绘制背景图像
        self.screen.blit(self.IMAGES['background'], (0, 0))  # 背景,元组参数表示绘制位置,也可以通过Rect矩形类来表示位置
        # 绘制上下管道图像
        for uPipe, lPipe in zip(self.upperPipes, self.lowerPipes):
            self.screen.blit(self.IMAGES['pipe'][0], (uPipe['x'], uPipe['y']))
            self.screen.blit(self.IMAGES['pipe'][1], (lPipe['x'], lPipe['y']))
        # 绘制地面图像
        self.screen.blit(self.IMAGES['base'], (self.BASEX, self.BASEY))  # 地面

(4)实现效果

最终我们的实现效果就是:

【FlappyBird小游戏】编写游戏逻辑(三)——添加Bird和Pipe【源码】_游戏开发_02

2、添加Bird对象

由于Bird比较复杂,所以我们要将其单独初始化为一个类

(1)初始化

class Bird(object):
    def __init__(self,_Player_Sprite,_screen):
        self.screen = _screen
        # 玩家图片相关设置
        self.Player_Sprite = _Player_Sprite # 加载图片资源
        self.PlayerInfo = {} # 创建一个玩家信息字典
        self.PlayerInfo['w'] = self.Player_Sprite[0].get_width() # 获取玩家图片的宽度
        self.PlayerInfo['h'] = self.Player_Sprite[0].get_height()  # 获取玩家图片的高度
        self.PLAYER_INDEX_GEN = cycle([0, 1, 2, 1]) # 图片序列的循环
        self.playerMaxVelY = 10  # 玩家在y轴上的最大速度
        self.playerMinVelY = -8  # 玩家在y轴上的最小速度
        self.playerAccY = 1  # 玩家在y轴上的下降的加速度
        self.playerFlapAcc = -7  # 玩家在y轴上的上升的加速度,向下为正方向
        # 重置游戏设置w
        self.reset()

(2)重置

重置游戏时Bird的调用函数:

    def reset(self):
        self.loopIter = 0
        self.PlayerInfo['x'] = int(SCREENWIDTH * 0.2)  # 玩家初始位置x
        self.PlayerInfo['y'] = int((SCREENHEIGHT - self.PlayerInfo['h']) / 2)  # 玩家初始位置y
        self.PlayerInfo['index'] = 0 # 玩家初始帧序列
        self.playerVelY = 0  # 玩家在y轴上的速度,向下为正方向
        self.playerFlapped = False  # 玩家是否上升

(3)帧渲染

我们在每帧中渲染的Bird图片是不一样的,这样就可以实现小鸟的动画效果:

    def frame_step(self, input_actions,BASEY):
        # 计算玩家序列帧
        if (self.loopIter + 1) % 3 == 0:
            self.PlayerInfo['index'] = next(self.PLAYER_INDEX_GEN)
        self.loopIter = (self.loopIter + 1) % 30
        # 绘制玩家图像
        self.screen.blit(self.Player_Sprite[self.PlayerInfo['index']],
                         (self.PlayerInfo['x'], self.PlayerInfo['y']))  # 玩家

(4)实现效果

最终我们的实现效果就是:

【FlappyBird小游戏】编写游戏逻辑(三)——添加Bird和Pipe【源码】_游戏开发_03图片来源:http://www.lyouxi.com/  手游