pygame小游戏-------FlappyBird像素鸟的实现

本文档展示了如何使用Python的Pygame库来简单复现经典游戏FlappyBird。代码包括游戏的主要元素,如鸟类、管道、地面以及游戏逻辑。玩家可以通过键盘控制鸟类飞行,避开管道障碍。游戏包含开始菜单、游戏窗口和死亡窗口三个阶段。
摘要由CSDN通过智能技术生成

简述:对FlappyBird像素鸟游戏的简单复现,仅两百行左右,工程目录结构为image文件夹和run.py文件。
pygame模块的下载直接pip install pygame即可,图片下载地址为像素鸟图片,音频文件自己找一个即可。
在这里插入图片描述

import pygame
import random
import os

#constents
width,height = 288,512
fps = 10

#setup
pygame.init()
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption('小垃圾') #窗口名字
clock = pygame.time.Clock()

#materials 资源
image_dir = {}
for i in os.listdir('./image'):
    name,extension = os.path.splitext(i)
    path = os.path.join('./image',i)
    image_dir[name] = pygame.image.load(path)

music = pygame.mixer.Sound('E:/音乐/夜曲.mp3') #背景音乐

#resize
image_dir['管道'] = pygame.transform.scale(image_dir['管道'],(image_dir['管道'].get_width()+10,300))
image_dir['地面'] = pygame.transform.scale(image_dir['地面'],(width+40,120))

class Bird:
    def __init__(self,x,y):
        self.image_name = '蓝鸟'
        self.image = image_dir[self.image_name+str(random.randint(1,3))]
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.y_vel = -10#初始速度
        self.max_y_vel = 10
        self.gravity = 1 #重力

        #角度变化
        self.rotata = 45
        self.max_rotata = -25
        self.rotata_vel = -3


    def updata(self,flap = False):

        if flap == True:
            self.y_vel = -10
            self.rotata = 45

        self.y_vel = min(self.y_vel+self.gravity,self.max_y_vel)#先上后下
        self.rect.y += self.y_vel

        self.rotata = max(self.rotata+self.rotata_vel,self.max_rotata)
        self.image = image_dir[self.image_name + str(random.randint(1, 3))]
        self.image = pygame.transform.rotate(self.image,self.rotata)

    def deathing(self):
        if self.rect.bottom < height-image_dir['地面'].get_height()//2-30:
            self.gravity+=2
            self.rect.y+= self.gravity
            self.image = image_dir[self.image_name + str(random.randint(1, 3))]
            self.image = pygame.transform.rotate(self.image, -40)
            return False
        return True


class Pipe:
    def __init__(self,x,y,cap):
        if cap == True:
            self.image = image_dir['管道']
            self.rect = self.image.get_rect()
            self.rect.x = x  #rect.x = x
            self.rect.y = y

        else:
            self.image = pygame.transform.flip(pygame.transform.scale(image_dir['管道'],(image_dir['管道'].get_width(),height)),False,True)
            self.rect = self.image.get_rect()
            self.rect.x = x  # rect.x = x
            self.rect.y = -height+y-100
        self.x_vel = -4

    def updata(self):
        self.rect.x  +=self.x_vel


class Floor:
    def __init__(self):
        self.floor_grap = image_dir['地面'].get_width() - width
        self.floor_x = 0
    def show_floor(self):
        self.floor_x -= 4
        screen.blit(image_dir['地面'], (self.floor_x, height - image_dir['地面'].get_height()))  # 绘制照片
        if self.floor_x <= -self.floor_grap:
            self.floor_x = 0

def show_score(score,choice):
    if choice == 0:
        w = image_dir['0'].get_width()*1.1
        x = (width - w*len(score))/2
        y = height*0.1
        for i in score:
            screen.blit(image_dir[i],(x,y))
            x += w
    else:
        w = image_dir['0'].get_width()*0.5
        x = width-2*w
        y =10
        for i in score[::-1]:
            screen.blit(image_dir[i],(x,y))
            x -= w


def menu_windows():
    bird_y_vel = 1
    bird_y = height/3-20
    bird1 = Bird(width/3-20, height/3-20)
    bird2 =  Bird(width/3+80, height/3-20)
    bird2.image_name = '红鸟'
    floor = Floor()
    while True:
        bird1.rotata = bird2.rotata = 0
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()

            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE :
                return

        bird_y +=bird_y_vel
        if bird_y > height/3-20 +8  or bird_y < height/3-20 -8:
            bird_y_vel *= -1

        bird1.updata()
        bird2.updata()
        screen.blit(image_dir['背景'],(0,0))#绘制照片
        screen.blit(image_dir['标题'], ((width-image_dir['标题'].get_width())/2, height/8-image_dir['标题'].get_height()))  # 绘制照片
        screen.blit(image_dir['准备'], ((width - image_dir['准备'].get_width()) / 2, height / 4 - image_dir['准备'].get_height()))  # 绘制照片
        screen.blit(image_dir['信息'], ((width - image_dir['信息'].get_width()) / 2, height/2 - image_dir['信息'].get_height()))

        screen.blit(bird1.image, (width/3-20,bird_y))  # 绘制照片
        screen.blit(bird2.image, (width/3+80,bird_y))  # 绘制照片

        floor.show_floor()
        pygame.display.update()
        clock.tick(fps)


