80+行代码实现简单的“飞行的小鸟”游戏(1)

上一篇 / 下一篇  2018-04-27 09:12:34 / 个人分类:博为峰原创技术文章

如果想尝试着用python做一款简单好玩的小游戏“飞行的小鸟”,那就得用到pygame这个模块,让我们先简单了解一下pygame吧。

     pygame是一个利用SDL全名Simple DirectMedia Layer写就的游戏库安装好python3境以后,可以用pip3 install pygame命令来安装pygame。pygame有很多的模我们这个游戏会用到以下模块:

    pygame主模块,一些通用的控制

    pygame.display用来访问显设备

    pygame.draw制形状,线和点

    pygame.rect管理矩形区域

    pygame.init初始化的一些定

    pygame.font使用字体

    pygame.time管理时间和帧信息

    另外因为游戏需要用到很多随机数,所以还需要random模块,也可以通过pip3命令安装。

既然是实现飞行的小鸟游戏,首先要有鸟和管子,这里我想通过类来分别定义小鸟和管子。小鸟和管子还要在屏幕上显示,所以这个屏幕的显示也是要定义的。首先看看这个屏幕的定义吧,下面是屏幕定义的代码和一些注释

pygame.init()
# 定义颜色
PIPE = (0,0,255)
SKY = (135,206,250)
BIRD = (220,20,60)
GROUND = (245,245,220)

# 设置游戏幕布大小
size = (800, 650)
screen = pygame.display.set_mode(size)
# 标题设置
pygame.display.set_caption("Flappy Block")
#字体设置
arial18 = pygame.font.SysFont('arial',18, False, False)
# 游戏未结束
done = False
# 时钟
clock = pygame.time.Clock()
# 游戏初始状态
gameState = 1 #未开始
pipes = []#定义管子的list

    pygame.init函数,初始化pygame模块,好让我们可以利用pygame的那些模块。比如pygame.font,pygame.draw等(上面列举到的模块)

    然后程序里定义各个对象的颜色,包括小鸟管子天空背景完了再设置游戏的屏幕大小。幕布左上角坐标是(0,0)设置了游戏的显示标题,还有字体。默认游戏是未开始的状态。gameState=1代表游戏初始未开始。pipes=[]管子是有序的,所以用list定义。

    现在来用类定义小鸟。python是强制缩进的,所以可以很清楚的看代码块一个代码块实现一定的逻辑。

# 定义小鸟
class Bird():
    def __init__(self):
        self.x = 250  # 小鸟x坐标
        self.y = 250  # 小鸟y坐标
        self.yV = 0   # 小鸟的位置初始化
    # 定义小鸟的下降振幅
    def flap(self):
        self.yV = -5  # 每次下降的位移
    # 定义小鸟的上升振幅和y周的上下边界
    def update(self):
        self.yV += 0.3  # 小鸟上升速度
        self.y += self.yV  # y轴位置等于原位置加yV振幅
    # 定义小鸟的飞行
    def draw(self):
        pygame.draw.rect(screen, BIRD, (self.x, self.y, 40, 40))#参数为(幕布,颜色,坐标,大小)
    # 重置小鸟
    def reset(self):
        self.x = 250
        self.y = 250
        self.yV = 0
bird = Bird()# 实例一个小鸟

    类class Bird()定义了小鸟。__init(self)__方法初始化了小鸟的位置等信息。注意这个self,在python语言里,类的方法,会有一个默认的参数,一般通用的都是用self表示,这个self是代表类的自身。flap方法定义了小鸟每次下降的位移。update方法定义了小鸟的上升。

draw方法

    通过调用pygame.draw.rect实现了小鸟的飞行。reset方法重置小鸟的位置。bird=Bird()是小鸟类的实例化。

下面来定义管子

# 定义管子
class Pipe():
    def __init__(self):
        self.centerY = random.randrange(180, 520)  # 管子的y轴中间值范围

