import pygame
import random

# ============ 基础设置 ============
WIDTH, HEIGHT = 480, 700
FPS = 60

# 色彩定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 35, 35)
YELLOW = (255, 225, 0)
BLUE = (0, 170, 255)
LIGHT_BLUE = (120, 220, 255)
DARK_RED = (160, 20, 20)
SKY_TOP = (12, 18, 40)
SKY_BOTTOM = (35, 55, 95)

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("美化飞机大战-带机翼")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 36)

# 星空背景
class Star:
    def __init__(self):
        self.x = random.randint(0, WIDTH)
        self.y = random.randint(-HEIGHT, HEIGHT)
        self.speed = random.uniform(1, 3)
        self.radius = random.uniform(1, 2.5)

    def update(self):
        self.y += self.speed
        if self.y > HEIGHT:
            self.y = -10
            self.x = random.randint(0, WIDTH)

    def draw(self):
        pygame.draw.circle(screen, WHITE, (int(self.x), int(self.y)), self.radius)

# 玩家飞机【绘制机身+左右机翼】
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        w, h = 46, 64
        self.image = pygame.Surface((w, h), pygame.SRCALPHA)
        # 机身主体
        pygame.draw.ellipse(self.image, BLUE, (12, 4, 22, 56))
        # 左侧机翼
        pygame.draw.polygon(self.image, BLUE, [(12, 30), (0, 46), (12, 42)])
        # 右侧机翼
        pygame.draw.polygon(self.image, BLUE, [(34, 30), (46, 46), (34, 42)])
        # 高光描边
        pygame.draw.ellipse(self.image, LIGHT_BLUE, (14, 6, 18, 52), width=2)
        pygame.draw.polygon(self.image, LIGHT_BLUE, [(12, 30), (0, 46), (12, 42)], width=1)
        pygame.draw.polygon(self.image, LIGHT_BLUE, [(34, 30), (46, 46), (34, 42)], width=1)
        # 机头光点
        pygame.draw.circle(self.image, YELLOW, (23, 8), 3)

        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH // 2
        self.rect.bottom = HEIGHT - 25
        self.speed = 8

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT] and self.rect.left > 0:
            self.rect.x -= self.speed
        if keys[pygame.K_RIGHT] and self.rect.right < WIDTH:
            self.rect.x += self.speed
        if keys[pygame.K_UP] and self.rect.top > 0:
            self.rect.y -= self.speed
        if keys[pygame.K_DOWN] and self.rect.bottom < HEIGHT:
            self.rect.y += self.speed

# 敌机【带机翼】
class Enemy(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        w, h = 42, 56
        self.image = pygame.Surface((w, h), pygame.SRCALPHA)
        # 敌机机身
        pygame.draw.ellipse(self.image, RED, (10, 4, 22, 48))
        # 机翼
        pygame.draw.polygon(self.image, RED, [(10, 26), (0, 38), (10, 34)])
        pygame.draw.polygon(self.image, RED, [(32, 26), (42, 38), (32, 34)])
        pygame.draw.ellipse(self.image, (255,160,160), (12,6,18,44), width=2)

        self.rect = self.image.get_rect()
        self.rect.x = random.randint(0, WIDTH - self.rect.width)
        self.rect.y = random.randint(-120, -40)
        self.speed = random.randint(3, 6)

    def update(self):
        self.rect.y += self.speed
        if self.rect.top > HEIGHT:
            self.rect.x = random.randint(0, WIDTH - self.rect.width)
            self.rect.y = random.randint(-120, -40)
            self.speed = random.randint(3, 6)

# 子弹
class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        w, h = 6, 18
        self.image = pygame.Surface((w, h), pygame.SRCALPHA)
        pygame.draw.rect(self.image, YELLOW, (0, 0, w, h), border_radius=3)
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.bottom = y
        self.speed = 11

    def update(self):
        self.rect.y -= self.speed
        if self.rect.bottom < 0:
            self.kill()

# 爆炸粒子
class Explosion:
    def __init__(self, x, y):
        self.particles = []
        for _ in range(12):
            px = x
            py = y
            dx = random.randint(-4, 4)
            dy = random.randint(-4, 4)
            self.particles.append([px, py, dx, dy, random.randint(3, 6)])

    def update(self):
        for p in self.particles:
            p[0] += p[2]
            p[1] += p[3]
            p[4] -= 0.25
        self.particles = [p for p in self.particles if p[4] > 0]

    def draw(self):
        for p in self.particles:
            pygame.draw.circle(screen, (255, 130, 0), (int(p[0]), int(p[1])), p[4])

    def alive(self):
        return len(self.particles) > 0

# ============ 初始化 ============
all_sprites = pygame.sprite.Group()
bullet_group = pygame.sprite.Group()
enemy_group = pygame.sprite.Group()

player = Player()
all_sprites.add(player)

for _ in range(8):
    e = Enemy()
    all_sprites.add(e)
    enemy_group.add(e)

star_list = [Star() for _ in range(80)]
explosion_list = []

score = 0
shoot_cd = 0
game_over = False
running = True

# ============ 主循环 ============
while running:
    clock.tick(FPS)

    # 渐变夜空
    for ly in range(HEIGHT):
        ratio = ly / HEIGHT
        r = int(SKY_TOP[0] * (1-ratio) + SKY_BOTTOM[0] * ratio)
        g = int(SKY_TOP[1] * (1-ratio) + SKY_BOTTOM[1] * ratio)
        b = int(SKY_TOP[2] * (1-ratio) + SKY_BOTTOM[2] * ratio)
        pygame.draw.line(screen, (r, g, b), (0, ly), (WIDTH, ly))

    # 绘制星空
    for star in star_list:
        star.update()
        star.draw()

    # 事件监听
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    if not game_over:
        shoot_cd += 1
        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE] and shoot_cd > 14:
            bullet = Bullet(player.rect.centerx, player.rect.top)
            all_sprites.add(bullet)
            bullet_group.add(bullet)
            shoot_cd = 0

        all_sprites.update()

        # 子弹击中敌机
        hits = pygame.sprite.groupcollide(enemy_group, bullet_group, True, True)
        for hit in hits:
            score += 10
            explosion_list.append(Explosion(hit.rect.centerx, hit.rect.centery))
            new_e = Enemy()
            all_sprites.add(new_e)
            enemy_group.add(new_e)

        # 撞击判定
        if pygame.sprite.spritecollide(player, enemy_group, True):
            explosion_list.append(Explosion(player.rect.centerx, player.rect.centery))
            game_over = True

        all_sprites.draw(screen)

        # 爆炸效果
        for exp in explosion_list:
            exp.update()
            exp.draw()
        explosion_list = [e for e in explosion_list if e.alive()]

        # 分数UI面板
        panel = pygame.Surface((130, 42), pygame.SRCALPHA)
        panel.fill((0, 0, 0, 160))
        screen.blit(panel, (8, 8))
        score_text = font.render(f"分数：{score}", True, WHITE)
        screen.blit(score_text, (14, 12))

    else:
        over_text = font.render("游戏结束！", True, RED)
        final_text = font.render(f"得分：{score}", True, YELLOW)
        screen.blit(over_text, (WIDTH//2 - 82, HEIGHT//2 - 60))
        screen.blit(final_text, (WIDTH//2 - 75, HEIGHT//2 - 10))

    pygame.display.flip()

pygame.quit()