feat(control) 小地图

This commit is contained in:
chicrobot committed 2025-12-31 00:30:38 +08:00
1 parent f86e5f3a79
commit e2bc630d6d
8 files changed
+339 -24

No files matched your search

+83 -8
View File
@@ -15,8 +15,12 @@ export class InputSystem {
right: [kb.addKey(Phaser.Input.Keyboard.KeyCodes.D), kb.addKey(Phaser.Input.Keyboard.KeyCodes.RIGHT)]
};
// 禁用浏览器右键菜单
scene.input.mouse.disableContextMenu();
// 鼠标/触摸事件
scene.input.on('pointerdown', this.onPointerDown, this);
scene.input.on('pointermove', this.onPointerMove, this);
scene.input.on('pointerup', this.onPointerUp, this);
}
@@ -32,12 +36,17 @@ export class InputSystem {
if (this.isKeyDown(this.keys.up)) dir.y -= 1;
if (this.isKeyDown(this.keys.down)) dir.y += 1;
if (dir.x !== 0 || dir.y !== 0) {
this.scene.events.emit('move-relative', dir);
}
// 无论是否有按键按下,都发送移动事件
// 当dir.x和dir.y都为0时,单位会停止移动
this.scene.events.emit('move-relative', dir);
}
onPointerDown(pointer) {
// 检查鼠标是否在小地图上,如果是则不处理框选
if (this.isMouseOnMiniMap(pointer)) {
return;
}
if (pointer.leftButtonDown()) {
const worldX = pointer.worldX;
const worldY = pointer.worldY;
@@ -57,19 +66,59 @@ export class InputSystem {
this.scene.events.emit('select-unit', clickedUnit);
} else {
// 开始框选或移动指令
this.selectionStart = { x: pointer.x, y: pointer.y };
// 存储世界坐标用于框选
this.selectionStart = { x: worldX, y: worldY };
this.scene.events.emit('selection-start', this.selectionStart);
}
} else if (pointer.rightButtonDown()) {
// 右键点击:移动选中的单位
const worldX = pointer.worldX;
const worldY = pointer.worldY;
this.scene.events.emit('move-to-point', worldX, worldY);
}
}
onPointerMove(pointer) {
// 检查鼠标是否在小地图上,如果是则不处理框选
if (this.isMouseOnMiniMap(pointer)) {
return;
}
if (this.selectionStart) {
// 使用世界坐标计算框选区域
const currentWorldX = pointer.worldX;
const currentWorldY = pointer.worldY;
// 计算当前选择框的位置和大小
const rect = new Phaser.Geom.Rectangle(
Math.min(this.selectionStart.x, currentWorldX),
Math.min(this.selectionStart.y, currentWorldY),
Math.abs(currentWorldX - this.selectionStart.x),
Math.abs(currentWorldY - this.selectionStart.y)
);
// 更新选择框的位置和大小
this.scene.events.emit('selection-update', rect);
}
}
onPointerUp(pointer) {
// 检查鼠标是否在小地图上,如果是则不处理框选
if (this.isMouseOnMiniMap(pointer)) {
this.selectionStart = null;
return;
}
if (this.selectionStart) {
// 使用世界坐标计算最终框选区域
const currentWorldX = pointer.worldX;
const currentWorldY = pointer.worldY;
const rect = new Phaser.Geom.Rectangle(
Math.min(this.selectionStart.x, pointer.x),
Math.min(this.selectionStart.y, pointer.y),
Math.abs(pointer.x - this.selectionStart.x),
Math.abs(pointer.y - this.selectionStart.y)
Math.min(this.selectionStart.x, currentWorldX),
Math.min(this.selectionStart.y, currentWorldY),
Math.abs(currentWorldX - this.selectionStart.x),
Math.abs(currentWorldY - this.selectionStart.y)
);
// 如果框太小,视为“点击地面移动”
@@ -83,4 +132,30 @@ export class InputSystem {
this.selectionStart = null;
}
}
/**
* 检查鼠标是否在小地图上
* @param {Phaser.Input.Pointer} pointer
* @returns {boolean}
*/
isMouseOnMiniMap(pointer) {
// 检查场景中是否有小地图
if (!this.scene.miniMap) {
return false;
}
const miniMap = this.scene.miniMap;
const mouseX = pointer.x;
const mouseY = pointer.y;
// 计算小地图的边界
const mapLeft = miniMap.x;
const mapRight = miniMap.x + miniMap.mapSize;
const mapTop = miniMap.y;
const mapBottom = miniMap.y + miniMap.mapSize;
// 检查鼠标是否在小地图边界内
return mouseX >= mapLeft && mouseX <= mapRight &&
mouseY >= mapTop && mouseY <= mapBottom;
}
}