import tkinter as tk from tkinter import messagebox, font import random import time import threading import math

class Game: def init(self, root): self.root = root self.root.title("彩虹六号:炸弹冲锋2D简化版") self.root.geometry("1024x768") self.root.resizable(False, False)

    # 设置中文字体
    self.font_family = "SimHei"
    
    # 游戏状态
    self.game_active = False
    self.defender_turn = False
    self.attacker_turn = False
    self.bomb_planted = False
    self.bomb_defused = False
    self.defender_wins = False
    self.attacker_wins = False
    
    # 计时器相关
    self.defense_timer = 60  # 1分钟防御准备时间
    self.game_timer = 300  # 5分钟游戏时间
    self.timer_running = False
    
    # 玩家和AI数量
    self.player_count = 1
    self.ai_count = 4
    self.total_players = self.player_count + self.ai_count
    
    # 游戏对象
    self.defenders = []
    self.attackers = []
    self.defense_objects = []
    self.bomb_site = {"x": 512, "y": 384, "radius": 50}
    self.defuser = None
    
    # 玩家控制变量
    self.player_speed = 5
    self.key_pressed = {"w": False, "a": False, "s": False, "d": False}
    
    # 创建开始界面
    self.create_start_screen()

def create_start_screen(self):
    # 清除现有界面
    for widget in self.root.winfo_children():
        widget.destroy()
    
    # 创建开始界面
    start_frame = tk.Frame(self.root, bg="#1a1a2e")
    start_frame.pack(fill=tk.BOTH, expand=True)
    
    # 游戏标题
    title_font = font.Font(family=self.font_family, size=36, weight="bold")
    title_label = tk.Label(start_frame, text="彩虹六号:炸弹冲锋2D简化版", font=title_font, fg="#e94560", bg="#1a1a2e")
    title_label.pack(pady=50)
    
    # 版权信息
    copyright_font = font.Font(family=self.font_family, size=12)
    copyright_label = tk.Label(start_frame, text="Ubisoft&BCZOZ70371", font=copyright_font, fg="#e94560", bg="#1a1a2e")
    copyright_label.pack(pady=10)
    
    # 操作说明
    controls_font = font.Font(family=self.font_family, size=14)
    controls_label = tk.Label(start_frame, text="WASD移动,空格射击", font=controls_font, fg="white", bg="#1a1a2e")
    controls_label.pack(pady=20)
    
    # 阵营选择按钮
    button_frame = tk.Frame(start_frame, bg="#1a1a2e")
    button_frame.pack(pady=100)
    
    defender_btn = tk.Button(button_frame, text="选择防守方", command=self.select_defender,
                            font=(self.font_family, 16), bg="#4CAF50", fg="white",
                            width=15, height=2, cursor="hand2")
    defender_btn.pack(side=tk.LEFT, padx=20)
    
    attacker_btn = tk.Button(button_frame, text="选择进攻方", command=self.select_attacker,
                            font=(self.font_family, 16), bg="#F44336", fg="white",
                            width=15, height=2, cursor="hand2")
    attacker_btn.pack(side=tk.LEFT, padx=20)

def select_defender(self):
    self.defender_turn = True
    self.create_game_screen()
    self.initialize_defenders()
    self.start_defense_prep_phase()
    self.setup_player_controls()

def select_attacker(self):
    self.attacker_turn = True
    self.create_game_screen()
    self.initialize_attackers()
    self.initialize_defenders()  # AI防守方
    self.start_attack_phase()
    self.setup_player_controls()