(大数上面管子长,小数下面管子长)
        self.x = 800  # 管子的初始x轴位置
        self.size = 150  # 上下两个管子之间的空间宽度的一半
    # 更新管子
    def update(self):
        # 几个全局变量
        global pipes
        global bird
        global gameState
        self.x -= 4  # 管子的移动速度,因为小鸟其实没有动x轴的位移,小鸟其实是不前进的,只是上下跳动
        # 管子的初始位置
        if self.x == 300:
            pipes.append(Pipe())  # 显示一个新管子
        if self.x <= -100:
            del pipes[0]  # 删除一个不再显示的管子
        # 小鸟撞到管子,游戏结束,第一个条件是撞到下面的管子,第二个条件是撞到上面的管子(小鸟位置固定,管子在x轴运动)
        #小鸟的y轴位移小于管子的y轴范围减去中间空的部分
        #或者小鸟的y轴位移+40大于管子的y轴范围加上中间空的部分,40是小鸟的长度
        #则小鸟撞到管子,游戏结束
        if self.x >= 170 and self.x <= 290 and bird.y <= (self.centerY - self.size) \
                or self.x >= 170 and self.x <= 290 and (bird.y + 40) >= (self.centerY + self.size):
            gameState = 3  # 结束
            # 小鸟飞过管子,游戏继续,两个75等于size的150
        if self.x == 168 and bird.y > (self.centerY - 75) and bird.y < (self.centerY + 75):
            gameState = 2
        # 小鸟撞到地面,游戏结束
        if bird.y >= 610:
            gameState = 3
    # 定义管子的显示

    def draw(self):
        # 定义上面管子的显示(幕布,颜色,坐标,宽=80,长)
        pygame.draw.rect(screen, PIPE, (self.x, 0, 80, (self.centerY - self.size)))
        # 定义下面管子的显示
        pygame.draw.rect(screen, PIPE, (self.x, (self.centerY + self.size), 80, (548 - self.centerY)))
# 实例化管子,显示新管子
pipes.append(Pipe())

    管子的这个类,我们说说和小鸟不一样的地方。update方法实现了管子的更新显示。注意globalglobal使参数全局化。管子的移动是self.x=4说明管子是从右向左运动,速率是4。(所以这个游戏里,其实是管子在左右动,而小鸟其实只是上下动,没有进行x轴的运动)。

    pipes.append(Pipe())是列表调用类,列表的append方法,是给列表里插入一个新的元素。这里代表显示(插入)一个新管子。del pipes[0]列表中0代表第一个元素的位置,也就是删掉第一个管子(管子不再显示)

    小鸟碰到管子


if self.x >= 170 and self.x <= 290 \ #管子的位置在120-290之间

 and bird.y <= (self.centerY - self.size) \#并且小鸟的身体碰到了上面的管子
        or self.x >= 170 and self.x <= 290 and (bird.y + 40) >= (self.centerY + self.size):#小鸟的身体碰到了下面的管子

    gameState = 3  # 结束

    小鸟飞过管子

# 小鸟飞过管子,游戏继续,两个75等于self.size的150
if self.x == 168 and bird.y > (self.centerY - 75) and bird.y < (self.centerY + 75):
    gameState = 2

    管子的x轴位置168,表示穿过了。而且小鸟刚好在两个管子的空间self.size里。

    实现管子的显示

# 定义管子的显示
    def draw(self):
        # 定义上面管子的显示(幕布,颜色,坐标,宽=80,长)
        pygame.draw.rect(screen, PIPE, (self.x, 0, 80, (self.centerY - self.size)))
        # 定义下面管子的显示
        pygame.draw.rect(screen, PIPE, (self.x, (self.centerY + self.size), 80, (548 - self.centerY)))
# 实例化管子,显示新管子
pipes.append(Pipe())

现在看一下游戏的具体实现。

    游戏要有控制键,设置为空格键控制。游戏结束要退出,用QUIT方法。游戏有三个状态

    1:未开始2:进行中3:结束

    首先游戏未开始时,点击空格键可以开始游戏,游戏结束以后,可以重新开始游戏,这需要重置小鸟和管子。游戏运行中的小鸟和管子,就是刷新显示小鸟和管子。

    还需要定义一下游戏开始的按钮显示


TAG:

 

评分:0

我来说两句

日历

« 2024-04-26  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 34101
  • 日志数: 43
  • 建立时间: 2018-01-25
  • 更新时间: 2018-11-09

RSS订阅

Open Toolbar