import pygame
import random
import sys

# 初始化pygame
pygame.init()

# 游戏设置
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 700
FPS = 60

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 50, 50)
GREEN = (50, 220, 90)
BLUE = (50, 140, 240)
YELLOW = (255, 225, 53)
ORANGE = (245, 165, 35)
PURPLE = (190, 75, 219)
CYAN = (69, 206, 209)

class Player:
    def __init__(self):
        self.width = 48
        self.height = 38
        self.x = SCREEN_WIDTH // 2 - self.width // 2
        self.y = SCREEN_HEIGHT - 160
        self.speed = 6
        self.bullets = []
        self.shoot_cooldown = 0
        
    def move_left(self):
        self.x = max(0, self.x - self.speed)
        
    def move_right(self):
        self.x = min(SCREEN_WIDTH - self.width, self.x + self.speed)
        
    def move_up(self):
        self.y = max(0, self.y - self.speed)
        
    def move_down(self):
        self.y = min(SCREEN_HEIGHT - self.height, self.y + self.speed)
        
    def shoot(self):
        if self.shoot_cooldown <= 0:
            bullet = Bullet(self.x + self.width // 2 - 2, self.y)
            self.bullets.append(bullet)
            self.shoot_cooldown = 15
            
    def update(self):
        if self.shoot_cooldown > 0:
            self.shoot_cooldown -= 1
            
        # 更新子弹
        for bullet in self.bullets[:]:
            bullet.update()
            if bullet.y < 0:
                self.bullets.remove(bullet)
                
    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

class Bullet:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 4
        self.height = 12
        self.speed = 8
        
    def update(self):
        self.y -= self.speed
        
    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

class Enemy:
    def __init__(self, enemy_type="normal"):
        self.type = enemy_type
        
        if enemy_type == "normal":
            self.width = 32
            self.height = 28
            self.hp = 1
            self.color = RED
            self.score_value = 10
        elif enemy_type == "fast":
            self.width = 26
            self.height = 22
            self.hp = 1
            self.color = YELLOW
            self.score_value = 20
        elif enemy_type == "tank":
            self.width = 44
            self.height = 34
            self.hp = 3
            self.color = PURPLE
            self.score_value = 50
            
        self.x = random.randint(0, SCREEN_WIDTH - self.width)
        self.y = -self.height
        self.speed = random.randint(2, 4)
        
        if enemy_type == "fast":
            self.speed = random.randint(4, 7)
        elif enemy_type == "tank":
            self.speed = random.randint(1, 2)
            
    def update(self):
        self.y += self.speed
        
    def hit(self):
        self.hp -= 1
        return self.hp <= 0
        
    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

class PowerUp:
    def __init__(self):
        self.width = 18
        self.height = 9
        self.x = random.randint(0, SCREEN_WIDTH - self.width)
        self.y = -self.height
        self.speed = 2
        self.type = random.choice(["shield", "rapid_fire"])
        
        if self.type == "shield":
            self.color = CYAN
        else:
            self.color = ORANGE
            
    def update(self):
        self.y += self.speed
        
    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

class Star:
    def __init__(self):
        self.x = random.randint(0, SCREEN_WIDTH)
        self.y = random.randint(0, SCREEN_HEIGHT)
        self.size = random.randint(1, 3)
        self.speed = random.uniform(0.5, 2)
        self.brightness = random.randint(100, 255)
        
    def update(self):
        self.y += self.speed
        if self.y > SCREEN_HEIGHT:
            self.y = 0
            self.x = random.randint(0, SCREEN_WIDTH)

def draw_player(screen, player):
    # 机身主体
    body_points = [
        (player.x + player.width // 2, player.y),
        (player.x + player.width, player.y + player.height // 2),
        (player.x + player.width - 8, player.y + player.height // 2 + 4),
        (player.x + player.width - 8, player.y + player.height - 4),
        (player.x + player.width, player.y + player.height),
        (player.x + player.width // 2, player.y + player.height - 8),
        (player.x, player.y + player.height),
        (player.x + 8, player.y + player.height - 4),
        (player.x + 8, player.y + player.height // 2 + 4),
        (player.x, player.y + player.height // 2)
    ]
    pygame.draw.polygon(screen, BLUE, body_points)
    
    # 驾驶舱
    cockpit_points = [
        (player.x + player.width // 2, player.y + 6),
        (player.x + player.width // 2 - 8, player.y + 14),
        (player.x + player.width // 2 + 8, player.y + 14)
    ]
    pygame.draw.polygon(screen, CYAN, cockpit_points)
    
    # 机翼装饰
    pygame.draw.line(screen, WHITE, 
                    (player.x + 10, player.y + player.height // 2),
                    (player.x + player.width - 10, player.y + player.height // 2), 2)

def draw_enemy(screen, enemy):
    if enemy.type == "normal":
        points = [
            (enemy.x + enemy.width // 2, enemy.y),
            (enemy.x + enemy.width, enemy.y + enemy.height // 2),
            (enemy.x + enemy.width - 6, enemy.y + enemy.height // 2 + 3),
            (enemy.x + enemy.width - 6, enemy.y + enemy.height - 3),
            (enemy.x + enemy.width, enemy.y + enemy.height),
            (enemy.x + enemy.width // 2, enemy.y + enemy.height - 6),
            (enemy.x, enemy.y + enemy.height),
            (enemy.x + 6, enemy.y + enemy.height - 3),
            (enemy.x + 6, enemy.y + enemy.height // 2 + 3),
            (enemy.x, enemy.y + enemy.height // 2)
        ]
        pygame.draw.polygon(screen, enemy.color, points)
        
    elif enemy.type == "fast":
        points = [
            (enemy.x + enemy.width // 2, enemy.y),
            (enemy.x + enemy.width, enemy.y + enemy.height // 2),
            (enemy.x + enemy.width // 2, enemy.y + enemy.height),
            (enemy.x, enemy.y + enemy.height // 2)
        ]
        pygame.draw.polygon(screen, enemy.color, points)
        
    elif enemy.type == "tank":
        # 大型敌人
        pygame.draw.rect(screen, enemy.color, 
                        (enemy.x, enemy.y, enemy.width, enemy.height), 
                        border_radius=4)
        # 装甲线
        pygame.draw.line(screen, BLACK, 
                        (enemy.x, enemy.y + enemy.height // 2),
                        (enemy.x + enemy.width, enemy.y + enemy.height // 2), 2)
        # 生命值指示器
        for i in range(enemy.hp):
            hp_x = enemy.x + 8 + i * 12
            hp_y = enemy.y + enemy.height // 2 - 4
            pygame.draw.circle(screen, WHITE, (hp_x, hp_y), 3)

def show_start_screen(screen):
    font_title = pygame.font.Font(None, 64)
    font_info = pygame.font.Font(None, 42)
    font_hint = pygame.font.Font(None, 28)
    
    title = font_title.render("太空防御者", True, WHITE)
    subtitle = font_info.render("Space Defender", True, CYAN)
    hint1 = font_hint.render("按 ENTER 开始游戏", True, YELLOW)
    hint2 = font_hint.render("方向键移动 | 空格射击", True, WHITE)
    
    screen.blit(title, (SCREEN_WIDTH // 2 - title.get_width() // 2, SCREEN_HEIGHT // 2 - 100))
    screen.blit(subtitle, (SCREEN_WIDTH // 2 - subtitle.get_width() // 2, SCREEN_HEIGHT // 2 - 30))
    screen.blit(hint1, (SCREEN_WIDTH // 2 - hint1.get_width() // 2, SCREEN_HEIGHT // 2 + 40))
    screen.blit(hint2, (SCREEN_WIDTH // 2 - hint2.get_width() // 2, SCREEN_HEIGHT // 2 + 85))

def show_game_over(screen, score, high_score):
    font_large = pygame.font.Font(None, 56)
    font_medium = pygame.font.Font(None, 46)
    font_small = pygame.font.Font(None, 33)
    
    game_over = font_large.render("GAME OVER", True, RED)
    score_text = font_medium.render(f"得分: {score}", True, WHITE)
    high_score_text = font_small.render(f"最高分: {high_score}", True, YELLOW)
    restart_text = font_small.render("按 SPACE 重新开始", True, CYAN)
    quit_text = font_small.render("按 ESC 退出", True, WHITE)
    
    screen.blit(game_over, (SCREEN_WIDTH // 2 - game_over.get_width() // 2, SCREEN_HEIGHT // 2 - 110))
    screen.blit(score_text, (SCREEN_WIDTH // 2 - score_text.get_width() // 2, SCREEN_HEIGHT // 2 - 40))
    screen.blit(high_score_text, (SCREEN_WIDTH // 2 - high_score_text.get_width() // 2, SCREEN_HEIGHT // 2 + 10))
    screen.blit(restart_text, (SCREEN_WIDTH // 2 - restart_text.get_width() // 2, SCREEN_HEIGHT // 2 + 65))
    screen.blit(quit_text, (SCREEN_WIDTH // 2 - quit_text.get_width() // 2, SCREEN_HEIGHT // 2 + 105))

def main():
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption("飞行躲避 - 太空防御者")
    clock = pygame.time.Clock()
    
    # 游戏状态
    game_state = "start"  # start, playing, gameover
    score = 0
    high_score = 0
    level = 1
    shield_active = False
    rapid_fire_active = False
    powerup_timer = 0
    
    # 游戏对象
    player = Player()
    enemies = []
    powerups = []
    stars = [Star() for _ in range(40)]
    
    # 生成控制
    spawn_timer = 0
    spawn_rate = 60
    
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                
            if event.type == pygame.KEYDOWN:
                if game_state == "start" and event.key == pygame.K_RETURN:
                    game_state = "playing"
                    
                elif game_state == "gameover":
                    if event.key == pygame.K_SPACE:
                        # 重新开始
                        player = Player()
                        enemies.clear()
                        powerups.clear()
                        score = 0
                        level = 1
                        shield_active = False
                        rapid_fire_active = False
                        spawn_rate = 60
                        game_state = "playing"
                    elif event.key == pygame.K_ESCAPE:
                        running = False
                        
        # 游戏逻辑
        keys = pygame.key.get_pressed()
        
        if game_state == "playing":
            # 玩家移动
            if keys[pygame.K_LEFT] or keys[pygame.K_a]:
                player.move_left()
            if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
                player.move_right()
            if keys[pygame.K_UP] or keys[pygame.K_w]:
                player.move_up()
            if keys[pygame.K_DOWN] or keys[pygame.K_s]:
                player.move_down()
                
            # 射击
            if keys[pygame.K_SPACE]:
                if rapid_fire_active:
                    player.shoot_cooldown = min(player.shoot_cooldown, 5)
                player.shoot()
                
            player.update()
            
            # 更新道具计时器
            if shield_active or rapid_fire_active:
                powerup_timer -= 1
                if powerup_timer <= 0:
                    shield_active = False
                    rapid_fire_active = False
                    
            # 生成敌人
            spawn_timer += 1
            if spawn_timer >= spawn_rate:
                spawn_timer = 0
                # 根据等级决定敌人类型
                rand_val = random.random()
                if rand_val < 0.6:
                    enemy_type = "normal"
                elif rand_val < 0.82:
                    enemy_type = "fast"
                else:
                    enemy_type = "tank"
                    
                # 限制坦克数量
                if enemy_type == "tank" and sum(1 for e in enemies if e.type == "tank") >= 2:
                    enemy_type = "normal"
                    
                enemies.append(Enemy(enemy_type))
                
                # 随机生成道具
                if random.random() < 0.03:
                    powerups.append(PowerUp())
                    
            # 更新敌人
            for enemy in enemies[:]:
                enemy.update()
                if enemy.y > SCREEN_HEIGHT:
                    enemies.remove(enemy)
                    
            # 更新道具
            for powerup in powerups[:]:
                powerup.update()
                if powerup.y > SCREEN_HEIGHT:
                    powerups.remove(powerup)
                    
            # 检测子弹与敌人碰撞
            for bullet in player.bullets[:]:
                bullet_rect = bullet.get_rect()
                for enemy in enemies[:]:
                    if bullet_rect.colliderect(enemy.get_rect()):
                        if enemy.hit():
                            score += enemy.score_value
                            enemies.remove(enemy)
                        if bullet in player.bullets:
                            player.bullets.remove(bullet)
                        break
                        
            # 检测玩家与敌人碰撞
            player_rect = player.get_rect()
            for enemy in enemies[:]:
                if player_rect.colliderect(enemy.get_rect()):
                    if shield_active:
                        enemies.remove(enemy)
                        score += enemy.score_value // 2
                    else:
                        game_state = "gameover"
                        if score > high_score:
                            high_score = score
                        break
                        
            # 检测玩家与道具碰撞
            for powerup in powerups[:]:
                if player_rect.colliderect(powerup.get_rect()):
                    if powerup.type == "shield":
                        shield_active = True
                        powerup_timer = 300  # 5秒
                    elif powerup.type == "rapid_fire":
                        rapid_fire_active = True
                        powerup_timer = 360  # 6秒
                    powerups.remove(powerup)
                    
            # 升级系统
            if score > level * 500:
                level += 1
                spawn_rate = max(20, spawn_rate - 5)
                
        # 更新星星背景
        for star in stars:
            star.update()
            
        # 绘制
        screen.fill(BLACK)
        
        # 绘制星星
        for star in stars:
            pygame.draw.circle(screen, (star.brightness,) * 3, 
                             (int(star.x), int(star.y)), star.size)
            
        if game_state == "start":
            show_start_screen(screen)
        elif game_state == "playing":
            # 绘制道具
            for powerup in powerups:
                pygame.draw.ellipse(screen, powerup.color, powerup.get_rect())
                # 道具图标
                if powerup.type == "shield":
                    pygame.draw.circle(screen, WHITE, 
                                     (powerup.x + powerup.width // 2, 
                                      powerup.y + powerup.height // 2), 4)
                else:
                    pygame.draw.rect(screen, WHITE, 
                                   (powerup.x + 4, powerup.y + 2, 10, 5))
                    
            # 绘制敌人
            for enemy in enemies:
                draw_enemy(screen, enemy)
                
            # 绘制子弹
            for bullet in player.bullets:
                pygame.draw.rect(screen, YELLOW, bullet.get_rect())
                
            # 绘制玩家
            draw_player(screen, player)
            
            # 护盾效果
            if shield_active:
                shield_surf = pygame.Surface((player.width + 20, player.height + 20), 
                                           pygame.SRCALPHA)
                pygame.draw.ellipse(shield_surf, (69, 222, 182, 77), 
                                  shield_surf.get_rect(), 3)
                screen.blit(shield_surf, (player.x - 10, player.y - 10))
                
            # HUD
            font = pygame.font.Font(None, 27)
            score_text = font.render(f"得分: {score}", True, WHITE)
            level_text = font.render(f"等级: {level}", True, CYAN)
            shield_text = font.render("护盾" if shield_active else "", True, CYAN)
            rapid_text = font.render("速射" if rapid_fire_active else "", True, ORANGE)
            
            screen.blit(score_text, (10, 17))
            screen.blit(level_text, (10, 47))
            if shield_active:
                screen.blit(shield_text, (SCREEN_WIDTH - 78, 23))
            if rapid_fire_active:
                screen.blit(rapid_text, (SCREEN_WIDTH - 88, 52))
                
        elif game_state == "gameover":
            show_game_over(screen, score, high_score)
            
        pygame.display.flip()
        clock.tick(FPS)
        
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()