You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
9.7 KiB

import pygame
import random
import math
# 初始化pygame
pygame.init()
# 设置屏幕尺寸
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("飞机大战游戏")
# 定义颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
# 加载背景图像
background_img = pygame.image.load("bg.png")
background_y = 0
# 加载飞机图像
player_img = pygame.image.load("player.png")
player_rect = player_img.get_rect()
player_rect.centerx = screen_width // 2
player_rect.bottom = screen_height - 10
# 子弹设置
bullet_img = pygame.image.load("bullet.png")
bullets = []
bullet_speed = 10
bullet_timer = 0
bullet_limit = 4 # 每秒最多发射4个子弹
bullet_cooldown = 0.25 # 每个子弹间隔时间(秒)
# 敌机设置
normal_enemy_img = pygame.image.load("enemy.png")
elite_enemy_img = pygame.image.load("boss.png")
enemies = []
enemy_speed = 3 # 降低BOSS飞机的飞行速度
elite_bullets = []
elite_bullet_speed = 5
elite_bullet_angle_range = 60
enemy_bullet_img = pygame.image.load("bossbullet.png")
pygame.mixer.music.load("bg.mp3")
pygame.mixer.music.play(-1)
attack_sound = pygame.mixer.Sound("attack.wav")
bomb_sound = pygame.mixer.Sound("bomb.wav")
# 加载爆炸动画
explosion_images = [pygame.image.load(f"effect/explode_{i}.png") for i in range(8)]
explosion_index = 0
# 加载技能图标
skill1_img = pygame.image.load("skill1.png")
skill2_img = pygame.image.load("skill2.png")
skills = []
skill_speed = 5
# 游戏循环控制
clock = pygame.time.Clock()
running = True
game_over = False
explosions = []
score = 0
lives = 3
bullet_type = 'normal' # 默认子弹类型
def reset_game():
global player_rect, bullets, enemies, elite_bullets, explosions, score, game_over, bullet_timer, lives, skills, bullet_type
player_rect.centerx = screen_width // 2
player_rect.bottom = screen_height - 10
bullets.clear()
enemies.clear()
elite_bullets.clear()
explosions.clear()
skills.clear()
score = 0
game_over = False
bullet_timer = 0
lives = 3
bullet_type = 'normal'
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if game_over:
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
reset_game()
continue
# 控制飞机移动
keys = pygame.key.get_pressed()
if (keys[pygame.K_LEFT] or keys[pygame.K_a]) and player_rect.left > 0:
player_rect.x -= 5
if (keys[pygame.K_RIGHT] or keys[pygame.K_d]) and player_rect.right < screen_width:
player_rect.x += 5
# 鼠标左键发射子弹
mouse_buttons = pygame.mouse.get_pressed()
if mouse_buttons[0] and bullet_timer <= 0 and len(bullets) < bullet_limit:
if bullet_type == 'normal':
bullet_rect = bullet_img.get_rect(center=player_rect.center)
bullets.append(bullet_rect)
elif bullet_type == 'skill1':
for angle in range(0, 360, 30):
bullet_rect = bullet_img.get_rect(center=player_rect.center)
bullet_rect.x += 100 * math.cos(math.radians(angle))
bullet_rect.y += 100 * math.sin(math.radians(angle))
bullets.append(bullet_rect)
elif bullet_type == 'skill2':
for i in range(-2, 3):
bullet_rect = bullet_img.get_rect(center=player_rect.center)
bullet_rect.y -= bullet_speed
bullet_rect.x += i * 15
bullets.append(bullet_rect)
bullet_timer = bullet_cooldown
# 更新子弹位置
for bullet in bullets[:]:
bullet.y -= bullet_speed
if bullet.bottom < 0:
bullets.remove(bullet)
# 生成敌机
if random.randint(1, 30) == 1:
if random.randint(1, 5) == 1:
enemy_rect = elite_enemy_img.get_rect(x=random.randint(0, screen_width - elite_enemy_img.get_width()), y=0)
enemies.append((enemy_rect, 'elite', 5)) # 每个BOSS有5点血
else:
enemy_rect = normal_enemy_img.get_rect(x=random.randint(0, screen_width - normal_enemy_img.get_width()), y=0)
enemies.append((enemy_rect, 'normal', 1)) # 普通敌机血量为1
# 更新敌机位置
for enemy in enemies[:]:
enemy_rect, enemy_type, enemy_health = enemy
enemy_rect.y += enemy_speed
if enemy_type == 'elite' and random.randint(1, 100) == 1:
for angle in range(90 - elite_bullet_angle_range // 2, 90 + elite_bullet_angle_range // 2 + 1, 10):
bullet_dx = elite_bullet_speed * math.cos(math.radians(angle))
bullet_dy = elite_bullet_speed * math.sin(math.radians(angle))
elite_bullet_rect = pygame.Rect(enemy_rect.centerx, enemy_rect.bottom, 10, 20)
elite_bullets.append((elite_bullet_rect, bullet_dx, bullet_dy))
if enemy_rect.top > screen_height:
enemies.remove(enemy)
# 更新精英敌机子弹位置
for elite_bullet in elite_bullets[:]:
elite_bullet_rect, bullet_dx, bullet_dy = elite_bullet
elite_bullet_rect.x += bullet_dx
elite_bullet_rect.y += bullet_dy
if elite_bullet_rect.top > screen_height or elite_bullet_rect.left < 0 or elite_bullet_rect.right > screen_width:
elite_bullets.remove(elite_bullet)
# 碰撞检测
for bullet in bullets[:]:
for enemy in enemies[:]:
enemy_rect, enemy_type, enemy_health = enemy
if bullet.colliderect(enemy_rect):
bullets.remove(bullet)
explosions.append((enemy_rect.topleft, explosion_index))
explosion_index = 0
if enemy_type == 'normal':
score += 1
enemies.remove(enemy)
attack_sound.play()
elif enemy_type == 'elite':
enemy_health -= 1
if enemy_health <= 0:
explosions.append((enemy_rect.topleft, explosion_index))
explosion_index = 0
score += 10
enemies.remove(enemy)
attack_sound.play()
# 随机生成技能图标
if random.choice([True, False]):
skill_rect = skill1_img.get_rect(center=(random.randint(0, screen_width), 0))
skills.append(skill_rect)
else:
skill_rect = skill2_img.get_rect(center=(random.randint(0, screen_width), 0))
skills.append(skill_rect)
else:
enemies[enemies.index(enemy)] = (enemy_rect, enemy_type, enemy_health) # 更新血量
break
# 碰撞检测精英子弹
for elite_bullet in elite_bullets[:]:
elite_bullet_rect, _, _ = elite_bullet
if elite_bullet_rect.colliderect(player_rect):
elite_bullets.remove(elite_bullet)
bomb_sound.play()
lives -= 1
explosions.append((player_rect.topleft, explosion_index))
explosion_index = 0
if lives <= 0:
game_over = True
break
# 碰撞检测敌机
for enemy in enemies[:]:
enemy_rect, enemy_type, _ = enemy
if player_rect.colliderect(enemy_rect):
lives -= 1
explosions.append((player_rect.topleft, explosion_index))
explosion_index = 0
if lives <= 0:
game_over = True
break
# 更新技能图标位置
for skill in skills[:]:
skill.y += skill_speed
if skill.top > screen_height:
skills.remove(skill)
if skill.colliderect(player_rect):
skills.remove(skill)
bullet_type = 'skill1' if skill == skill1_img else 'skill2'
break
# 更新背景位置
background_y += 1
if background_y >= screen_height:
background_y = 0
# 绘制
screen.fill(WHITE)
screen.blit(background_img, (0, background_y))
screen.blit(background_img, (0, background_y - screen_height))
screen.blit(player_img, player_rect)
for bullet in bullets:
screen.blit(bullet_img, bullet)
for enemy in enemies:
enemy_rect, enemy_type, enemy_health = enemy
if enemy_type == 'normal':
screen.blit(normal_enemy_img, enemy_rect)
else:
screen.blit(elite_enemy_img, enemy_rect)
pygame.draw.rect(screen, WHITE, (enemy_rect.x, enemy_rect.y - 10, 100, 10)) # 血条初始为100像素
pygame.draw.rect(screen, RED, (enemy_rect.x, enemy_rect.y - 10, 100 - (20 * (5 - enemy_health)), 10)) # 更新血条
for elite_bullet in elite_bullets:
elite_bullet_rect, _, _ = elite_bullet
screen.blit(enemy_bullet_img, elite_bullet_rect)
for skill in skills:
screen.blit(skill1_img if skill == skill1_img else skill2_img, skill)
for explosion in explosions[:]:
pos, index = explosion
if index < len(explosion_images):
screen.blit(explosion_images[index], pos)
explosions[explosions.index(explosion)] = (pos, index + 1)
else:
explosions.remove(explosion)
# 绘制分数
font = pygame.font.SysFont(None, 36)
score_text = font.render(f"Score: {score}", True, RED)
screen.blit(score_text, (10, 10))
if game_over:
over_text = font.render(f"Game Over! Score: {score} Press SPACE to Restart", True, RED)
screen.blit(over_text, (screen_width // 2 - over_text.get_width() // 2, screen_height // 2))
pygame.display.flip()
bullet_timer -= clock.get_time() / 1000 # 每帧减少计时器
clock.tick(60)
pygame.quit()