mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-30 05:31:29 +08:00
124 lines
3.4 KiB
JavaScript
124 lines
3.4 KiB
JavaScript
// 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);
|
||
}
|
||
}
|
||
} |