def create_game_screen(self):
    # 清除现有界面
    for widget in self.root.winfo_children():
        widget.destroy()
    
    # 创建游戏界面
    self.game_frame = tk.Frame(self.root, bg="#0f3460")
    self.game_frame.pack(fill=tk.BOTH, expand=True)
    
    # 创建游戏画布
    self.canvas = tk.Canvas(self.game_frame, bg="#16213e", width=1024, height=668)
    self.canvas.pack()
    
    # 绘制银行地图
    self.draw_bank_map()
    
    # 创建状态面板
    self.status_frame = tk.Frame(self.game_frame, bg="#0f3460", height=100)
    self.status_frame.pack(fill=tk.X)
    
    # 计时器
    self.timer_label = tk.Label(self.status_frame, text="01:00", font=(self.font_family, 24), fg="white", bg="#0f3460")
    self.timer_label.pack(side=tk.LEFT, padx=20)
    
    # 玩家状态
    self.player_status_label = tk.Label(self.status_frame, text="玩家状态", font=(self.font_family, 14), fg="white", bg="#0f3460")
    self.player_status_label.pack(side=tk.LEFT, padx=20)
    
    # 游戏状态
    self.game_status_label = tk.Label(self.status_frame, text="游戏状态", font=(self.font_family, 14), fg="white", bg="#0f3460")
    self.game_status_label.pack(side=tk.RIGHT, padx=20)

def draw_bank_map(self):
    # 绘制银行外部轮廓
    self.canvas.create_rectangle(100, 100, 924, 568, fill="#2c497f", outline="#e94560", width=2)
    
    # 绘制金库区域
    self.canvas.create_rectangle(self.bomb_site["x"] - self.bomb_site["radius"], 
                                self.bomb_site["y"] - self.bomb_site["radius"],
                                self.bomb_site["x"] + self.bomb_site["radius"], 
                                self.bomb_site["y"] + self.bomb_site["radius"],
                                fill="#4a5568", outline="#e94560", width=2)
    self.canvas.create_text(self.bomb_site["x"], self.bomb_site["y"], text="金库", 
                           font=(self.font_family, 12), fill="white")
    
    # 绘制入口
    self.canvas.create_rectangle(100, 284, 150, 384, fill="#16213e", outline="#e94560", width=2)  # 左入口
    self.canvas.create_rectangle(874, 284, 924, 384, fill="#16213e", outline="#e94560", width=2)  # 右入口
    
    # 绘制一些障碍物
    obstacles = [
        (200, 200, 300, 250), (400, 200, 500, 250), (600, 200, 700, 250),
        (200, 400, 300, 450), (400, 400, 500, 450), (600, 400, 700, 450)
    ]
    
    for obs in obstacles:
        self.canvas.create_rectangle(obs[0], obs[1], obs[2], obs[3], fill="#1a1a2e", outline="#e94560")

def initialize_defenders(self):
    # 清空现有防守方
    self.defenders = []
    
    # 创建玩家控制的防守方
    if self.defender_turn:
        player_defender = {"id": 0, "x": 512, "y": 384, "health": 100, "is_player": True, "role": "defender"}
        self.defenders.append(player_defender)
        
        # 绘制玩家
        self.draw_unit(player_defender, "blue")
    
    # 创建AI控制的防守方
    for i in range(1, self.total_players):
        ai_defender = {"id": i, "x": random.randint(200, 800), "y": random.randint(200, 500), 
                      "health": 100, "is_player": False, "role": "defender"}
        self.defenders.append(ai_defender)
        
        # 绘制AI
        self.draw_unit(ai_defender, "blue")

def initialize_attackers(self):
    # 清空现有进攻方
    self.attackers = []
    
    # 创建玩家控制的进攻方
    if self.attacker_turn:
        player_attacker = {"id": 0, "x": 100, "y": 334, "health": 100, "is_player": True, "role": "attacker"}
        self.attackers.append(player_attacker)
        
        # 绘制玩家
        self.draw_unit(player_attacker, "red")
    
    # 创建AI控制的进攻方
    for i in range(1, self.total_players):
        # 随机选择左侧或右侧入口
        if random.choice([True, False]):
            x = 100
            y = random.randint(284, 384)
        else:
            x = 924
            y = random.randint(284, 384)
            
        ai_attacker = {"id": i, "x": x, "y": y, "health": 100, "is_player": False, "role": "attacker"}
        self.attackers.append(ai_attacker)
        
        # 绘制AI
        self.draw_unit(ai_attacker, "red")