def game_windows():
    score = 0
    bird = Bird(width/3-20, height/3-20)
    floor = Floor()
    distance = 200 #两根管道之间的距离
    pipe_list_down = []
    pipe_list_up = []
    for i in range(4):
        pipe_h = random.randint(image_dir['地面'].get_height()+20,400)
        image_dir['管道'] = pygame.transform.scale(image_dir['管道'],(image_dir['管道'].get_width(),pipe_h))
        pipe_list_down.append(Pipe(width+distance*i,height-pipe_h,1))
        pipe_list_up.append(Pipe(width + distance * i, height - pipe_h,0))

    while True:
        flap = False
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()

            if event.type == pygame.KEYDOWN and event.key == pygame.K_w:
                flap = True

            if event.type == pygame.KEYDOWN and event.key == pygame.K_s:
               pass


        #地面运动
        screen.blit(image_dir['背景'], (0, 0))  # 绘制照片

        first_pipe = pipe_list_down[0]
        first_pipe1 = pipe_list_up[0]
        if first_pipe.rect.right <0 and first_pipe1.rect.right <0:
            pipe_list_down.remove(first_pipe)
            pipe_list_up.remove(first_pipe1)
            pipe_h = random.randint(image_dir['地面'].get_height()+20, 400)
            image_dir['管道'] = pygame.transform.scale(image_dir['管道'], (image_dir['管道'].get_width(), pipe_h))
            pipe_list_down.append(Pipe(first_pipe.rect.right+4*distance,height-pipe_h,1))
            pipe_list_up.append(Pipe(first_pipe.rect.right + 4 * distance, height - pipe_h, 0))
            del first_pipe,first_pipe1

        for i in pipe_list_up +pipe_list_down:
            i.updata()
            screen.blit(i.image,i.rect)

            left2right = max(bird.rect.right,i.rect.right) - min(bird.rect.left,i.rect.left)
            top2bottom = max(bird.rect.bottom,i.rect.bottom)- min(bird.rect.top,i.rect.top)

            if left2right < (bird.rect.width +i.rect.width) and top2bottom < (bird.rect.height +i.rect.height):
                if i in pipe_list_up:
                    return {'bird':bird,'pipe1':i,'pipe2':pipe_list_down[pipe_list_up.index(i)],'score':str(score//2)}
                else:
                    return {'bird': bird, 'pipe1': i, 'pipe2': pipe_list_up[pipe_list_down.index(i)],
                            'score': str(score // 2)}

            if bird.rect.y <= 0 or bird.rect.y >= height-image_dir['地面'].get_height()//2:
                result = {'bird': bird, 'pipe1': i, 'pipe2': pipe_list_down[pipe_list_up.index(i)],
                          'score': str(score // 2)}
                return result  #保留结果状态

            if  bird.rect.left +i.x_vel<i.rect.centerx <bird.rect.left:
                score +=1
                #不同得分切换小鸟
                if score > 4:
                    bird.image_name = '黄鸟'
                if score >10:
                    bird.image_name = '红鸟'


        bird.updata(flap)
        floor.show_floor()
        screen.blit(bird.image, (width / 3 - 20, bird.rect.y))  # 绘制照片
        show_score(str(score // 2),1)
        pygame.display.update()
        clock.tick(fps)

def end_windows(result):
    bird = result['bird']
    pipe1 = result['pipe1']
    pipe2 = result['pipe2']
    score = result['score']
    floor = Floor()
    while True:
        temp = bird.deathing()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            #死亡过程中不能切换界面
            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE and temp:
                return

        screen.blit(image_dir['背景'], (0, 0))  # 绘制照片
        screen.blit(pipe1.image, pipe1.rect)
        screen.blit(pipe2.image, pipe2.rect)
        screen.blit(image_dir['结束'], ((width - image_dir['结束'].get_width())/2,height/3-20 - image_dir['结束'].get_height()))
        floor.show_floor()

        screen.blit(bird.image,bird.rect)
        show_score(score,0)
        pygame.display.update()
        clock.tick(fps)

def main():
    music.play()
    while True:
        image_dir['背景'] = random.choice([image_dir['白天'],image_dir['黑夜']])
        image_dir['背景'] = pygame.transform.scale(image_dir['背景'], (width, height))  # 转化大小

        menu_windows()
        result = game_windows()
        end_windows(result)

if __name__ == '__main__':
    main()


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值