当前位置:首页>python>python-TANK大战

python-TANK大战

  • 2026-09-02 19:06:37
python-TANK大战
游戏界面如下:
参考代码:
import tkinter as tkimport randomfrom tkinter import messageboxclass TankGame:    def __init__(self, root):        self.root = root        self.root.title("坦克大战")        self.root.resizable(False, False)        # 游戏配置        self.cell_size = 30  # 每个格子的大小(像素)        self.map_width = 20  # 地图宽度(格子数)        self.map_height = 15  # 地图高度(格子数)        # 计算窗口大小        self.game_width = self.map_width * self.cell_size        self.game_height = self.map_height * self.cell_size        self.info_width = 200        # 设置窗口大小        self.root.geometry(f"{self.game_width + self.info_width + 40}x{self.game_height + 40}")        # 游戏状态        self.player_tank = None        self.enemy_tanks = []        self.bullets = []        self.walls = []        self.score = 0        self.enemy_count = 5  # 敌方坦克数量        self.game_over = False        self.paused = False        self.game_loop_id = None        # 移动延迟(防止移动太快)        self.move_delay = 0        self.enemy_move_delay = 0        # 颜色配置        self.colors = {            'bg': '#2c3e50',            'player': '#2ecc71',            'enemy': '#e74c3c',            'wall': '#95a5a6',            'bullet': '#f1c40f',            'grid': '#34495e'        }        # 创建界面        self.setup_ui()        # 绑定键盘事件        self.bind_keys()        # 开始游戏        self.start_game()        # 游戏循环        self.game_loop()    def setup_ui(self):        """创建用户界面"""        # 主框架        main_frame = tk.Frame(self.root, bg=self.colors['bg'])        main_frame.pack(expand=True, fill=tk.BOTH)        # 游戏画布        self.canvas = tk.Canvas(            main_frame,            width=self.game_width,            height=self.game_height,            bg=self.colors['bg'],            highlightthickness=2,            highlightbackground='#555'        )        self.canvas.pack(side=tk.LEFT, padx=10, pady=10)        # 信息面板        info_frame = tk.Frame(main_frame, width=self.info_width, bg='#34495e')        info_frame.pack(side=tk.RIGHT, padx=10, pady=10, fill=tk.BOTH)        info_frame.pack_propagate(False)        # 得分显示        self.score_label = tk.Label(            info_frame,            text=f"得分: {self.score}",            font=('Arial', 18, 'bold'),            bg='#34495e',            fg='white'        )        self.score_label.pack(pady=20)        # 敌方剩余数量        self.enemy_label = tk.Label(            info_frame,            text=f"敌方剩余: {self.enemy_count}",            font=('Arial', 14, 'bold'),            bg='#34495e',            fg='white'        )        self.enemy_label.pack(pady=10)        # 操作说明        controls_frame = tk.Frame(info_frame, bg='#34495e')        controls_frame.pack(pady=20)        controls = [            "操作说明:",            "",            "WASD 或 方向键: 移动",            "J 或 空格: 射击",            "",            "P: 暂停",            "R: 重新开始"        ]        for text in controls:            label = tk.Label(                controls_frame,                text=text,                font=('Arial', 10),                bg='#34495e',                fg='#95a5a6'            )            label.pack(pady=2)    def bind_keys(self):        """绑定键盘事件"""        # 移动控制        self.root.bind('<KeyPress-Left>', lambda e: self.move_player('left'))        self.root.bind('<KeyPress-Right>', lambda e: self.move_player('right'))        self.root.bind('<KeyPress-Up>', lambda e: self.move_player('up'))        self.root.bind('<KeyPress-Down>', lambda e: self.move_player('down'))        self.root.bind('<KeyPress-a>', lambda e: self.move_player('left'))        self.root.bind('<KeyPress-d>', lambda e: self.move_player('right'))        self.root.bind('<KeyPress-w>', lambda e: self.move_player('up'))        self.root.bind('<KeyPress-s>', lambda e: self.move_player('down'))        # 射击控制        self.root.bind('<KeyPress-space>', lambda e: self.shoot())        self.root.bind('<KeyPress-j>', lambda e: self.shoot())        self.root.bind('<KeyPress-J>', lambda e: self.shoot())        # 游戏控制        self.root.bind('<KeyPress-p>', lambda e: self.toggle_pause())        self.root.bind('<KeyPress-P>', lambda e: self.toggle_pause())        self.root.bind('<KeyPress-r>', lambda e: self.restart())        self.root.bind('<KeyPress-R>', lambda e: self.restart())        # 确保窗口获得焦点        self.root.focus_set()    def start_game(self):        """开始游戏"""        self.create_map()        self.player_tank = Tank(self.map_width // 2, self.map_height - 2, 'player', self.colors['player'])        self.enemy_tanks = []        self.bullets = []        self.score = 0        self.enemy_count = 5        self.game_over = False        self.paused = False        self.move_delay = 0        self.enemy_move_delay = 0        # 创建敌方坦克        for i in range(self.enemy_count):            while True:                x = random.randint(1, self.map_width - 2)                y = random.randint(1, 5)                # 确保不与玩家重叠且不与其他敌方坦克重叠                overlap = False                if (x, y) == (self.player_tank.x, self.player_tank.y):                    overlap = True                for enemy in self.enemy_tanks:                    if enemy.x == x and enemy.y == y:                        overlap = True                        break                if not overlap:                    enemy = Tank(x, y, 'enemy', self.colors['enemy'])                    self.enemy_tanks.append(enemy)                    break        self.update_info()        self.draw()    def create_map(self):        """创建地图(墙壁)"""        self.walls = []        # 创建边界墙壁        for x in range(self.map_width):            self.walls.append(Wall(x, 0))  # 上边界            self.walls.append(Wall(x, self.map_height - 1))  # 下边界        for y in range(self.map_height):            self.walls.append(Wall(0, y))  # 左边界            self.walls.append(Wall(self.map_width - 1, y))  # 右边界        # 创建一些障碍物        obstacles = [            (5, 5), (6, 5), (7, 5),            (12, 5), (13, 5), (14, 5),            (3, 8), (4, 8), (5, 8), (6, 8),            (13, 8), (14, 8), (15, 8), (16, 8),            (8, 10), (9, 10), (10, 10), (11, 10),            (4, 12), (5, 12), (14, 12), (15, 12)        ]        for x, y in obstacles:            if 0 < x < self.map_width - 1 and 0 < y < self.map_height - 1:                self.walls.append(Wall(x, y))    def move_player(self, direction):        """移动玩家坦克(带延迟,防止移动太快)"""        if self.game_over or self.paused:            return        # 移动延迟控制        if self.move_delay > 0:            return        new_x, new_y = self.player_tank.x, self.player_tank.y        if direction == 'left':            new_x -= 1        elif direction == 'right':            new_x += 1        elif direction == 'up':            new_y -= 1        elif direction == 'down':            new_y += 1        # 检查碰撞        if self.can_move(new_x, new_y, self.player_tank):            self.player_tank.x = new_x            self.player_tank.y = new_y            self.player_tank.direction = direction            self.move_delay = 3  # 设置移动延迟,数值越大移动越慢            self.draw()    def move_enemies(self):        """移动敌方坦克(带延迟)"""        if self.enemy_move_delay > 0:            self.enemy_move_delay -= 1            return        for enemy in self.enemy_tanks[:]:            # 随机移动            directions = ['up', 'down', 'left', 'right']            move_dir = random.choice(directions)            new_x, new_y = enemy.x, enemy.y            if move_dir == 'left':                new_x -= 1            elif move_dir == 'right':                new_x += 1            elif move_dir == 'up':                new_y -= 1            elif move_dir == 'down':                new_y += 1            # 检查碰撞            if self.can_move(new_x, new_y, enemy):                enemy.x = new_x                enemy.y = new_y                enemy.direction = move_dir        self.enemy_move_delay = 4  # 敌方移动延迟,比玩家稍慢    def can_move(self, x, y, tank):        """检查坦克是否可以移动到指定位置"""        # 检查边界        if x <= 0 or x >= self.map_width - 1 or y <= 0 or y >= self.map_height - 1:            return False        # 检查墙壁碰撞        for wall in self.walls:            if wall.x == x and wall.y == y:                return False        # 检查其他坦克碰撞        if tank.type == 'player':            for enemy in self.enemy_tanks:                if enemy.x == x and enemy.y == y:                    return False        else:            if self.player_tank.x == x and self.player_tank.y == y:                return False            for other in self.enemy_tanks:                if other != tank and other.x == x and other.y == y:                    return False        return True    def shoot(self):        """玩家射击(无冷却)"""        if self.game_over or self.paused:            return        bullet = Bullet(            self.player_tank.x,            self.player_tank.y,            self.player_tank.direction,            'player'        )        self.bullets.append(bullet)    def enemy_shoot(self, enemy):        """敌方射击(无冷却)"""        bullet = Bullet(            enemy.x,            enemy.y,            enemy.direction,            'enemy'        )        self.bullets.append(bullet)    def update_bullets(self):        """更新子弹位置和碰撞(子弹速度加快)"""        for bullet in self.bullets[:]:            # 子弹每次移动多格,加快速度            for _ in range(3):  # 每次更新移动3格,速度是坦克的3倍                # 移动子弹                if bullet.direction == 'up':                    bullet.y -= 1                elif bullet.direction == 'down':                    bullet.y += 1                elif bullet.direction == 'left':                    bullet.x -= 1                elif bullet.direction == 'right':                    bullet.x += 1                # 检查边界                if (bullet.x <= 0 or bullet.x >= self.map_width - 1 or                    bullet.y <= 0 or bullet.y >= self.map_height - 1):                    if bullet in self.bullets:                        self.bullets.remove(bullet)                    break                # 检查墙壁碰撞                hit_wall = False                for wall in self.walls[:]:                    if wall.x == bullet.x and wall.y == bullet.y:                        if wall in self.walls:                            self.walls.remove(wall)                        if bullet in self.bullets:                            self.bullets.remove(bullet)                        hit_wall = True                        break                if hit_wall:                    break                # 检查坦克碰撞                if bullet.type == 'player':                    for enemy in self.enemy_tanks[:]:                        if enemy.x == bullet.x and enemy.y == bullet.y:                            if enemy in self.enemy_tanks:                                self.enemy_tanks.remove(enemy)                            if bullet in self.bullets:                                self.bullets.remove(bullet)                            self.score += 10                            self.enemy_count = len(self.enemy_tanks)                            self.update_info()                            break                    if bullet not in self.bullets:                        break                else:                    if (self.player_tank.x == bullet.x and                         self.player_tank.y == bullet.y):                        self.game_over = True                        if bullet in self.bullets:                            self.bullets.remove(bullet)                        return                # 如果子弹已经移除,跳出循环                if bullet not in self.bullets:                    break    def update_info(self):        """更新信息显示"""        self.score_label.config(text=f"得分: {self.score}")        self.enemy_label.config(text=f"敌方剩余: {self.enemy_count}")        # 检查胜利条件        if self.enemy_count == 0 and not self.game_over:            self.game_over = True            self.show_victory()    def toggle_pause(self):        """暂停/继续游戏"""        if not self.game_over:            self.paused = not self.paused            self.draw()            if not self.paused:                self.game_loop()    def restart(self):        """重新开始游戏"""        # 停止当前的游戏循环        if self.game_loop_id:            self.root.after_cancel(self.game_loop_id)            self.game_loop_id = None        self.start_game()        self.draw()        self.game_loop()    def show_game_over(self):        """显示游戏结束"""        self.draw()        result = messagebox.askyesno("游戏结束",                                      f"游戏结束!\n最终得分: {self.score}\n是否重新开始?")        if result:            self.restart()        else:            self.root.quit()    def show_victory(self):        """显示胜利"""        self.draw()        result = messagebox.askyesno("胜利",                                      f"恭喜获胜!\n最终得分: {self.score}\n是否重新开始?")        if result:            self.restart()        else:            self.root.quit()    def draw(self):        """绘制游戏画面"""        self.canvas.delete("all")        # 绘制网格线        for x in range(self.map_width + 1):            self.canvas.create_line(                x * self.cell_size, 0,                x * self.cell_size, self.game_height,                fill=self.colors['grid'], width=1            )        for y in range(self.map_height + 1):            self.canvas.create_line(                0, y * self.cell_size,                self.game_width, y * self.cell_size,                fill=self.colors['grid'], width=1            )        # 绘制墙壁        for wall in self.walls:            self.canvas.create_rectangle(                wall.x * self.cell_size, wall.y * self.cell_size,                (wall.x + 1) * self.cell_size, (wall.y + 1) * self.cell_size,                fill=self.colors['wall'], outline=self.colors['bg'], width=2            )        # 绘制玩家坦克        if self.player_tank:            self.draw_tank(self.player_tank)        # 绘制敌方坦克        for enemy in self.enemy_tanks:            self.draw_tank(enemy)        # 绘制子弹        for bullet in self.bullets:            self.canvas.create_rectangle(                bullet.x * self.cell_size + self.cell_size//3,                bullet.y * self.cell_size + self.cell_size//3,                (bullet.x + 1) * self.cell_size - self.cell_size//3,                (bullet.y + 1) * self.cell_size - self.cell_size//3,                fill=self.colors['bullet'], outline=''            )        # 绘制游戏结束或暂停文字        if self.game_over:            text = "胜利!" if self.enemy_count == 0 else "游戏结束"            color = "green" if self.enemy_count == 0 else "red"            self.canvas.create_text(                self.game_width // 2,                self.game_height // 2,                text=text,                font=('Arial', 30, 'bold'),                fill=color            )        elif self.paused:            self.canvas.create_text(                self.game_width // 2,                self.game_height // 2,                text="暂停",                font=('Arial', 30, 'bold'),                fill='yellow'            )    def draw_tank(self, tank):        """绘制坦克"""        x = tank.x * self.cell_size        y = tank.y * self.cell_size        size = self.cell_size        # 绘制坦克身体        self.canvas.create_rectangle(            x + 2, y + 2,            x + size - 2, y + size - 2,            fill=tank.color, outline='white', width=2        )        # 绘制炮管        炮管长度 = size // 2        炮管宽度 = size // 6        if tank.direction == 'up':            self.canvas.create_line(                x + size//2, y + size//2,                x + size//2, y - 炮管长度//2,                fill='white', width=炮管宽度            )        elif tank.direction == 'down':            self.canvas.create_line(                x + size//2, y + size//2,                x + size//2, y + size + 炮管长度//2,                fill='white', width=炮管宽度            )        elif tank.direction == 'left':            self.canvas.create_line(                x + size//2, y + size//2,                x - 炮管长度//2, y + size//2,                fill='white', width=炮管宽度            )        elif tank.direction == 'right':            self.canvas.create_line(                x + size//2, y + size//2,                x + size + 炮管长度//2, y + size//2,                fill='white', width=炮管宽度            )    def game_loop(self):        """游戏主循环"""        if not self.game_over and not self.paused:            # 更新移动延迟            if self.move_delay > 0:                self.move_delay -= 1            self.move_enemies()            # 敌方随机射击(无冷却,但降低概率)            if self.enemy_tanks and not self.game_over:                for enemy in self.enemy_tanks:                    if random.random() < 0.02:  # 降低射击概率                        self.enemy_shoot(enemy)            self.update_bullets()            self.draw()            # 游戏循环间隔(控制整体速度)            self.game_loop_id = self.root.after(100, self.game_loop)        elif not self.game_over and self.paused:            # 暂停时继续检查,但不更新游戏逻辑            self.game_loop_id = self.root.after(100, self.game_loop)        elif self.game_over:            # 游戏结束时不再循环,等待用户操作            passclass Tank:    """坦克类"""    def __init__(self, x, y, type, color):        self.x = x        self.y = y        self.type = type        self.direction = 'up'        self.color = colorclass Wall:    """墙壁类"""    def __init__(self, x, y):        self.x = x        self.y = yclass Bullet:    """子弹类"""    def __init__(self, x, y, direction, type):        self.x = x        self.y = y        self.direction = direction        self.type = typedef main():    root = tk.Tk()    game = TankGame(root)    root.mainloop()if __name__ == "__main__":    main()

最新文章

随机文章