def draw_unit(self, unit, color):
    size = 15
    if unit["is_player"]:
        size = 20
        
    # 绘制单位
    unit["canvas_obj"] = self.canvas.create_oval(unit["x"] - size, unit["y"] - size,
                                                unit["x"] + size, unit["y"] + size,
                                                fill=color)
    
    # 绘制单位ID
    unit["canvas_text"] = self.canvas.create_text(unit["x"], unit["y"], 
                                                  text=str(unit["id"]), 
                                                  fill="white", 
                                                  font=(self.font_family, 10))

def start_defense_prep_phase(self):
    self.game_status_label.config(text="防守方准备阶段")
    self.timer_label.config(text=f"{self.defense_timer//60:02d}:{self.defense_timer%60:02d}")
    self.timer_running = True
    
    # 启动计时器线程
    timer_thread = threading.Thread(target=self.run_defense_timer)
    timer_thread.daemon = True
    timer_thread.start()
    
    # 启动AI防守准备
    if not self.defender_turn:  # 如果玩家是进攻方,AI需要准备防守
        self.run_ai_defense_prep()

def run_defense_timer(self):
    while self.defense_timer > 0 and self.timer_running:
        time.sleep(1)
        self.defense_timer -= 1
        self.root.after(0, lambda: self.timer_label.config(
            text=f"{self.defense_timer//60:02d}:{self.defense_timer%60:02d}"))
        
        # 更新AI防御布置
        if not self.defender_turn:
            self.root.after(0, self.update_ai_defense_prep)
    
    if self.timer_running:
        self.root.after(0, self.start_attack_phase)

def run_ai_defense_prep(self):
    # AI防守准备逻辑
    for defender in self.defenders:
        if not defender["is_player"]:
            # 在炸弹区域附近布置防御
            if random.random() < 0.7:
                # 放置摄像头
                cam_x = self.bomb_site["x"] + random.randint(-100, 100)
                cam_y = self.bomb_site["y"] + random.randint(-100, 100)
                self.defense_objects.append({"type": "camera", "x": cam_x, "y": cam_y})
                
                # 绘制摄像头
                self.canvas.create_oval(cam_x - 5, cam_y - 5, cam_x + 5, cam_y + 5, fill="yellow")
            
            # 放置陷阱
            if random.random() < 0.5:
                trap_x = self.bomb_site["x"] + random.randint(-80, 80)
                trap_y = self.bomb_site["y"] + random.randint(-80, 80)
                self.defense_objects.append({"type": "trap", "x": trap_x, "y": trap_y})
                
                # 绘制陷阱
                self.canvas.create_rectangle(trap_x - 5, trap_y - 5, trap_x + 5, trap_y + 5, fill="purple")

def update_ai_defense_prep(self):
    # 继续更新AI防御布置
    for defender in self.defenders:
        if not defender["is_player"] and random.random() < 0.3:
            # 随机移动到炸弹区域附近
            target_x = self.bomb_site["x"] + random.randint(-100, 100)
            target_y = self.bomb_site["y"] + random.randint(-100, 100)
            
            # 移动AI
            self.move_unit(defender, target_x, target_y)

def start_attack_phase(self):
    self.timer_running = False
    self.defense_timer = 60  # 重置防御计时器
    
    # 开始攻击阶段
    self.game_active = True
    self.game_status_label.config(text="战斗阶段")
    self.game_timer = 300  # 5分钟游戏时间
    self.timer_label.config(text=f"{self.game_timer//60:02d}:{self.game_timer%60:02d}")
    self.timer_running = True
    
    # 启动游戏计时器线程
    game_timer_thread = threading.Thread(target=self.run_game_timer)
    game_timer_thread.daemon = True
    game_timer_thread.start()
    
    # 启动AI行动
    if self.attacker_turn:
        # 玩家是进攻方,AI控制防守方
        self.start_ai_defense_actions()
    else:
        # 玩家是防守方,AI控制进攻方
        self.start_ai_attack_actions()

