最近接触到了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)
至此,整个游戏的基本功能已经实现,我还进行了一些细节上的调整,比如加入了开始界面和结束界面。来看看最终的效果吧!
感谢阅读!如果需要整个源码,请戳戳我!