Flappy Bird游戏——Python

最近跟随b站up趣派编程学习的python小游戏,链接:

https://www.bilibili.com/video/BV1Kz4y1m7PZ?spm_id_from=333.999.0.0&vd_source=c3f07254735ffa6c21130697d6067707ww

import pygame
import random,time
import os #导入操作系统库os

#确定常量
Width,Height = 288,512  #宽和高
FPS = 30  #帧数 每秒刷新30次游戏画面

#基础设置
pygame.init()   #初始化
SCREEN = pygame.display.set_mode((Width,Height)) #pygame游戏窗口模块以及设置窗口大小
pygame.display.set_caption('Flappy Bird--By Deng Ruzhao')
CLOCK=pygame.time.Clock()

#加载素材
PICTURES={}
for picture in os.listdir('assets/sprites'):  #listdir将列出文件夹里的所有文件
    name,extension = os.path.splitext(picture)  #splitext将分割文件名与后缀(.png)
    path = os.path.join('assets/sprites',picture) #path.join拼接文件路径与文件名
    PICTURES[name]= pygame.image.load(path)  #pygame装载图片


'''bird = pygame.image.load('assets/sprites/red-mid.png')  #pygame图像模块 导入图片
bgpic = pygame.image.load('assets/sprites/day.png')
guide = pygame.image.load('assets/sprites/guide.png')
floor = pygame.image.load('assets/sprites/floor.png')
pipe = pygame.image.load('assets/sprites/green-pipe.png')
gameover = pygame.image.load('assets/sprites/gameover.png')'''

FLOOR_Y = Height - PICTURES['floor'].get_height()

AUDIO = {}  #字典
for audio in os.listdir('assets/audio'):
    name,extension = os.path.splitext(audio)
    path = os.path.join('assets/audio',audio)
    AUDIO[name] = pygame.mixer.Sound(path)

'''start = pygame.mixer.Sound('assets/audio/start.wav')  #混音器模块中的Sound设置声音
die = pygame.mixer.Sound('assets/audio/die.wav')
hit = pygame.mixer.Sound('assets/audio/hit.wav')
score = pygame.mixer.Sound('assets/audio/score.wav')
flap = pygame.mixer.Sound('assets/audio/flap.wav')'''
def main():
    while True:
        AUDIO['start'].play()   #播放音频
        PICTURES['bgpic'] = PICTURES[random.choice(['day','night'])]
        color = random.choice(['red','yellow','blue'])  #随机选择游戏中的小鸟颜色
        PICTURES['birds'] = [PICTURES[color+'-up'],PICTURES[color+'-mid'],PICTURES[color+'-down']]  #列表
        pipe = PICTURES[random.choice(['red-pipe','green-pipe'])]
        PICTURES['pipes'] = [pipe,pygame.transform.flip(pipe,False,True)]  #transform变形模块中的flip翻转模块 False水平不反转 True竖直反转
        menu_window()  #菜单界面
        result = game_window()  #游戏界面
        end_window(result)   #结束界面

def menu_window():
    floor_gap = PICTURES['floor'].get_width()-Width
    floor_x = 0

    guide_x = (Width-PICTURES['guide'].get_width())/2
    guide_y = (Height-PICTURES['guide'].get_height())/2
    bird_x = Width*0.2
    bird_y = (Height-PICTURES['birds'][0].get_height())/2  #小鸟x,y位置
    bird_y_speed = 1  #小鸟y方向上的速度
    bird_y_range = [bird_y-8,bird_y+8]  #y方向运动范围

    idx = 0
    repeat = 5
    frames = [0]*repeat+[1]*repeat+[2]*repeat+[1]*repeat#等同于 frames = [0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1]  #由于小鸟拍动翅膀,5帧自然

    while True:
        for event in pygame.event.get():  #获取事件(即鼠标键盘的操作)
            if event.type == pygame.QUIT:
                quit()
            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:  #判断事件为键盘输入的空格
                return

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

        bird_y += bird_y_speed
        if bird_y < bird_y_range[0] or bird_y > bird_y_range[1]:
            bird_y_speed *= -1

        idx += 1
        idx %= len(frames)
        SCREEN.blit(PICTURES['bgpic'],(0,0)) #贴上素材 先写的先画,按图层来画
        SCREEN.blit(PICTURES['floor'], (floor_x, FLOOR_Y))
        SCREEN.blit(PICTURES['guide'], (guide_x, guide_y))
        SCREEN.blit(PICTURES['birds'][frames[idx]], (bird_x, bird_y))
        pygame.display.update()
        CLOCK.tick(FPS)