def run_game_timer(self):
    while self.game_timer > 0 and self.timer_running and not self.defender_wins and not self.attacker_wins:
        time.sleep(1)
        self.game_timer -= 1
        self.root.after(0, lambda: self.timer_label.config(
            text=f"{self.game_timer//60:02d}:{self.game_timer%60:02d}"))
        
        # 更新AI行动
        if self.attacker_turn:
            self.root.after(0, self.update_ai_defense_actions)
        else:
            self.root.after(0, self.update_ai_attack_actions)
    
    if self.timer_running and not self.defender_wins and not self.attacker_wins:
        # 时间到,检查胜利条件
        self.root.after(0, self.check_win_conditions)

def start_ai_defense_actions(self):
    # 防守AI初始行动
    pass

def update_ai_defense_actions(self):
    # 更新防守AI行动
    for defender in self.defenders:
        if not defender["is_player"] and defender["health"] > 0:
            # 检测进攻方
            nearest_attacker = self.find_nearest_enemy(defender, self.attackers)
            if nearest_attacker and self.distance(defender, nearest_attacker) < 200:
                # 发现敌人,向敌人移动
                target_x = nearest_attacker["x"] + random.randint(-20, 20)
                target_y = nearest_attacker["y"] + random.randint(-20, 20)
                self.move_unit(defender, target_x, target_y)
                
                # 有几率射击
                if random.random() < 0.3:
                    self.shoot_at(defender, nearest_attacker)
            else:
                # 没有发现敌人,巡逻或守卫炸弹点
                if random.random() < 0.05:
                    # 随机巡逻
                    target_x = self.bomb_site["x"] + random.randint(-150, 150)
                    target_y = self.bomb_site["y"] + random.randint(-150, 150)
                    self.move_unit(defender, target_x, target_y)
                else:
                    # 守卫当前位置
                    pass

def start_ai_attack_actions(self):
    # 进攻AI初始行动
    for attacker in self.attackers:
        if not attacker["is_player"] and attacker["health"] > 0:
            # 移动到炸弹区域
            target_x = self.bomb_site["x"] + random.randint(-100, 100)
            target_y = self.bomb_site["y"] + random.randint(-100, 100)
            self.move_unit(attacker, target_x, target_y)

def update_ai_attack_actions(self):
    # 更新进攻AI行动
    for attacker in self.attackers:
        if not attacker["is_player"] and attacker["health"] > 0:
            # 检查是否可以安装拆弹器
            if not self.bomb_planted and self.is_in_bomb_site(attacker) and random.random() < 0.01:
                self.plant_defuser(attacker)
                continue
            
            # 检测防守方
            nearest_defender = self.find_nearest_enemy(attacker, self.defenders)
            if nearest_defender and self.distance(attacker, nearest_defender) < 200:
                # 发现敌人,向敌人移动
                target_x = nearest_defender["x"] + random.randint(-20, 20)
                target_y = nearest_defender["y"] + random.randint(-20, 20)
                self.move_unit(attacker, target_x, target_y)
                
                # 有几率射击
                if random.random() < 0.3:
                    self.shoot_at(attacker, nearest_defender)
            else:
                # 没有发现敌人,继续向炸弹点移动
                if not self.is_in_bomb_site(attacker):
                    target_x = self.bomb_site["x"] + random.randint(-50, 50)
                    target_y = self.bomb_site["y"] + random.randint(-50, 50)
                    self.move_unit(attacker, target_x, target_y)
                else:
                    # 已经在炸弹点,巡逻
                    target_x = attacker["x"] + random.randint(-30, 30)
                    target_y = attacker["y"] + random.randint(-30, 30)
                    self.move_unit(attacker, target_x, target_y)

def find_nearest_enemy(self, unit, enemies):
    nearest = None
    min_dist = float('inf')
    
    for enemy in enemies:
        if enemy["health"] > 0:
            dist = self.distance(unit, enemy)
            if dist < min_dist:
                min_dist = dist
                nearest = enemy
    
    return nearest

def distance(self, unit1, unit2):
    return math.sqrt((unit1["x"] - unit2["x"])**2 + (unit1["y"] - unit2["y"])**2)

