用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - python代码库

像素鸟(笨鸟先飞)

2021-09-30 作者: python学习者举报

[python]代码库

import os
import random
import pygame

W, H = 288, 512
FPS = 30
IMAGE_PATH = "./assets/sprites/"
AUDIO_PATH = "./assets/audio/"

pygame.init()
pygame.mixer.init()
SCREEN = pygame.display.set_mode((W, H))
pygame.display.set_caption("Flappy Bird")
CLOCK = pygame.time.Clock()

IMAGE = {}
for image in os.listdir(IMAGE_PATH):
    name, extension = os.path.splitext(image)
    path = os.path.join(IMAGE_PATH, image)
    IMAGE[name] = pygame.image.load(path)

FLOOR_Y = H - IMAGE["floor"].get_height()

AUDIO = {}
for audio in os.listdir(AUDIO_PATH):
    name, extension = os.path.splitext(audio)
    path = os.path.join(AUDIO_PATH, audio)
    AUDIO[name] = pygame.mixer.Sound(path)


def main():
    """游戏主函数"""
    # 播放开始音效
    AUDIO["start"].play()

    IMAGE["bgpic"] = IMAGE[random.choice(["day", "night"])]
    color = random.choice(["red", "blue", "yellow"])
    IMAGE["birds"] = [IMAGE[color+"-up"], IMAGE[color+"-mid"], IMAGE[color+"-down"]]
    pipe = IMAGE[random.choice(["green-pipe", "red-pipe"])]
    IMAGE["pipes"] = [pipe, pygame.transform.flip(pipe, False, True)]

    # 显示窗口
    menu_window()
    result = game_window()
    end_window(result)


def menu_window():
    """控制游戏菜单窗口函数"""
    floor_x = 0
    floor_gap = W - IMAGE["floor"].get_width()

    guide_x = (W - IMAGE["guide"].get_width()) / 2
    guide_y = (H - IMAGE["guide"].get_height()) / 2

    bird_x = W * 0.2
    bird_y = (H - IMAGE["birds"][0].get_width()) / 2 + 53
    bird_y_val = 1
    bird_y_range = [bird_y - 8, bird_y + 8]

    idx = 0
    repeat = 5
    frames = [0] * repeat + [1] * repeat + [2] * repeat + [1] * repeat

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    quit()
                if event.key == pygame.K_SPACE:
                    return

        floor_x -= 4
        if floor_x <= floor_gap:
            floor_x = 0

        bird_y += bird_y_val
        if bird_y < bird_y_range[0] or bird_y > bird_y_range[1]:  # 不让小鸟移出规定范围
            bird_y_val *= -1

        idx += 1
        idx %= len(frames)

        SCREEN.blit(IMAGE["bgpic"], (0, 0))
        SCREEN.blit(IMAGE["floor"], (floor_x, FLOOR_Y))
        SCREEN.blit(IMAGE["guide"], (guide_x, guide_y))
        SCREEN.blit(IMAGE["birds"][frames[idx]], (bird_x, bird_y))
        pygame.display.update()
        CLOCK.tick(FPS)


def game_window():
    """控制游戏进行函数"""
    AUDIO["flap"].play()

    score = 0 

    floor_x = 0
    floor_gap = W - IMAGE["floor"].get_width()

   
    bird = Bird(W * 0.2, H * 0.4)


    pipe_group = pygame.sprite.Group()
    distance = 150
    n_pairs = 4
    pipe_gap = 100
    for i in range(n_pairs):
        pipe_y = random.randint(int(H*0.3), int(H*0.7))
        pipe_up = Pipe(W + i * distance, pipe_y)
        pipe_down = Pipe(W + i * distance, pipe_y - pipe_gap, False)
        pipe_group.add(pipe_up)
        pipe_group.add(pipe_down)

    while True:
        flap = False
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    quit()
                if event.key == pygame.K_SPACE:
                    AUDIO["flap"].play()
                    flap = True  # 向上飞

        floor_x -= 4
        if floor_x <= floor_gap:  # 不让地面移出屏幕
            floor_x = 0

        first_pipe_up = pipe_group.sprites()[0]
        first_pipe_down = pipe_group.sprites()[1]
        if first_pipe_up.rect.right < 0:
            pipe_y = random.randint(int(H * 0.3), int(H * 0.75))
            new_pipe_up = Pipe(first_pipe_up.rect.x + n_pairs * distance, pipe_y)
            new_pipe_down = Pipe(first_pipe_down.rect.x + n_pairs * distance, pipe_y - pipe_gap, False)
            pipe_group.add(new_pipe_up)
            pipe_group.add(new_pipe_down)
            first_pipe_up.kill()
            first_pipe_down.kill()

        # 更新角色状态
        bird.update(flap)  # 小鸟飞行动作切换
        pipe_group.update()  # 水管移动

        # 碰撞检测
        if bird.rect.y > FLOOR_Y or bird.rect.y < 0 or \
                pygame.sprite.spritecollideany(bird, pipe_group):
            AUDIO["hit"].play()
            AUDIO["die"].play()
            bird.dying = True
            result = {"bird": bird, "pipe_group": pipe_group, "score": score}

            return result

        if bird.rect.left + first_pipe_up.x_val < first_pipe_up.rect.centerx < bird.rect.left:
            AUDIO["score"].play()
            score += 1

        SCREEN.blit(IMAGE["bgpic"], (0, 0))
        pipe_group.draw(SCREEN)
        SCREEN.blit(IMAGE["floor"], (floor_x, FLOOR_Y))

        show_score(score)

        SCREEN.blit(bird.image, bird.rect)
        pygame.display.update()
        CLOCK.tick(FPS)


