import tkinter as tk
import random
import math
from typing import List, Tuple

class ShootingGame:
    def __init__(self, root):
        self.root = root
        self.root.title("二维移动射击游戏")
        
        # 游戏区域大小
        self.canvas_width = 800
        self.canvas_height = 600
        
        # 创建画布
        self.canvas = tk.Canvas(
            root, 
            width=self.canvas_width,
            height=self.canvas_height,
            bg="black"
        )
        self.canvas.pack()
        
        # 游戏状态
        self.running = True
        self.score = 0
        self.game_over = False
        
        # 玩家属性
        self.player_size = 20
        self.player_speed = 5
        self.player_x = self.canvas_width // 2
        self.player_y = self.canvas_height - 50
        
        # 玩家生命值
        self.player_health = 3
        
        # 子弹属性
        self.bullet_speed = 8
        self.bullets: List[Tuple[int, int, int]] = []  # (x, y, id)
        
        # 敌人属性
        self.enemy_speed = 2
        self.enemy_spawn_rate = 0.02
        self.enemies: List[Tuple[int, int, int, int]] = []  # (x, y, id, health)
        
        # 敌人生成计数器
        self.enemy_counter = 0
        
        # 绘制初始元素
        self.draw_player()
        self.draw_hud()
        
        # 绑定按键事件
        self.root.bind("<KeyPress>", self.on_key_press)
        self.root.bind("<KeyRelease>", self.on_key_release)
        self.root.bind("<space>", self.shoot)
        
        # 当前按下的按键
        self.keys_pressed = set()
        
        # 开始游戏循环
        self.game_loop()
        
    def draw_player(self):
        """绘制玩家飞船"""
        if hasattr(self, 'player_id'):
            self.canvas.delete(self.player_id)
        
        # 创建三角形飞船
        points = [
            self.player_x, self.player_y - self.player_size,  # 顶点
            self.player_x - self.player_size, self.player_y + self.player_size,  # 左下
            self.player_x + self.player_size, self.player_y + self.player_size   # 右下
        ]
        
        self.player_id = self.canvas.create_polygon(
            points, 
            fill="blue", 
            outline="white", 
            width=2
        )
        
    def draw_hud(self):
        """绘制HUD（分数、生命值）"""
        # 清空旧的HUD
        if hasattr(self, 'hud_id'):
            self.canvas.delete(self.hud_id)
        
        # 分数
        score_text = f"分数: {self.score}"
        score_id = self.canvas.create_text(
            10, 10, 
            text=score_text, 
            anchor="nw", 
            fill="white", 
            font=("Arial", 16)
        )
        
        # 生命值
        health_text = f"生命值: {'♥' * self.player_health}"
        health_id = self.canvas.create_text(
            self.canvas_width - 10, 10, 
            text=health_text, 
            anchor="ne", 
            fill="red", 
            font=("Arial", 16)
        )
        
        self.hud_id = (score_id, health_id)
        
    def on_key_press(self, event):
        """处理按键按下"""
        self.keys_pressed.add(event.keysym)
        
    def on_key_release(self, event):
        """处理按键释放"""
        if event.keysym in self.keys_pressed:
            self.keys_pressed.remove(event.keysym)
            
    def move_player(self):
        """移动玩家"""
        moved = False
        
        if "Left" in self.keys_pressed and self.player_x > self.player_size:
            self.player_x -= self.player_speed
            moved = True
        if "Right" in self.keys_pressed and self.player_x < self.canvas_width - self.player_size:
            self.player_x += self.player_speed
            moved = True
        if "Up" in self.keys_pressed and self.player_y > self.player_size:
            self.player_y -= self.player_speed
            moved = True
        if "Down" in self.keys_pressed and self.player_y < self.canvas_height - self.player_size:
            self.player_y += self.player_speed
            moved = True
            
        if moved:
            self.draw_player()
            
    def shoot(self, event=None):
        """发射子弹"""
        bullet_id = self.canvas.create_rectangle(
            self.player_x - 2, 
            self.player_y - self.player_size - 10,
            self.player_x + 2, 
            self.player_y - self.player_size,
            fill="yellow",
            outline="orange"
        )
        self.bullets.append((self.player_x, self.player_y - self.player_size, bullet_id))
        
    def move_bullets(self):
        """移动子弹"""
        bullets_to_remove = []
        
        for i, (x, y, bullet_id) in enumerate(self.bullets):
            new_y = y - self.bullet_speed
            
            # 检查子弹是否飞出屏幕
            if new_y < 0:
                bullets_to_remove.append(i)
                continue
                
            # 移动子弹
            self.canvas.coords(bullet_id, 
                x - 2, new_y - 5,
                x + 2, new_y
            )
            self.bullets[i] = (x, new_y, bullet_id)
            
        # 移除出界的子弹
        for index in reversed(bullets_to_remove):
            bullet_id = self.bullets[index][2]
            self.canvas.delete(bullet_id)
            del self.bullets[index]
            
    def spawn_enemy(self):
        """生成敌人"""
        self.enemy_counter += 1
        if random.random() < self.enemy_spawn_rate:
            x = random.randint(20, self.canvas_width - 20)
            y = random.randint(20, 100)
            
            # 随机敌人大小
            size = random.randint(15, 30)
            health = 1 if size < 20 else 2
            
            enemy_id = self.canvas.create_oval(
                x - size, y - size,
                x + size, y + size,
                fill="red" if health == 1 else "darkred",
                outline="white"
            )
            self.enemies.append((x, y, enemy_id, health))
            
    def move_enemies(self):
        """移动敌人"""
        for i, (x, y, enemy_id, health) in enumerate(self.enemies):
            new_y = y + self.enemy_speed
            
            # 移动敌人
            size = 15 if health == 1 else 20
            self.canvas.coords(enemy_id,
                x - size, new_y - size,
                x + size, new_y + size
            )
            
            # 检查敌人是否与玩家碰撞
            distance = math.sqrt((x - self.player_x)**2 + (new_y - self.player_y)**2)
            if distance < self.player_size + size:
                self.player_health -= 1
                self.canvas.delete(enemy_id)
                del self.enemies[i]
                self.draw_hud()
                if self.player_health <= 0:
                    self.game_over = True
                break
                
            # 检查是否飞出屏幕
            if new_y > self.canvas_height + size:
                self.canvas.delete(enemy_id)
                del self.enemies[i]
                break
            else:
                self.enemies[i] = (x, new_y, enemy_id, health)
                
    def check_collisions(self):
        """检查子弹与敌人的碰撞"""
        bullets_to_remove = []
        enemies_to_remove = []
        
        for bullet_idx, (bullet_x, bullet_y, bullet_id) in enumerate(self.bullets):
            for enemy_idx, (enemy_x, enemy_y, enemy_id, enemy_health) in enumerate(self.enemies):
                distance = math.sqrt((bullet_x - enemy_x)**2 + (bullet_y - enemy_y)**2)
                size = 15 if enemy_health == 1 else 20
                
                if distance < size:  # 碰撞检测
                    # 减少敌人生命值
                    if enemy_health > 1:
                        # 减少生命值
                        new_health = enemy_health - 1
                        self.enemies[enemy_idx] = (enemy_x, enemy_y, enemy_id, new_health)
                        # 改变颜色
                        self.canvas.itemconfig(enemy_id, fill="red")
                    else:
                        # 敌人被消灭
                        self.score += 10
                        self.canvas.delete(enemy_id)
                        enemies_to_remove.append(enemy_idx)
                    
                    # 移除子弹
                    bullets_to_remove.append(bullet_idx)
                    break
        
        # 移除碰撞的子弹
        for idx in reversed(sorted(set(bullets_to_remove))):
            if idx < len(self.bullets):
                bullet_id = self.bullets[idx][2]
                self.canvas.delete(bullet_id)
                del self.bullets[idx]
        
        # 移除被消灭的敌人
        for idx in reversed(sorted(set(enemies_to_remove))):
            if idx < len(self.enemies):
                del self.enemies[idx]
                
    def game_loop(self):
        """游戏主循环"""
        if not self.running or self.game_over:
            if self.game_over:
                self.show_game_over()
            return
            
        # 移动玩家
        self.move_player()
        
        # 移动子弹
        self.move_bullets()
        
        # 生成敌人
        self.spawn_enemy()
        
        # 移动敌人
        self.move_enemies()
        
        # 检查碰撞
        self.check_collisions()
        
        # 更新HUD
        self.draw_hud()
        
        # 继续游戏循环
        self.root.after(16, self.game_loop)  # ~60 FPS
        
    def show_game_over(self):
        """显示游戏结束画面"""
        self.canvas.create_text(
            self.canvas_width // 2,
            self.canvas_height // 2,
            text=f"游戏结束!\n最终分数: {self.score}",
            fill="white",
            font=("Arial", 36, "bold"),
            justify="center"
        )
        
        # 重新开始按钮
        restart_btn = tk.Button(
            self.root,
            text="重新开始",
            command=self.restart_game,
            font=("Arial", 16),
            bg="green",
            fg="white"
        )
        self.canvas.create_window(
            self.canvas_width // 2,
            self.canvas_height // 2 + 80,
            window=restart_btn
        )
        
    def restart_game(self):
        """重新开始游戏"""
        # 清除所有画布元素
        self.canvas.delete("all")
        
        # 重置游戏状态
        self.score = 0
        self.player_health = 3
        self.game_over = False
        self.bullets = []
        self.enemies = []
        self.player_x = self.canvas_width // 2
        self.player_y = self.canvas_height - 50
        
        # 重新绘制
        self.draw_player()
        self.draw_hud()
        
        # 重新开始游戏循环
        self.game_loop()
        
def main():
    root = tk.Tk()
    game = ShootingGame(root)
    root.mainloop()

if __name__ == "__main__":
    main()