def is_in_bomb_site(self, unit):
    return (unit["x"] >= self.bomb_site["x"] - self.bomb_site["radius"] and
            unit["x"] <= self.bomb_site["x"] + self.bomb_site["radius"] and
            unit["y"] >= self.bomb_site["y"] - self.bomb_site["radius"] and
            unit["y"] <= self.bomb_site["y"] + self.bomb_site["radius"])

def move_unit(self, unit, target_x, target_y):
    # 简单移动逻辑
    dx = target_x - unit["x"]
    dy = target_y - unit["y"]
    distance = math.sqrt(dx*dx + dy*dy)
    
    if distance > 5:  # 避免微小移动
        # 移动速度
        speed = 3
        
        # 计算移动方向和距离
        move_x = (dx / distance) * speed
        move_y = (dy / distance) * speed
        
        # 更新位置
        unit["x"] += move_x
        unit["y"] += move_y
        
        # 更新画布上的位置
        self.canvas.coords(unit["canvas_obj"], 
                         unit["x"] - 15 if unit["is_player"] else unit["x"] - 10,
                         unit["y"] - 15 if unit["is_player"] else unit["y"] - 10,
                         unit["x"] + 15 if unit["is_player"] else unit["x"] + 10,
                         unit["y"] + 15 if unit["is_player"] else unit["y"] + 10)
        
        self.canvas.coords(unit["canvas_text"], unit["x"], unit["y"])

def setup_player_controls(self):
    # 绑定键盘事件
    self.root.bind("<KeyPress>", self.on_key_press)
    self.root.bind("<KeyRelease>", self.on_key_release)
    
    # 启动玩家控制循环
    self.update_player_position()

def on_key_press(self, event):
    key = event.keysym.lower()
    if key in self.key_pressed:
        self.key_pressed[key] = True
    elif key == "space":
        self.player_shoot()

def on_key_release(self, event):
    key = event.keysym.lower()
    if key in self.key_pressed:
        self.key_pressed[key] = False

def update_player_position(self):
    if not self.game_active:
        self.root.after(10, self.update_player_position)
        return
        
    # 获取玩家对象
    player = None
    if self.defender_turn:
        player = next((d for d in self.defenders if d["is_player"]), None)
    elif self.attacker_turn:
        player = next((a for a in self.attackers if a["is_player"]), None)
    
    if player and player["health"] > 0:
        dx, dy = 0, 0
        
        # 根据按键计算移动方向
        if self.key_pressed["w"]:
            dy -= self.player_speed
        if self.key_pressed["s"]:
            dy += self.player_speed
        if self.key_pressed["a"]:
            dx -= self.player_speed
        if self.key_pressed["d"]:
            dx += self.player_speed
        
        # 边界检查
        new_x = player["x"] + dx
        new_y = player["y"] + dy
        
        if new_x < 100:
            new_x = 100
        elif new_x > 924:
            new_x = 924
        
        if new_y < 100:
            new_y = 100
        elif new_y > 568:
            new_y = 568
        
        # 更新玩家位置
        player["x"] = new_x
        player["y"] = new_y
        
        # 更新画布上的位置
        self.canvas.coords(player["canvas_obj"], 
                         player["x"] - 20, player["y"] - 20,
                         player["x"] + 20, player["y"] + 20)
        
        self.canvas.coords(player["canvas_text"], player["x"], player["y"])
    
    # 继续更新
    self.root.after(10, self.update_player_position)

def player_shoot(self):
    # 获取玩家对象
    player = None
    enemies = []
    
    if self.defender_turn:
        player = next((d for d in self.defenders if d["is_player"]), None)
        enemies = self.attackers
    elif self.attacker_turn:
        player = next((a for a in self.attackers if a["is_player"]), None)
        enemies = self.defenders
    
    if player and player["health"] > 0:
        # 寻找最近的敌人
        nearest_enemy = self.find_nearest_enemy(player, enemies)
        if nearest_enemy and self.distance(player, nearest_enemy) < 300:
            # 玩家射击
            self.shoot_at(player, nearest_enemy)

