// objects/Unit.js export default class Unit extends Phaser.Physics.Arcade.Sprite { constructor(scene, x, y, texture) { super(scene, x, y, texture); scene.add.existing(this); scene.physics.add.existing(this); // 启用圆形碰撞体(更自然) this.setCircle(14); // 启用与世界边界的碰撞(必须配合 physics.world.setBounds) this.setCollideWorldBounds(true); // 移动目标(x, y) this.target = null; // 选中状态 this.isSelected = false; this.selectedIndicator = null; this.createSelectedIndicator(); } /** * 创建选中状态指示器 */ createSelectedIndicator() { // 创建一个外圈指示器,默认隐藏 this.selectedIndicator = this.scene.add.circle(this.x, this.y, this.width * 0.7, 0x00ff00, 0.0); this.selectedIndicator.setStrokeStyle(2, 0x00ff00, 1); this.selectedIndicator.setVisible(false); // 确保指示器与单位一起移动 this.selectedIndicator.setOrigin(0.5, 0.5); // 移除固定位置设置,让指示器随单位和相机一起移动 this.selectedIndicator.setScrollFactor(1, 1); } /** * 设置单位选中状态 * @param {boolean} isSelected */ setSelected(isSelected) { this.isSelected = isSelected; if (this.selectedIndicator) { this.selectedIndicator.setVisible(isSelected); } } /** * 设置移动目标点 * @param {number} x * @param {number} y */ setTarget(x, y) { // 获取世界边界 const worldBounds = this.scene.physics.world.bounds; // 限制目标点在世界边界内 const clampedX = Math.max(worldBounds.x, Math.min(worldBounds.right, x)); const clampedY = Math.max(worldBounds.y, Math.min(worldBounds.bottom, y)); this.target = { x: clampedX, y: clampedY }; } /** * 清除目标并停止移动 */ clearTarget() { this.target = null; this.setVelocity(0, 0); } /** * 相对移动控制(用于键盘/虚拟摇杆) * @param {number} x - 水平方向 (-1 到 1) * @param {number} y - 垂直方向 (-1 到 1) */ moveRelative(x, y) { const speed = 150; // 单位:像素/秒 // 归一化方向向量 const magnitude = Math.sqrt(x * x + y * y); if (magnitude > 0) { // 有按键输入时,清除目标点,切换到直接控制模式 this.clearTarget(); const normalizedX = x / magnitude; const normalizedY = y / magnitude; this.setVelocity(normalizedX * speed, normalizedY * speed); } else { // 没有按键输入时,保持当前的目标点(如果有的话) this.setVelocity(0, 0); } } /** * 每帧更新移动逻辑(需在 GameScene.update 中调用) */ update() { // 更新选中指示器位置 if (this.selectedIndicator && this.isSelected) { this.selectedIndicator.setPosition(this.x, this.y); } } updateMovement() { if (!this.target) { return; } const dx = this.target.x - this.x; const dy = this.target.y - this.y; const distance = Math.sqrt(dx * dx + dy * dy); // 到达阈值:5 像素内视为“到达” if (distance < 5) { // 精确对齐到目标点(可选) this.setPosition(this.target.x, this.target.y); this.clearTarget(); } else { const speed = 150; // 单位:像素/秒 const angle = Math.atan2(dy, dx); this.setVelocity(Math.cos(angle) * speed, Math.sin(angle) * speed); } } }