def game_window():
    score = 0
    AUDIO['flap'].play()
    floor_gap = PICTURES['floor'].get_width() - Width
    floor_x = 0

    bird = Bird(Width*0.2,Height*0.4) #从Bird类中生成对象bird

    distance = 150
    n_pairs = 4
    pipe_gap = 130
    pipe_group = pygame.sprite.Group()
    for i in range(n_pairs):
        pipe_y = random.randint(int(Height*0.3),int(Height*0.7))  #0.3 0.7
        pipe_up = Pipe(Width+i*distance,pipe_y,True)
        pipe_down = Pipe(Width+i*distance,pipe_y-pipe_gap,False)
        pipe_group.add(pipe_up)
        pipe_group.add(pipe_down)
        '''pipes.append(pipe_up)
        pipes.append(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_SPACE:
                    flap = True
                    AUDIO['flap'].play()


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

        bird.update(flap)
        first_pipe_up = pipe_group.sprites()[0]
        first_pipe_down = pipe_group.sprites()[1]
        if first_pipe_up.rect.right < 0:  #.right不能改为.x或.left
            '''pipes.remove(first_pipe_up)
            pipes.remove(first_pipe_down)''' #pygame里sprites自动移除
            pipe_y = random.randint(int(Height * 0.3), int(Height * 0.7))
            new_pipe_up = Pipe(first_pipe_up.rect.x+n_pairs*distance,pipe_y,True)
            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)
            '''pipes.append(new_pipe_up)
            pipes.append(new_pipe_down)'''
            '''del first_pipe_up
            del first_pipe_down'''
            first_pipe_up.kill()
            first_pipe_down.kill()

        '''for pipe in pipes:
            pipe.update()'''
        pipe_group.update()

        if bird.rect.y <0 or bird.rect.y > FLOOR_Y or pygame.sprite.spritecollideany(bird,pipe_group):  #输赢判断:小鸟出界或撞击地板则输或者是否碰撞(碰撞采用精灵库自带函数jiance)
            bird.dying = True
            AUDIO['hit'].play()
            AUDIO['die'].play()
            result = {'bird':bird,'pipe_group':pipe_group,'score':score}
            return result

        '''for pipe in pipe_group.sprites(): #判断是否碰撞
            right_to_left = max(bird.rect.right,pipe.rect.right)-min(bird.rect.left,pipe.rect.left)
            bottom_to_top = max(bird.rect.bottom,pipe.rect.bottom)-min(bird.rect.top,pipe.rect.top)
            if right_to_left < bird.rect.width+pipe.rect.width and bottom_to_top < bird.rect.height+pipe.rect.height:
                AUDIO['hit'].play()
                AUDIO['die'].play()
                result = {'bird':bird,'pipe_group':pipe_group}
                return result'''

        if bird.rect.left+first_pipe_up.x_speed < first_pipe_up.rect.centerx < bird.rect.left:  #前一帧鸟的位置 < 水管中心 < 后一帧鸟的位置
            score += 1
            AUDIO['score'].play()

        SCREEN.blit(PICTURES['bgpic'],(0,0))
        pipe_group.draw(SCREEN)
        SCREEN.blit(PICTURES['floor'], (floor_x, FLOOR_Y))


        show_score(score)

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

def end_window(result):
    gameover_x = (Width-PICTURES['gameover'].get_width())/2
    gameover_y = (Height-PICTURES['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 and event.key == pygame.K_SPACE:  #判断事件为键盘输入的空格
                    return


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

def show_score(score):
    score_str = str(score)
    n = len(score_str)
    w = PICTURES['0'].get_width() * 1.1
    x = (Width - w * n) / 2
    y = Height * 0.1
    for i in score_str:
        SCREEN.blit(PICTURES[i], (x, y))
        x += w


class Bird:  #类---小鸟
    def __init__(self,x,y):  #定义类时选择需要输入的参数,这里是x,y
        self.frames = [0]*5+[1]*5+[2]*5+[1]*5
        self.idx = 0
        self.pictures = PICTURES['birds']
        self.picture = self.pictures[self.frames[self.idx]]
        self.rect = self.picture.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.y_speed = -10
        self.max_y_speed = 10
        self.gravity = 1  #重力加速度
        self.rotate = 45
        self.max_rotate = -20
        self.rotate_speed = -3
        self.y_speed_after_flap = -10  #拍打翅膀后速度
        self.rotate_after_flap = 45  #拍打翅膀后角度
        self.dying = False

    def update(self,flap=False):  #默认拍打翅膀 为否

        if flap:
            self.y_speed = self.y_speed_after_flap
            self.rotate = self.rotate_after_flap

        self.y_speed = min(self.y_speed+self.gravity,self.max_y_speed)
        self.rect.y += self.y_speed
        self.rotate = max(self.rotate+self.rotate_speed,self.max_rotate)

        self.idx += 1
        self.idx %= len(self.frames)
        self.picture = self.pictures[self.frames[self.idx]]
        self.picture = pygame.transform.rotate(self.picture,self.rotate)  #rotate旋转模块

    def go_die(self):
        if self.rect.y < FLOOR_Y:
            self.rect.y += self.max_y_speed
            self.rotate = -90
            self.picture = self.pictures[self.frames[self.idx]]
            self.picture = pygame.transform.rotate(self.picture,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 = PICTURES['pipes'][0]  #图片只能self.image 不然报错'Pipe' object has no attribute 'image'
            self.rect = self.image.get_rect()
            self.rect.x = x
            self.rect.top = y

        else:
            self.image = PICTURES['pipes'][1]
            self.rect = self.image.get_rect()
            self.rect.x = x
            self.rect.bottom = y
        self.x_speed = -4

    def update(self):
        self.rect.x += self.x_speed

main()




'''while True:
    for event in pygame.event.get():  #获取事件(即鼠标键盘的操作)
        if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:  #判断事件为键盘输入的空格
            bird = pygame.transform.flip(bird,True,False)  #transform变形模块中的flip翻转模块 True水平翻转 False竖直不翻转



    color = (random.randint(0,255),random.randint(0,255),random.randint(0,255))
    SCREEN.fill(color)
    SCREEN.blit(bird,(150,250))
    pygame.display.update()
    #time.sleep(0.1)
    CLOCK.tick(10)'''
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值