当前位置:   article > 正文

Python基础教程——用做一个童年经典flybird游戏!【完整教程】_python 做一个flybird 游戏

python 做一个flybird 游戏

今天我们用Python写一个十年前风靡一时的flybird小游戏。主要用到是pygame模块。这个拿来做游戏还是很方便。

在这里插入图片描述
游戏界面

1.设置好编码模式和导入所需的库。假如模块缺失的自行用pip命令安装一下缺失的模块。


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import random
import pygame
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.定义好全局变量,屏幕宽高、管道宽高、小鸟的宽高、地面的高度。这里我们使用长方体代替管道和小鸟。


# FPS
FPS = 30
# 屏幕宽高
SCREEN_WIDTH = 288
SCREEN_HEIGHT = 512
# 管道宽高
PIPE_WIDTH = 50
PIPE_HEIGHT = 300
# 管道之间空隙
PIPE_GAP_SIZE = 100
# 小鸟
BIRD_WIDTH = 20
BIRD_HEIGHT = 20
# 地面高度
FLOOR_HEIGHT = 80
# 游戏有效高度
BASE_HEIGHT = SCREEN_HEIGHT - FLOOR_HEIGHT
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3.定义好小鸟类,设置好初始的状态、更新小鸟的位置方法、上升、下落状态方法和绘制小鸟方法。


