笔者已将代码和资源放在了gitee,请自行领取
import pygame, os, random
from itertools import cycle
pygame.init()
images = {}
for image in os.listdir('../assets/sprites'):
name, extension = os.path.splitext(image)
path = os.path.join('../assets/sprites', image)
images[name] = pygame.image.load(path)
color = random.choice(['red', 'yellow', 'blue'])
images['birds'] = [images[color + 'bird-upflap'], images[color + 'bird-midflap'],
images[color + 'bird-downflap']]
def return_audio():
audios = {}
audios['wing'] = pygame.mixer.Sound('../assets/audio/wing.wav')
audios['point'] = pygame.mixer.Sound('../assets/audio/point.wav')
audios['hit'] = pygame.mixer.Sound('../assets/audio/hit.wav')
audios['die'] = pygame.mixer.Sound('../assets/audio/die.wav')
return audios
def return_image():
return images
class Bird(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.dying = False
self.repeat = 2
self.idx = 0
self.frames = cycle([0, 0, 1, 1, 2, 2, 1, 1])
self.images = images['birds']
self.image = images['birds'][0]
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.y_vel_after_flap = -10
self.concussion_y = 1
self.concussion_y_vel = 1
self.bird_y_range = [self.rect.y - 8, self.rect.y + 8]
def update(self):
self.image = images['birds'][next(self.frames)]
def move(self, flap=False):
if flap:
self.y_vel = self.y_vel_after_flap
# self.rotate = self.rotate_after_flap
self.y_vel = min(self.y_vel + self.gravity, self.max_y_vel)
self.rect.y += self.y_vel
def consussion(self):
self.rect.y += self.concussion_y_vel
if self.rect.y < self.bird_y_range[0] or self.rect.y > \
self.bird_y_range[1]:
self.concussion_y_vel *= -1
def go_die(self, FLOOR_Y):
if self.rect.y < FLOOR_Y:
self.rect.y += self.max_y_vel
self.image = self.images[self.frames[self.idx]]
else:
self.dying = False
def is_die(self, FLOOR_Y):
if self.rect.y > FLOOR_Y or self.rect.y < 0:
self.dying = True
return self.dying
class Pipe(pygame.sprite.Sprite):
def __init__(self, x, y, upwards=True):
super().__init__()
if upwards:
self.image = images['pipe-red']
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.top = y
else:
self.image = pygame.transform.flip(images['pipe-red'], False, True)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.bottom = y
self.x_vel = -4
def update(self):
self.rect.x += self.x_vel
用于生成管道
class GEN_PIPE:
def __init__(self, n):
self.n = n
self.pipes = pygame.sprite.Group()
self.gen_pipe()
self.pipe_move()
self.pipe_width=images['pipe-red'].get_width()
def gen_pipe_y(self):
return random.randint(int(H * 0.3), int(H * 0.7))
def gen_distance(self):
return random.randint(150, 180)
def gen_pipe(self):
for i in range(self.n):
distance = self.gen_distance()
# distance = 150
pipe_y = self.gen_pipe_y()
pipe_up = Pipe(W + i * distance, pipe_y, True)
pipe_down = Pipe(W + i * distance, pipe_y - PIPE_GAP, False)
self.pipes.add(pipe_up, pipe_down)
def pipe_move(self):
first_up = self.pipes.sprites()[0]
first_down = self.pipes.sprites()[1]
# distance = 150
distance = self.gen_distance()
if first_up.rect.right < 0:
# distance = self.gen_distance()
pipe_y = self.gen_pipe_y()
new_pipe_up = Pipe(first_up.rect.x + self.n * distance, pipe_y, True)
new_pipe_down = Pipe(first_up.rect.x + self.n * distance, pipe_y - PIPE_GAP, False)
self.pipes.add(new_pipe_up)
self.pipes.add(new_pipe_down)
first_up.kill()
first_down.kill()
import pygame
def main():
while True:
menu_window()# 开始界面
game_window()# 游戏界面
end_window()# 游戏结束界面
def menu_window():
pass
def game_window():
pass
def end_window():
pass
import random
from def_sprite import Bird, Pipe, return_image,return_audio
import pygame
images = return_image()
audios=return_audio()
W = 288
H = 500
FPS = 30
MAX_FLOOR_DISTANCE = images['base'].get_width() - W
PIPE_GAP = 100
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((W, H))
pygame.display.set_caption('bird')
clock = pygame.time.Clock()
FLOOR_Y = H - return_image()['base'].get_height() # 地板高度
floor_x = 0
def menu_window():
floor_gap = return_image()['base'].get_width() - W
bird = Bird(W * 0.2, H * 0.5)
# floor_x = 0
guide_x = (W - return_image()['message'].get_width()) / 2
guide_y = (FLOOR_Y - return_image()['message'].get_height()) / 2
while True:
# is_close()
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
if event.type == pygame.KEYDOWN:
# print('111')
if event.key == pygame.K_SPACE:
return
# floor_x -= 4
# if floor_x <= -floor_gap:
# floor_x = 0
# floor_move()
bird.update()
bird.consussion()
screen.blit(images['background-day'], (0, 0))
screen.blit(images['base'], (floor_move(), FLOOR_Y))
screen.blit(images['message'], (guide_x, guide_y))
screen.blit(bird.image, bird.rect)
# 框架
pygame.display.update()
clock.tick(FPS)
def game_window():
bird = Bird(W * 0.2, H * 0.4)
# floor_x = 0
score = 0
ALL_PIPE = GEN_PIPE(4)
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
audios['wing'].play()
# 地面移动
# floor_x -= 4
# if floor_x <= -MAX_FLOOR_DISTANCE:
# floor_x = 0
bird.update()
ALL_PIPE.pipe_move()
ALL_PIPE.pipes.update()
bird.move(flap)
if bird.is_die(FLOOR_Y) or is_crash(bird, ALL_PIPE.pipes):
audios['die'].play()
return
pipe_x=ALL_PIPE.pipes.sprites()[0].rect.x+ALL_PIPE.pipe_width
if pipe_x<bird.rect.right<pipe_x+4:
score+=1
audios['point'].play()
screen.blit(images['background-day'], (0, 0))
ALL_PIPE.pipes.draw(screen)
screen.blit(images['base'], (floor_move(), FLOOR_Y))
show_score(score)
screen.blit(bird.image, bird.rect)
# 框架
pygame.display.update()
clock.tick(FPS)
def end_window():
gameover_x = (W - images['gameover'].get_width()) / 2
gameover_y = (H - images['gameover'].get_height()) / 2
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
return
screen.blit(images['background-night'], (0, 0))
screen.blit(images['base'], (0, FLOOR_Y))
screen.blit(images['gameover'], (gameover_x, gameover_y))
# 框架
pygame.display.update()
clock.tick(FPS)
def is_close():
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
def is_crash(sprite1, sprite2):
aa = pygame.sprite.spritecollideany(sprite1, sprite2)
return aa
def floor_move():
global floor_x
floor_x -= 4
if floor_x <= -MAX_FLOOR_DISTANCE:
floor_x = 0
return floor_x
def show_score(score):
score_str = str(score)
n = len(score_str)
width = images['0'].get_width() * 1.1
init_x = (W - n * width) / 2
init_y = H * 0.1
for num in score_str:
screen.blit(images[num], (init_x, init_y))
init_x += width