1 Star 1 Fork 1

Slash/flappybird

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
new_flappybirds.py 22.52 KB
一键复制 编辑 原始数据 按行查看 历史
Slash 提交于 2022-02-09 17:06 . v01
import pygame, sys, random
"""定义背景类,实现背景滚动"""
class Background(pygame.sprite.Sprite):
def __init__(self, picture, isout = False):
"""初始化背景类,picture是背景图片,Flase用于指定两张图片"""
pygame.sprite.Sprite.__init__(self)
self.image = picture
self.rect = picture.get_rect()
self.speed = 1 # 背景移动速度
if isout:
self.rect.x = bgwidth # 另一个背景图片在当前图片左侧
def update(self):
self.rect.x -= self.speed
if self.rect.x <= -bgwidth:
self.rect.x = bgwidth
"""屏幕绘制方法"""
def blit_screen(msg, size, pos):
if size == '':
screen.blit(msg, pos)
else:
screen.blit(pygame.transform.scale(msg, size), pos)
"""添加泡泡组方法"""
def add_bubble(group, num):
"""生成指定数量泡泡,group为泡泡组,num为生成泡泡数量"""
for i in range(num):
bb = Bubble()
group.add(bb)
""" 定义鸟类继承自pygame精灵类 """
class Love(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.rect = love_image.get_rect(x=uppip.rect.x,y=uppip.rect.bottom)
self.mask = pygame.mask.from_surface(love_image)
self.yspeed = 1
self.up = False
self.flag = True
self.random = random.randint(1, 8)
def love_move(self, top, bottom):
if self.up :
self.rect.y -= self.yspeed
if self.rect.y <= top:
self.rect.y += self.yspeed
self.up = not self.up
else:
self.rect.y += self.yspeed
if self.rect.y >= bottom - self.rect.height:
self.rect.y -= self.yspeed
self.up = not self.up
def eat_love(self):
if self.random == 2:
love.rect.x = uppip.rect.x + 11
love.love_move(uppip.rect.bottom, downpip.rect.y)
if self.flag:
blit_screen(love_image, '', (love.rect.x, love.rect.y))
class Bird(pygame.sprite.Sprite):
def __init__(self):
"""小鸟类初始化方法"""
pygame.sprite.Sprite.__init__(self)
self.rect = bird1.get_rect(x=80, y=200) # 小鸟初始位置
self.jump = False # 判断是否跳跃
self.jumpspeed = 5 # 小鸟初始跳跃加速度
self.gravity = 1 # 小鸟初始重力加速度
def bird_jump(self):
"""定义小鸟跳跃方法"""
if self.jump:
if game.level == 2:
self.jumpspeed -= 0.3
else:
self.jumpspeed -= 0.5 # 小鸟跳跃,跳跃加速度-0.5,y坐标-5
self.rect.y -= self.jumpspeed
else:
if game.level == 2:
self.gravity += 0.1
else:
self.gravity += 0.2 # 小鸟下落,重力加速度+0.2,y坐标+1
self.rect.y += self.gravity
self.rect[1] = self.rect.y # 更新矩形的y坐标
def bird_update(self, f, p1, p2, p3):
"""实现小鸟动态跳跃"""
if f % 3 == 1:
bird.mask = pygame.mask.from_surface(p1)
blit_screen(p1, '', bird.rect)
elif f % 3 == 2:
bird.mask = pygame.mask.from_surface(p2)
blit_screen(p2, '', bird.rect)
else:
bird.mask = pygame.mask.from_surface(p3)
blit_screen(p3, '', bird.rect)
pygame.display.update()
""" 定义管道类继承自pygame精灵类 """
class Pipeline(pygame.sprite.Sprite):
def __init__(self, posy, picture):
"""定义管道初始化"""
pygame.sprite.Sprite.__init__(self)
self.mask = pygame.mask.from_surface(picture) # 管道像素遮罩
self.rect = picture.get_rect(x=400, y=posy) # 管道初始位置
self.xspeed = 3 # 管道移动速度
self.yspeed = 0.5
self.is_up = True
self.flag = True
def pipeline_move(self):
"""定义管道移动方法"""
global score, lives
uppip.rect.x -= self.xspeed # 上下管道x坐标-3
downpip.rect.x -= self.xspeed
if score > 20: # 分数超过20管道开始上下移动
if self.is_up:
uppip.rect.bottom -= self.yspeed
downpip.rect.bottom -= self.yspeed
if uppip.rect.bottom <= 0:
self.is_up = False
if not self.is_up:
uppip.rect.y += self.yspeed
downpip.rect.y += 1 # !!!!!这里有点问题!!!为什么只能是1
if downpip.rect.top >= bgheight:
self.is_up = True
if uppip.rect.x + uppip.rect.width == bird.rect.x: # 判断小鸟是否越过管道,若越过,加一分
score += 1
if uppip.rect.x < -52: # 管道移出画面,恢复管道初始x位置,随机设置y位置
uppip.rect.x = bgwidth
downpip.rect.x = bgwidth
uppip.rect.y = random.randint(100-bgheight,350-bgheight)
downpip.rect.y = uppip.rect.bottom + random.randint(70, 150)
love.random = random.randint(1, 9)
love.flag = True
self.flag = True
print(love.random)
""" 定义泡泡类继承自pygame精灵类 """
class Bubble(pygame.sprite.Sprite):
def __init__(self):
"""定义泡泡初始化"""
pygame.sprite.Sprite.__init__(self)
# self.image = pygame.image.load("./picture/bubble.png")
self.rect = bubble_image2.get_rect(x=bgwidth, y=random.randint(0, 300)) # 泡泡初始位置
self.mask = pygame.mask.from_surface(bubble_image2) # 泡泡像素遮罩
self.xspeed = random.randint(2, 5) # 泡泡初始x速度
self.yspeed = random.randint(-2, 3) # 泡泡初始y速度
def bubble_move(self):
"""定义泡泡移动方法"""
global score, cnt, bubble_num
self.rect.x -= self.xspeed # 泡泡xy坐标依据速度变化self.rect.x == -self.rect.width
self.rect.y += self.yspeed
if self.rect.x == -self.rect.width-20 or self.rect.bottom == 0 or self.rect.top == bgheight: # 小鸟越过泡泡,每越过一组加一分
cnt += 1
if cnt % bubble_num == 0:
score += 1
if cnt % (3*bubble_num) == 0:
bubble_num += 1
cnt = 0
bubble_group.empty()
add_bubble(bubble_group,bubble_num)
for each in bubble_group:
each.rect.x = bgwidth # 初始化泡泡位置
# each.rect.y = random.randint(bird.rect.y - 200, bird.rect.y + 200)
each.rect.y = random.randint(0,300)
""" 定义音乐类 """
class Music(object):
def __init__(self):
pygame.mixer.music.load("./music/flappybird.mp3")
def background_music(self, flag):
"""控制背景音乐播放"""
if flag:
pygame.mixer.music.play(-1, 0.0)
else:
pygame.mixer.music.stop()
def jump_music(self, flag):
"""控制小鸟跳跃音效播放"""
if flag:
jump = pygame.mixer.Sound("./music/jump.mp3")
pygame.mixer.Sound.set_volume(jump, 0.3)
jump.play()
def dead_music(self, flag):
"""音效播放"""
if flag:
dead = pygame.mixer.Sound("./music/fail.mp3")
dead.play()
""" 定义按钮类 """
class Button(object):
def __init__(self):
"""初始化按钮位置和大小"""
self.selfxy = self.selfx, self.selfy = 120, 60
self.srposxy = self.srposx, self.srposy = 140, 300
self.mqposxy = self.mqposx, self.mqposy = 140, 400
""" 定义flappybird游戏类 """
class Game(object):
def __init__(self):
"""初始化游戏阶段等级"""
self.level = 1
self.groups = pipeline_group
def check_dead(self, groups):
"""检查小鸟是否死亡方法(group用于传递当前障碍物组)"""
global lives
if pygame.sprite.spritecollide(bird, groups, False, pygame.sprite.collide_mask):
if lives > 0 and uppip.flag:
lives -= 1
uppip.flag = False
return False
if lives ==0 and uppip.flag:
return True
elif bird.rect.y <= 0 or bird.rect.y + bird.rect.height >= bgheight:
lives = 0
return True
else:
return False
def updata_screen(self, l):
"""
实时更新屏幕方法(l用于传递当前游戏阶段等级):
分别绘制游戏背景/障碍物/分数
调用障碍物/小鸟移动方法
"""
global lives
clock.tick(60)
bg_group.update() # 绘制游戏背景
bg_group.draw(screen)
if l == 1:
uppip.pipeline_move() # 调用管道移动方法
love.eat_love()
blit_screen(pineup, '', (uppip.rect.x, uppip.rect.y)) # 绘制上下管道
blit_screen(pinedown, '', (downpip.rect.x, downpip.rect.y))
if pygame.sprite.collide_mask(bird, love) and love.flag:
lives += 1
love.flag = False
if l == 2:
# bubble_group.draw(screen)
for each in bubble_group: # 遍历"组",调用泡泡移动方法,绘制泡泡
each.bubble_move()
blit_screen(bubble_image2, '', each.rect)
score_font.render("Score : " + str(score), True, (255, 255, 255)) # 设置分数字体内容、抗锯齿、颜色
bird.bird_jump()
blit_screen(score_font.render("Score : " + str(score), True, (255, 255, 255)), '', (10, 0))
blit_screen(love_image, '', (10, 50))
blit_screen(score_font.render(" x " + str(lives), True, (255, 255, 255)), '', (45, 30))
def get_result(self, flag):
"""
返回游戏结果方法(flag用于控制小鸟死亡音效):
关闭背景音乐
绘制gameover/分数/晕倒的小鸟/返回按钮/退出按钮并显示在屏幕上
"""
music.dead_music(flag) # 播放小鸟死亡音效
music.background_music(False) # 关闭背景音乐
gameover_text = 'Game Over' # 设置文本内容
self.gameover = myfont.render(gameover_text, True, (242, 3, 36)) # 设置文本内容、抗锯齿、颜色
self.go_selfxy = myfont.size(gameover_text)[0], myfont.size(gameover_text)[1] # 获取文本大小
blit_screen(star, '', (bird.rect.x, bird.rect.y)) # 绘制晕倒的小鸟
blit_screen(self.gameover, self.go_selfxy, (75, 120)) # 绘制gameover
blit_screen(return_image, sr_button.selfxy, sr_button.srposxy) # 绘制返回按钮
blit_screen(quit_image, mq_button.selfxy, mq_button.mqposxy) # 绘制退出按钮
pygame.display.update() # 屏幕显示
def begin(self):
"""
游戏开始方法:
点击开始按钮进入游戏
level1为城市
level2为海洋
点击音乐按钮控制音乐开关
游戏结束后点击返回按钮回到主界面
游戏结束后点击退出按钮退出游戏
"""
switch = True # 音乐开关,默认为开
music.background_music(switch) # 播放音乐
f = 1 # 小鸟图片序号1-3
delay = 99
while True:
clock.tick(60) # 设置时间间隔60ms
blit_screen(bg_land, bgsize, (0, 0)) # 绘制游戏背景
blit_screen(wt, title_selfxy, title_posxy) # 绘制游戏标题
blit_screen(start_image, sr_button.selfxy, sr_button.srposxy) # 绘制开始按钮
blit_screen(music_image, mq_button.selfxy, mq_button.mqposxy) # 绘制音乐开关按钮
if not switch:
blit_screen(quit_music, mq_button.selfxy, mq_button.mqposxy)
bird.bird_update(f, bird1, bird2, bird3)
delay -= 1
if not (delay % 6):
f += 1
if not delay: # 初始化延时
f = 1
delay = 99
# ↓获取鼠标事件:quit=退出游戏/点击开始按钮=进入游戏/连续点击音乐按钮=开关音乐
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit() # 退出游戏
if event.type == pygame.MOUSEBUTTONDOWN and mq_button.mqposx < \
pygame.mouse.get_pos()[0] < mq_button.mqposx + \
mq_button.selfx and mq_button.mqposy < \
pygame.mouse.get_pos()[1] < mq_button.mqposy + \
mq_button.selfy:
switch = not switch # 交替变化实现每次点击切换音乐状态
music.background_music(switch)
if event.type == pygame.MOUSEBUTTONDOWN and sr_button.srposx < \
pygame.mouse.get_pos()[0] < sr_button.srposx + \
sr_button.selfx and sr_button.srposy < \
pygame.mouse.get_pos()[1] < sr_button.srposy + \
sr_button.selfy:
self.updata_screen(self.level) # 进入游戏,绘制游戏中的屏幕
# f = 1 # 小鸟图片序号1-3
# delay = 99 # 延时
while True:
clock.tick(60)
if self.level == 1:
bird.bird_update(f, bird1, bird2, bird3)
if self.level == 2:
bird.bird_update(f, bird4, bird5, bird6)
delay -= 1
if not (delay % 3):
f += 1
if not delay: # 初始化延时
f = 1
delay = 99
# ↓获取事件:quit=退出游戏;鼠标点击/按键盘=小鸟跳跃
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if (event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN):
music.jump_music(switch) # 播放跳跃声音
bird.jump = True # 小鸟跳跃
bird.gravity = 1 # 初始化重力加速度
bird.jumpspeed = 5 # 初始化跳跃阻力
# ↓若小鸟死亡,返回结果,加载游戏结束界面;若没有死亡,则加载游戏界面
if self.check_dead(self.groups):
self.get_result(switch) # 返回游戏结果
# ↓获取事件:quit按钮=退出游戏;return按钮=返回游戏准备界面;
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN and mq_button.mqposx < \
pygame.mouse.get_pos()[0] < mq_button.mqposx + \
mq_button.selfx and mq_button.mqposy < \
pygame.mouse.get_pos()[1] < mq_button.mqposy + \
mq_button.selfy:
pygame.quit() # 卸载pygame所有模块
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN and sr_button.srposx < \
pygame.mouse.get_pos()[0] < sr_button.srposx + \
sr_button.selfx and sr_button.srposy < \
pygame.mouse.get_pos()[1] < sr_button.srposy + \
sr_button.selfy:
return # 回到游戏主界面
else:
# ↓实时更新屏幕内容:背景/管道/小鸟/分数
self.updata_screen(self.level)
if score == 40: # 根据分数设置游戏阶段
self.level = 2
self.groups = bubble_group
bg_group.empty()
bg_group.add(bg2,bg3)
""" 程序开始 """
if __name__ == '__main__':
while True:
pygame.init() # 初始化所有导入的pygame模块
pygame.font.init() # 字体模块
pygame.display.set_caption('flappy bird @fg') # 游戏窗口标题
bgsize = bgwidth, bgheight = 400, 600 # 游戏窗口大小
font = pygame.font.SysFont('', 50) # 创建font对象
screen = pygame.display.set_mode(bgsize, pygame.RESIZABLE) # 创建屏幕对象
clock = pygame.time.Clock() # 时间模块
title = 'Flappy Bird!' # 游戏标题
title_posxy = 50, 100 # 游戏标题位置
myfont = pygame.font.Font("./word/bitsybutton_v2.ttf", 90) # 创建字体对象
score_font = pygame.font.Font("./word/bitsybutton_v2.ttf", 50)
wt = myfont.render(title, True, (255, 255, 255)) # 设置字体内容、抗锯齿、颜色
title_selfxy = myfont.size(title)[0], myfont.size(title)[1] # 设置标题大小
bg_land = pygame.image.load("./picture/land.png").convert() # land背景图片
bg_sea = pygame.image.load("./picture/sea.png").convert() # sea背景图片
start_image = pygame.image.load("./picture/start1.jpg").convert() # 开始按钮
music_image = pygame.image.load("./picture/music1.jpg").convert() # 音乐按钮
return_image = pygame.image.load("./picture/return1.jpg").convert() # 返回按钮
quit_image = pygame.image.load("./picture/quit1.jpg").convert() # 退出按钮
quit_music = pygame.image.load("./picture/music2.jpg").convert() # 音乐停止按钮
star = pygame.image.load("./picture/star.png").convert_alpha() # 眩晕效果
bird1 = pygame.image.load("./picture/bird1.png").convert_alpha() # landbird小鸟
bird2 = pygame.image.load("./picture/bird2.png").convert_alpha()
bird3 = pygame.image.load("./picture/bird3.png").convert_alpha()
bird4 = pygame.image.load("./picture/bird4.png").convert_alpha() # seabird小鸟
bird5 = pygame.image.load("./picture/bird5.png").convert_alpha()
bird6 = pygame.image.load("./picture/bird6.png").convert_alpha()
pineup = pygame.image.load("./picture/pipe2.png").convert_alpha() # 上管道图片
pinedown = pygame.image.load("./picture/pipe1.png").convert_alpha() # 下管道图片
bubble_image1 = pygame.image.load("./picture/smallbubble.png").convert_alpha() # 泡泡图片
bubble_image2 = pygame.image.load("./picture/midbubble.png").convert_alpha()
bubble_image3 = pygame.image.load("./picture/bigbubble.png").convert_alpha()
love_image = pygame.image.load("./picture/life2.png").convert_alpha()
# love1 =Love(200)
# love_group = pygame.sprite.Group()
# love_group.add(love, love1)
lives = 0
bubble_num = 6
cnt = 0 # 泡泡数量
score = 0 # 游戏得分
bg = Background(bg_land)
bg1 = Background(bg_land,True)
bg2 = Background(bg_sea)
bg3 = Background(bg_sea,True)
bg_group = pygame.sprite.Group()
bg_group.add(bg,bg1)
pipeline_group = pygame.sprite.Group() # 管道组
uppip = Pipeline(-300, pineup) # 初始化管道类
downpip = Pipeline(400, pinedown)
pipeline_group.add(uppip, downpip) # 添加管道类
bubble_group = pygame.sprite.Group() # 泡泡组
love = Love()
add_bubble(bubble_group, bubble_num) # 添加泡泡类
sr_button = Button() # 初始化按钮类
mq_button = Button()
quitmusic = Button()
music = Music() # 初始化音乐类
bird = Bird() # 初始化鸟类
game = Game() # 初始化游戏类
game.begin() # 游戏开始
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/fg_slash/flappybird.git
[email protected]:fg_slash/flappybird.git
fg_slash
flappybird
flappybird
master

搜索帮助