import tkinter as tk
import random
import math

WIDTH, HEIGHT = 600, 700
FPS = 16  # ≈60 FPS

class Bullet:
    def __init__(self, canvas, x, y):
        self.canvas = canvas
        self.id = canvas.create_oval(
            x - 3, y - 10,
            x + 3, y,
            fill="yellow", outline="orange", width=1
        )
        self.speed = 14

    def move(self):
        self.canvas.move(self.id, 0, -self.speed)
        pos = self.canvas.coords(self.id)
        return pos[1] < 0

    def destroy(self):
        self.canvas.delete(self.id)

    def get_bounds(self):
        return self.canvas.coords(self.id)


class Enemy:
    def __init__(self, canvas):
        self.canvas = canvas
        self.x = random.randint(40, WIDTH - 40)
        self.y = random.randint(-120, -40)
        self.size = 28
        self.speed = random.uniform(2.2, 3.8)

        self.id = canvas.create_rectangle(
            self.x - self.size, self.y - self.size,
            self.x + self.size, self.y + self.size,
            fill="#f44336", outline="#b71c1c", width=2
        )

    def move(self):
        self.canvas.move(self.id, 0, self.speed)
        pos = self.canvas.coords(self.id)
        return pos[3] > HEIGHT

    def destroy(self):
        self.canvas.delete(self.id)

    def get_bounds(self):
        return self.canvas.coords(self.id)


class Player:
    def __init__(self, canvas):
        self.canvas = canvas
        self.x = WIDTH // 2
        self.y = HEIGHT - 80
        self.speed = 7

        self.id = canvas.create_polygon(
            self.x, self.y - 25,
            self.x - 20, self.y + 15,
            self.x + 20, self.y + 15,
            fill="#4CAF50", outline="#1B5E20", width=2
        )

        # 推进器火焰
        self.flame = canvas.create_polygon(
            self.x, self.y + 15,
            self.x - 8, self.y + 30,
            self.x + 8, self.y + 30,
            fill="orange", outline=""
        )

    def move(self, dx, dy):
        self.x += dx * self.speed
        self.y += dy * self.speed

        # 边界限制
        self.x = max(20, min(WIDTH - 20, self.x))
        self.y = max(50, min(HEIGHT - 50, self.y))

        self.canvas.coords(
            self.id,
            self.x, self.y - 25,
            self.x - 20, self.y + 15,
            self.x + 20, self.y + 15
        )
        self.canvas.coords(
            self.flame,
            self.x, self.y + 15,
            self.x - 8, self.y + 30,
            self.x + 8, self.y + 30
        )

    def get_bounds(self):
        return self.canvas.coords(self.id)


class ShootingGame:
    def __init__(self, root):
        self.root = root
        self.root.title("015. 二维移动射击")
        self.root.resizable(False, False)

        self.canvas = tk.Canvas(
            root, width=WIDTH, height=HEIGHT, bg="#0d1b2a"
        )
        self.canvas.pack()

        # 星空背景
        for _ in range(60):
            x = random.randint(0, WIDTH)
            y = random.randint(0, HEIGHT)
            r = random.randint(1, 2)
            self.canvas.create_oval(
                x, y, x + r, y + r,
                fill="white", outline=""
            )

        self.player = Player(self.canvas)
        self.bullets = []
        self.enemies = []
        self.score = 0
        self.game_over = False

        self.score_text = self.canvas.create_text(
            70, 25, text="得分: 0",
            font=("Consolas", 14, "bold"), fill="white"
        )

        self.keys = set()
        self.bind_keys()
        self.spawn_enemy()
        self.game_loop()

    def bind_keys(self):
        self.root.bind("<KeyPress>", self.key_down)
        self.root.bind("<KeyRelease>", self.key_up)
        self.root.bind("<space>", lambda e: self.shoot())
        self.root.focus_set()

    def key_down(self, e):
        self.keys.add(e.keysym.lower())

    def key_up(self, e):
        self.keys.discard(e.keysym.lower())

    def handle_input(self):
        dx = dy = 0
        if "a" in self.keys:
            dx -= 1
        if "d" in self.keys:
            dx += 1
        if "w" in self.keys:
            dy -= 1
        if "s" in self.keys:
            dy += 1
        self.player.move(dx, dy)

    def shoot(self):
        if self.game_over:
            return
        bullet = Bullet(self.canvas, self.player.x, self.player.y - 25)
        self.bullets.append(bullet)

    def spawn_enemy(self):
        if self.game_over:
            return
        self.enemies.append(Enemy(self.canvas))
        delay = max(600, 1200 - self.score * 10)
        self.root.after(delay, self.spawn_enemy)

    def check_collisions(self):
        # 子弹 vs 敌机
        for bullet in self.bullets[:]:
            b_bounds = bullet.get_bounds()
            for enemy in self.enemies[:]:
                e_bounds = enemy.get_bounds()
                if (b_bounds[2] > e_bounds[0] and
                    b_bounds[0] < e_bounds[2] and
                    b_bounds[3] > e_bounds[1] and
                    b_bounds[1] < e_bounds[3]):
                    bullet.destroy()
                    enemy.destroy()
                    self.bullets.remove(bullet)
                    self.enemies.remove(enemy)
                    self.score += 1
                    self.canvas.itemconfig(
                        self.score_text, text=f"得分: {self.score}"
                    )
                    break

        # 玩家 vs 敌机
        p_bounds = self.player.get_bounds()
        for enemy in self.enemies:
            e_bounds = enemy.get_bounds()
            if (p_bounds[2] > e_bounds[0] and
                p_bounds[0] < e_bounds[2] and
                p_bounds[3] > e_bounds[1] and
                p_bounds[1] < e_bounds[3]):
                self.game_over = True
                self.canvas.create_text(
                    WIDTH // 2, HEIGHT // 2,
                    text="游戏结束！\n按 R 重新开始",
                    font=("Microsoft YaHei", 22, "bold"),
                    fill="yellow", justify=tk.CENTER
                )
                self.root.bind("<r>", lambda e: self.restart())
                return

    def game_loop(self):
        if self.game_over:
            return

        self.handle_input()

        # 更新子弹
        for bullet in self.bullets[:]:
            if bullet.move():
                bullet.destroy()
                self.bullets.remove(bullet)

        # 更新敌机
        for enemy in self.enemies[:]:
            if enemy.move():
                enemy.destroy()
                self.enemies.remove(enemy)

        self.check_collisions()
        self.root.after(FPS, self.game_loop)

    def restart(self):
        self.canvas.delete("all")
        self.__init__(self.root)


if __name__ == "__main__":
    root = tk.Tk()
    ShootingGame(root)
    root.mainloop()