pygame初探:复刻小游戏《Flappy Bird》

最近接触到了python里面的pygame模块,可以用来写一些很有意思的小游戏,我稍微了解了一些pygame 里面常用的方法,然后自己写了一个简陋版的flappy bird,整个代码大概两百行不到,接下来浅浅做一个代码解读。

flappy bird 里面有两样主要的元素:小鸟和柱子。我对它们分别建了一个类。

小鸟类如下:

class Bird:
    def __init__(self,screen):
        self.size=[30,30]
        self.location=[385,285]
        self.speed=1
        self.image=pygame.image.load('小鸟.png')
        self.image=pygame.transform.scale(self.image,(self.size[0],self.size[1]))
        self.imageRect=self.image.get_rect()
        self.imageRect=self.imageRect.move(self.location[0],self.location[1])
        screen.blit(self.image,self.imageRect)
        self.screen=screen

小鸟类的属性有它的大小、位置、速度和对应的图像。在构造函数里,我在游戏屏幕上绘制了小鸟的初始图像。

然后是柱子类:

class Pillar:
    def __init__(self):
        self.width=70
        self.color=27,190,72
        self.position=[pygame.display.Info().current_w,0]
        self.upPillarHeight=random.randint(150,400)
        self.gapHeight=random.randint(80,150)
        self.downPillarHeight=pygame.display.Info().current_h-self.upPillarHeight-self.gapHeight
        self.speed=1

柱子类的属性有它的大小、位置、颜色,由于在flappy bird 中,柱子总是上下两段成对出现,我让每一对柱子都作为一个单独的对象,给它们随机一个上下柱子的高度和中间空隙的高度。另外在游戏中,小鸟在往前飞,也可以理解为柱子在往后倒退,所以我将小鸟的水平速度设为0,并且给柱子赋予一个水平向左的速度。

定义完了两个类,接下来进入游戏的主要逻辑。

首先是游戏的初始化,我写了一个这样的方法:

def initGame():
    pygame.init()
    screen=pygame.display.set_mode(windowSize)
    pygame.display.set_caption('Flappy Bird')
    pygame.key.set_repeat(1,2)

游戏的初始化需要调用pygame.init()方法,然后用pygame.display.set_mode()方法来设置游戏窗口的大小,用set_caption方法来设置游戏标题。pygame.key.set_repeat()方法是用来让键盘在被持续按下时游戏可以持续响应。 

然后需要建立小鸟和柱子对象。由于在游戏中柱子是不断刷新的,我使用了一个列表来存储当前有效的柱子。

bird=Bird(screen)
pillarList=[]
pillarList.append(Pillar())
pillarList.append(Pillar())

接下来用while(True)使游戏不断地运行起来。在每一轮循环里,需要使小鸟和柱子进行相应的移动。两者的移动代码是相似的,所以我只展示小鸟类的移动方法:

    def move(self,screen):
        BLACK=0,0,0
        pygame.draw.rect(screen, BLACK, (self.location[0], self.location[1], self.size[0], self.size[1]))
        if self.location[1]==0 and self.speed<0:
            self.speed=-self.speed
        self.location[1]+=self.speed
        self.imageRect=self.imageRect.move(0,self.speed)
        screen.blit(self.image,self.imageRect)

如果小鸟速度为正,则向下移动,为负则向上移动。实现小鸟的移动只需要将小鸟的原位置涂成背景色(在这里是黑色),然后改变小鸟的位置,并且在新的位置重新绘制小鸟图像。

我设定柱子列表中只有两个柱子,在前面的一个柱子从屏幕上消失后,就将其从列表中删除,并且添加新的柱子。

if pillarList[0].getPosition()+pillarList[0].width<0:
    pillarList.remove(pillarList[0])
    pillarList.append(elements.Pillar())

在原版游戏中,我们可以看到对键盘不做任何操作时小鸟会往下掉,如果按下键盘小鸟则会向上飞。下面这段代码通过改变小鸟的速度方向实现了这个功能。

        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                sys.exit()
            if event.type==pygame.KEYDOWN:
                if event.key==pygame.K_SPACE:
                    bird.setNegativeSpeed()
            if event.type==pygame.KEYUP:
                bird.setPositiveSpeed()

小鸟类中的setNegativeSpeed()和setPositiveSpeed()方法即用来将小鸟速度设置成负或正,非常简单,这里不再展示。

现在我们已经让小鸟和柱子运动起来,整个游戏的雏形就搭好了。接下来需要做的是判断小鸟撞到地上或者撞到柱子上的情况,以结束游戏。

#判断是否撞上柱子       
for pillar in pillarList:
            if bird.touchPillar(pillar):
                bird.setZeroSpeed()
                for p in pillarList:
                    p.setZeroSpeed()
                font.render_to(screen,(100,250),'Oops! You ran into the pillar!',fgcolor=fontColor)
                font.render_to(screen,(90,320),'Press [R] to restart the game.',fgcolor=fontColor)


#判断是否撞到地上
        if bird.touchGround():
            bird.setZeroSpeed()
            for p in pillarList:
                p.setZeroSpeed()
            font.render_to(screen, (50, 250), 'Oops! You dropped on the ground!', fgcolor=fontColor)
            font.render_to(screen, (90, 320), 'Press [R] to restart the game.', fgcolor=fontColor)

至此,整个游戏的基本功能已经实现,我还进行了一些细节上的调整,比如加入了开始界面和结束界面。来看看最终的效果吧!

 感谢阅读!如果需要整个源码,请戳戳我!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值