[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()
[源代码打包下载]
初级程序员
by: 云代码会员 发表于:2021-11-11 17:35:03 顶(0) | 踩(0) 回复
dwdAWD
回复评论