def shoot_at(self, shooter, target):
    # 射击逻辑
    hit_chance = 0.7  # 命中率
    
    if random.random() < hit_chance:
        # 命中
        target["health"] -= 34  # 每次射击造成34点伤害
        
        if target["health"] <= 0:
            # 敌人被消灭
            self.canvas.delete(target["canvas_obj"])
            self.canvas.delete(target["canvas_text"])
            
            # 检查胜利条件
            self.check_win_conditions()
        else:
            # 显示伤害效果
            self.show_damage(target)

def show_damage(self, unit):
    # 创建伤害数字
    damage_text = self.canvas.create_text(unit["x"], unit["y"] - 20, 
                                        text=str(34), fill="red", 
                                        font=(self.font_family, 12))
    
    # 2秒后删除伤害数字
    self.root.after(2000, lambda: self.canvas.delete(damage_text))

def plant_defuser(self, attacker):
    if not self.bomb_planted:
        self.bomb_planted = True
        self.defuser = {"x": attacker["x"], "y": attacker["y"], "defuse_time": 30}
        
        # 绘制拆弹器
        self.defuser["canvas_obj"] = self.canvas.create_rectangle(
            self.defuser["x"] - 10, self.defuser["y"] - 10,
            self.defuser["x"] + 10, self.defuser["y"] + 10,
            fill="orange")
        
        # 更新游戏状态
        self.game_status_label.config(text="拆弹器已放置!防守方需要阻止拆除")
        
        # 启动拆弹计时器
        defuse_thread = threading.Thread(target=self.run_defuse_timer)
        defuse_thread.daemon = True
        defuse_thread.start()

def run_defuse_timer(self):
    while self.defuser["defuse_time"] > 0 and self.timer_running and not self.defender_wins:
        time.sleep(1)
        self.defuser["defuse_time"] -= 1
        
        # 更新拆弹器显示
        self.root.after(0, lambda: self.canvas.itemconfig(
            self.defuser["canvas_obj"], outline=f"#{int(255*(self.defuser['defuse_time']/30)):02x}0000"))
        
        # 检查是否有防守方在附近可以拆除
        for defender in self.defenders:
            if defender["health"] > 0 and self.distance(defender, self.defuser) < 30:
                # 防守方在附近,可以拆除
                self.root.after(0, self.defend_defuser)
                return
    
    if self.timer_running and not self.defender_wins:
        # 拆弹成功
        self.root.after(0, self.attacker_wins_game)

def defend_defuser(self):
    # 防守方拆除拆弹器
    self.bomb_planted = False
    self.canvas.delete(self.defuser["canvas_obj"])
    self.game_status_label.config(text="拆弹器已被防守方拆除!")
    
    # 延迟后检查胜利条件
    self.root.after(2000, self.check_win_conditions)

def check_win_conditions(self):
    # 检查进攻方是否全灭
    all_attackers_dead = all(attacker["health"] <= 0 for attacker in self.attackers)
    
    # 检查防守方是否全灭
    all_defenders_dead = all(defender["health"] <= 0 for defender in self.defenders)
    
    # 检查炸弹是否被拆除
    bomb_defused = self.bomb_planted and self.defuser["defuse_time"] <= 0
    
    # 胜利条件判断
    if all_attackers_dead and not self.bomb_planted:
        self.defender_wins_game()
    elif all_defenders_dead or bomb_defused:
        self.attacker_wins_game()
    elif self.game_timer <= 0 and not self.bomb_planted:
        # 时间到,炸弹未放置,防守方胜利
        self.defender_wins_game()

def defender_wins_game(self):
    self.timer_running = False
    self.defender_wins = True
    self.game_status_label.config(text="防守方胜利!")
    messagebox.showinfo("游戏结束", "防守方胜利!")
    self.root.after(3000, self.create_start_screen)

def attacker_wins_game(self):
    self.timer_running = False
    self.attacker_wins = True
    self.game_status_label.config(text="进攻方胜利!")
    messagebox.showinfo("游戏结束", "进攻方胜利!")
    self.root.after(3000, self.create_start_screen)

if name == "main": root = tk.Tk() game = Game(root) root.mainloop()