class Bird(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
        self.rect = pygame.Rect(*position, BIRD_WIDTH, BIRD_HEIGHT)
        # 定义飞行变量
        self.is_flapped = False
        self.up_speed = 10
        self.down_speed = 0
        self.time_pass = FPS / 1000

    # 更新小鸟的位置
    def update(self):
        # 判断小鸟是上升还是下降
        if self.is_flapped:
            # 上升速度越来越小
            self.up_speed -= 60 * self.time_pass
            self.rect.top -= self.up_speed
            # 上升速度小于等于0, 改为下降状态
            if self.up_speed <= 0:
                self.down()
                self.up_speed = 10
                self.down_speed = 0
        else:
            # 下降速度越来越大
            self.down_speed += 20 * self.time_pass
            self.rect.bottom += self.down_speed

        # 判断小鸟是否撞到了边界死亡
        is_dead = False
        if self.rect.top <= 0:  # 上边界
            self.up_speed = 0
            self.rect.top = 0
            is_dead = True

        if self.rect.bottom >= BASE_HEIGHT:  # 下边界
            self.up_speed = 0
            self.down_speed = 0
            self.rect.bottom = BASE_HEIGHT
            is_dead = True

        return is_dead

    # 下落状态
    def down(self):
        self.is_flapped = False

    # 上升状态
    def up(self):
        if self.is_flapped:
            self.up_speed = max(12, self.up_speed + 1)
        else:
            self.is_flapped = True

    def draw(self, screen):
        pygame.draw.rect(screen, (255, 255, 0), self.rect, 0)#设置小鸟的颜色,0代表填充,1代表无填充
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

4.定义好管道类,做好初始化和绘制方法。


class Pipe(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
        left, top = position
        # 如果是下边的管道, 通过定义管道高度, 删除地面以下的管道
        pipe_height = PIPE_HEIGHT
        if top > 0:
            pipe_height = BASE_HEIGHT - top + 1
        self.rect = pygame.Rect(left, top, PIPE_WIDTH, pipe_height)
        # 用于计算分数
        self.used_for_score = False

    def draw(self, screen):
        pygame.draw.rect(screen, (0, 255, 0), self.rect, 0)#设置管的颜色为绿色,0代表填充,1代表无填充

    @staticmethod
    def generate_pipe_position():
        # 生成上下两个管道的坐标
        top = int(BASE_HEIGHT * 0.2) + random.randrange(
            0, int(BASE_HEIGHT * 0.6 - PIPE_GAP_SIZE))
        return {
            'top': (SCREEN_WIDTH + 25, top - PIPE_HEIGHT),
            'bottom': (SCREEN_WIDTH + 25, top + PIPE_GAP_SIZE)
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

5.定义初始化游戏函数


# 初始化游戏
def init_game():
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption('Fly Bird游戏')
    return screen
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

6.定义初始化精灵函数


# 初始化精灵
def init_sprite():
    # 小鸟类
    bird_position = [SCREEN_WIDTH * 0.2, (SCREEN_HEIGHT - BIRD_HEIGHT) / 3]
    bird = Bird(bird_position)
    # 管道类
    pipe_sprites = pygame.sprite.Group()
    for i in range(2):
        pipe_pos = Pipe.generate_pipe_position()
        # 添加上方的管道
        pipe_sprites.add(
            Pipe((SCREEN_WIDTH + i * SCREEN_WIDTH / 2,
                  pipe_pos.get('top')[-1])))
        # 添加下方的管道
        pipe_sprites.add(
            Pipe((SCREEN_WIDTH + i * SCREEN_WIDTH / 2,
                  pipe_pos.get('bottom')[-1])))
    return bird, pipe_sprites
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

7.定义小鸟和管道碰撞检测函数


# 精灵类碰撞检测和小鸟更新位置
def collision(bird, pipe_sprites):
    # 检测碰撞
    is_collision = False
    for pipe in pipe_sprites:
        if pygame.sprite.collide_rect(bird, pipe):
            is_collision = True
    # 更新小鸟
    is_dead = bird.update()
    if is_dead:
        is_collision = True
    return is_collision
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

8.定义小鸟飞越管道函数,管道不断左移,实现小鸟往前飞效果。


# 移动pipe实现小鸟往前飞的效果
def move_pipe(bird, pipe_sprites, is_add_pipe, score):
    flag = False  # 下一次是否要增加新的pipe的标志位
    for pipe in pipe_sprites:
        pipe.rect.left -= 4
        # 小鸟飞过pipe 加分
        if pipe.rect.centerx < bird.rect.centerx and not pipe.used_for_score:
            pipe.used_for_score = True
            score += 0.5
        # 增加新的pipe
        if pipe.rect.left < 10 and pipe.rect.left > 0 and is_add_pipe:
            pipe_pos = Pipe.generate_pipe_position()
            pipe_sprites.add(Pipe(position=pipe_pos.get('top')))
            pipe_sprites.add(Pipe(position=pipe_pos.get('bottom')))
            is_add_pipe = False
        # 删除已不在屏幕的pipe, 更新标志位
        elif pipe.rect.right < 0:
            pipe_sprites.remove(pipe)
            flag = True
    if flag:
        is_add_pipe = True
    return is_add_pipe, score
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

9.定义绘制分数函数

# 画分数
def draw_score(screen, score):
    font_size = 32
    digits = len(str(int(score)))
    offset = (SCREEN_WIDTH - digits * font_size) / 2
    font = pygame.font.SysFont('Blod', font_size)
    screen.blit(font.render(str(int(score)), True, (255, 255, 255)),
                (offset, SCREEN_HEIGHT * 0.1))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

10.定义绘制游戏结束函数

# 画游戏结束
def draw_game_over(screen, text):
    font_size = 24
    font = pygame.font.SysFont("simhei", font_size)#设置字体和字号
    screen.blit(font.render(text, True, (255, 255, 255), (0, 0, 0)),
                (60, SCREEN_HEIGHT * 0.4))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

11.定义监听键盘空格按下函数。按下空格键或者up键小鸟网上飞。


# 按键
def press(is_game_running, bird):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # 点击关闭按钮退出
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE or event.key == pygame.K_UP:  # 空格键或者up键小鸟上升
                if is_game_running:
                    bird.up()
            elif event.key == 13 and not is_game_running:  # 游戏结束时回车键继续
                return True
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

12.定义游戏的主控函数,设置游戏图标,实例化精灵对象,组织游戏流程。


def main():
    img = pygame.image.load('./moneyge_icon.png')
    pygame.display.set_icon(img)
    screen = init_game()  # 初始化游戏
    bird, pipe_sprites = init_sprite()  # 初始化精灵
    clock = pygame.time.Clock()
    is_add_pipe = True  # 是否需要增加管道
    is_game_running = True  # 是否在游戏中
    score = 0  # 初始分数
    while True:
        restart = press(is_game_running, bird)  # 按键
        if restart:
            return
        screen.fill((100, 10, 10))  # 填充背景
        is_collision = collision(bird, pipe_sprites)  # 碰撞检测
        if is_collision:
            is_game_running = False  # 如果碰撞 游戏结束
        if is_game_running:
            is_add_pipe, score = move_pipe(bird, pipe_sprites, is_add_pipe,
                                           score)  # 不碰撞 移动管道
        else:
            draw_game_over(screen, '请按回车继续游戏!')  # 游戏结束
        bird.draw(screen)  # 画鸟
        draw_score(screen, score)  # 画分数
        # 画地面
        pygame.draw.line(screen, (0, 255, 255), (0, BASE_HEIGHT),
                         (SCREEN_WIDTH, BASE_HEIGHT))
        # 画管道
        for pipe in pipe_sprites:
            pipe.draw(screen)

        # 更新画布
        pygame.display.update()
        clock.tick(FPS)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

13.主函数入口调用游戏的主控函数,启动游戏。


if __name__ == "__main__":
    while True:
        main()
  • 1
  • 2
  • 3
  • 4

这样我们flybird小游戏就写好啦,大家可以自己研究一下试试看哦!

最后这里免费分享给大家一份Python学习资料,包含视频、源码。课件,希望能帮到那些不满现状,想提升自己却又没有方向的朋友,也可以和我一起来学习交流呀。
编程资料、学习路线图、源代码、软件安装包等!

看下方图片哦(掉落)↓↓↓

Python所有方向的学习路线图,清楚各个方向要学什么东西
100多节Python课程视频,涵盖必备基础、爬虫和数据分析
100多个Python实战案例,学习不再是只会理论
华为出品独家Python漫画教程,手机也能学习
历年互联网企业Python面试真题,复习时非常方便****

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/414467
推荐阅读
相关标签
  

闽ICP备14008679号