def end_window(result):
    """控制游戏结束窗口函数"""
    gameover_x = (W - IMAGE["gameover"].get_width()) / 2
    gameover_y = (FLOOR_Y - IMAGE["gameover"].get_height()) / 2

    bird = result["bird"]
    pipe_group = result["pipe_group"]

    while True:
        if bird.dying:
            bird.go_die()
        else:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    quit()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        quit()
                    if event.key == pygame.K_SPACE:
                        return

        SCREEN.blit(IMAGE["bgpic"], (0, 0))
        pipe_group.draw(SCREEN)
        SCREEN.blit(IMAGE["floor"], (0, FLOOR_Y))
        SCREEN.blit(IMAGE["gameover"], (gameover_x, gameover_y))
        SCREEN.blit(bird.image, bird.rect)
        show_score(result["score"])
        pygame.display.update()
        CLOCK.tick(FPS)


def show_score(score):
    """显示得分"""
    score_str = str(score)
    n = len(score_str)
    w = IMAGE["0"].get_width() * 1.1
    x = (W - n * w) / 2
    y = H * 0.1
    for num in score_str:
        SCREEN.blit(IMAGE[num], (x, y))
        x += w


class Bird:
    """小鸟类"""
    def __init__(self, x, y):
        """初始化小鸟信息"""
        self.dix = 0
        self.frames = [0] * 5 + [1] * 5 + [2] * 5 + [1] * 5
        self.images = IMAGE["birds"]
        self.image = self.images[self.frames[self.dix]]
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.y_val = -10
        self.max_y_val = 10
        self.gravity = 1
        self.rotate = 45
        self.max_rotate = -20
        self.rotate_val = -3
        self.y_val_after_flap = -10
        self.rotate_after_flap = 45
        self.dying = False

    def update(self, flap=False):
        """更新小鸟飞行状态"""
        if flap:
            self.y_val = self.y_val_after_flap
            self.rotate = self.rotate_after_flap

        self.y_val = min(self.y_val + self.gravity, self.max_y_val)
        self.rect.y += self.y_val
        self.rotate = max(self.rotate + self.rotate_val, self.max_rotate)

        self.dix += 1
        self.dix %= len(self.frames)
        self.image = self.images[self.frames[self.dix]]
        self.image = pygame.transform.rotate(self.image, self.rotate)

    def go_die(self):
        """判断失败后是否在地面之上"""
        if self.rect.y < FLOOR_Y:
            self.rect.y += self.max_y_val
            self.rotate = -90
            self.image = self.images[self.frames[self.dix]]
            self.image = pygame.transform.rotate(self.image, self.rotate)
        else:
            self.dying = False


class Pipe(pygame.sprite.Sprite):
    """水管类"""
    def __init__(self, x, y, upwards=True):
        """初始化"""
        pygame.sprite.Sprite.__init__(self)  # 初始化精灵组
        if upwards:
            self.image = IMAGE["pipes"][0]
            self.rect = self.image.get_rect()
            self.rect.x = x
            self.rect.top = y
        else:
            self.image = IMAGE["pipes"][1]
            self.rect = self.image.get_rect()
            self.rect.x = x
            self.rect.bottom = y
        self.x_val = -4

    def update(self):
        """更新水管移动"""
        self.rect.x += self.x_val


if __name__ == '__main__':
    main()

[源代码打包下载]




网友评论    (发表评论)

共7 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...