// ui/MiniMap.js import { selectedUnits, setCameraLocked, cameraLocked } from '../systems/ControlMode.js'; export class MiniMap { constructor(scene, options = {}) { this.scene = scene; this.worldSize = options.worldSize || 2000; this.mapSize = options.mapSize || 200; this.x = options.x || 10; this.y = options.y || 10; // 计算缩放比例(将世界坐标转换为小地图坐标) this.scale = this.mapSize / (this.worldSize * 2); // 创建小地图容器 this.container = scene.add.container(this.x, this.y); this.container.setScrollFactor(0, 0); // 小地图固定在屏幕上 // 创建小地图背景 this.background = scene.add.rectangle(0, 0, this.mapSize, this.mapSize, 0x000000, 0.5); this.background.setOrigin(0, 0); this.background.setStrokeStyle(1, 0xffffff, 0.8); this.container.add(this.background); // 创建视口指示器 this.viewport = scene.add.rectangle(0, 0, 0, 0, 0xffffff, 0.3); this.viewport.setOrigin(0, 0); this.viewport.setStrokeStyle(1, 0xffffff, 1); this.container.add(this.viewport); // 创建单位标记数组 this.unitMarkers = []; // 锁定按钮相关属性 this.lockButton = null; this.lockButtonText = null; this.lockHint = null; // 设置交互 this.setupInteractions(); // 更新小地图(初始调用) this.update(); } setupInteractions() { // 启用容器交互 this.container.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.mapSize, this.mapSize), Phaser.Geom.Rectangle.Contains); // 点击小地图移动相机 this.container.on('pointerdown', (pointer) => { this.handleMapClick(pointer); }); // 拖动小地图移动相机 this.container.on('pointermove', (pointer) => { if (pointer.isDown) { this.handleMapDrag(pointer); } }); } handleMapClick(pointer) { // 将小地图坐标转换为世界坐标 const worldX = (pointer.x - this.x) / this.scale - this.worldSize; const worldY = (pointer.y - this.y) / this.scale - this.worldSize; // 移动相机到点击位置 this.scene.cameras.main.centerOn(worldX, worldY); } handleMapDrag(pointer) { // 将小地图坐标转换为世界坐标 const worldX = (pointer.x - this.x) / this.scale - this.worldSize; const worldY = (pointer.y - this.y) / this.scale - this.worldSize; // 移动相机到拖动位置 this.scene.cameras.main.centerOn(worldX, worldY); } createLockButton() { // 移除旧的按钮(如果存在) this.destroyLockButton(); // 创建锁定按钮背景,直接添加到场景中 const buttonX = this.x; // 按钮x坐标与小地图对齐 const buttonY = this.y + this.mapSize + 5; // 按钮位于小地图下方 this.lockButton = this.scene.add.rectangle(buttonX, buttonY, 100, 25, 0x444444, 0.8); this.lockButton.setOrigin(0, 0); this.lockButton.setStrokeStyle(1, 0xffffff, 0.8); this.lockButton.setInteractive(); // 使用默认的点击区域 this.lockButton.setScrollFactor(0, 0); // 固定在屏幕上 // 创建锁定按钮文本,直接添加到场景中 this.lockButtonText = this.scene.add.text(buttonX + 5, buttonY + 6, '锁定角色', { fontSize: '12px', fill: '#ffffff', fontFamily: 'Arial' }); this.lockButtonText.setOrigin(0, 0); this.lockButtonText.setScrollFactor(0, 0); // 固定在屏幕上 // 添加按钮点击事件 this.lockButton.on('pointerdown', () => { console.log('锁定按钮被点击'); // 添加调试日志 this.toggleLock(); }); // 添加悬停效果 this.lockButton.on('pointerover', () => { this.lockButton.setFillStyle(cameraLocked ? 0x22ff22 : 0x666666, 0.8); }); this.lockButton.on('pointerout', () => { this.lockButton.setFillStyle(cameraLocked ? 0x00ff00 : 0x444444, 0.8); }); // 初始隐藏按钮 this.lockButton.setVisible(false); this.lockButtonText.setVisible(false); } // 销毁锁定按钮 destroyLockButton() { if (this.lockButton) { this.lockButton.destroy(); this.lockButton = null; } if (this.lockButtonText) { this.lockButtonText.destroy(); this.lockButtonText = null; } } toggleLock() { // 切换锁定状态 const newLockedState = !cameraLocked; // 更新全局锁定状态 setCameraLocked(newLockedState); this.updateLockButton(); // 立即将相机中心绑定到选中角色 if (newLockedState && selectedUnits.length === 1) { const selectedUnit = selectedUnits[0]; this.scene.cameras.main.centerOn(selectedUnit.x, selectedUnit.y); // 添加锁定提示 this.showLockHint(newLockedState); } else { // 移除锁定提示 this.hideLockHint(); } } updateLockButton() { if (selectedUnits.length === 1) { // 如果按钮不存在,创建按钮 if (!this.lockButton) { this.createLockButton(); } // 更新按钮状态 this.lockButton.setVisible(true); this.lockButtonText.setVisible(true); this.lockButtonText.setText(cameraLocked ? '取消锁定' : '锁定角色'); this.lockButton.setFillStyle(cameraLocked ? 0x00ff00 : 0x444444, 0.8); } else { // 销毁按钮 this.destroyLockButton(); // 移除锁定提示 this.hideLockHint(); } } // 添加锁定提示 showLockHint(locked) { // 如果已经有提示,先移除 this.hideLockHint(); // 创建提示文本 this.lockHint = this.scene.add.text(this.scene.sys.game.config.width / 2, 50, locked ? '已锁定相机到选中角色' : '已取消相机锁定', { fontSize: '16px', fill: '#ffffff', fontFamily: 'Arial', backgroundColor: 'rgba(0, 0, 0, 0.7)', padding: { x: 10, y: 5 } }); this.lockHint.setOrigin(0.5, 0.5); this.lockHint.setScrollFactor(0, 0); // 固定在屏幕上 // 3秒后自动隐藏 this.scene.time.delayedCall(3000, () => { this.hideLockHint(); }, [], this); } // 移除锁定提示 hideLockHint() { if (this.lockHint) { this.lockHint.destroy(); this.lockHint = null; } } update() { // 更新锁定按钮状态 this.updateLockButton(); // 如果锁定状态且只有一个选中角色,将相机中心绑定到该角色 if (cameraLocked && selectedUnits.length === 1) { const selectedUnit = selectedUnits[0]; this.scene.cameras.main.centerOn(selectedUnit.x, selectedUnit.y); } // 更新视口指示器位置和大小 this.updateViewport(); // 更新单位标记 this.updateUnitMarkers(); } updateViewport() { const camera = this.scene.cameras.main; // 计算相机视口在世界中的位置和大小 const viewportLeft = camera.scrollX; const viewportTop = camera.scrollY; const viewportWidth = camera.width * camera.zoom; const viewportHeight = camera.height * camera.zoom; // 将世界坐标转换为小地图坐标 const mapLeft = (viewportLeft + this.worldSize) * this.scale; const mapTop = (viewportTop + this.worldSize) * this.scale; const mapWidth = viewportWidth * this.scale; const mapHeight = viewportHeight * this.scale; // 更新视口指示器 this.viewport.setPosition(mapLeft, mapTop); this.viewport.setSize(mapWidth, mapHeight); } updateUnitMarkers() { // 清除现有标记 this.unitMarkers.forEach(marker => { marker.destroy(); }); this.unitMarkers = []; // 获取所有单位 if (this.scene.unitGroup) { const units = this.scene.unitGroup.getChildren(); units.forEach(unit => { // 将单位世界坐标转换为小地图坐标 const mapX = (unit.x + this.worldSize) * this.scale; const mapY = (unit.y + this.worldSize) * this.scale; // 检查单位是否被选中 const isSelected = selectedUnits.includes(unit); // 根据选中状态设置不同的颜色和大小 const color = isSelected ? 0x00ff00 : 0xff0000; const size = isSelected ? 3 : 2; // 创建单位标记 const marker = this.scene.add.circle(mapX, mapY, size, color, 1); marker.setOrigin(0.5, 0.5); // 将标记添加到容器和数组中 this.container.add(marker); this.unitMarkers.push(marker); }); } } }