mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-30 00:21:29 +08:00
feat(control) 小地图
This commit is contained in:
1 parent
f86e5f3a79
commit
e2bc630d6d
8 files changed
+339
-24
No files matched your search
+112
-4
@@ -1,16 +1,124 @@
|
||||
// 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();
|
||||
}
|
||||
|
||||
moveTo(targetX, targetY) {
|
||||
this.scene.physics.moveToObject(this, {x: targetX, y: targetY}, 200);
|
||||
/**
|
||||
* 创建选中状态指示器
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
moveRelative(dirX, dirY, speed = 100) {
|
||||
this.setVelocity(dirX * speed, dirY * speed);
|
||||
/**
|
||||
* 设置单位选中状态
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user