mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-29 20:41: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
@@ -11,14 +11,20 @@ export class CommandSystem {
|
||||
}
|
||||
|
||||
onMoveRelative(dir) {
|
||||
if (activeUnit) {
|
||||
activeUnit.moveRelative(dir.x, dir.y);
|
||||
}
|
||||
const targets = selectedUnits.length > 0 ? selectedUnits : (activeUnit ? [activeUnit] : []);
|
||||
|
||||
targets.forEach(unit => {
|
||||
unit.moveRelative(dir.x, dir.y);
|
||||
});
|
||||
}
|
||||
|
||||
onMoveToPoint(x, y) {
|
||||
const targets = selectedUnits.length > 0 ? selectedUnits : (activeUnit ? [activeUnit] : []);
|
||||
targets.forEach(unit => unit.moveTo(x, y));
|
||||
|
||||
|
||||
targets.forEach(unit => {
|
||||
unit.setTarget(x, y); // ← 使用新接口
|
||||
});
|
||||
}
|
||||
|
||||
onSelectUnit(unit) {
|
||||
|
||||
@@ -9,7 +9,7 @@ export let selectedUnits = [];
|
||||
|
||||
export function setActiveUnit(unit) {
|
||||
activeUnit = unit;
|
||||
selectedUnits = unit ? [unit] : [];
|
||||
// 不再重置selectedUnits数组,这样可以同时选中多个单位
|
||||
}
|
||||
|
||||
export function addToSelection(unit) {
|
||||
|
||||
+83
-8
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,9 @@ export class SelectionSystem {
|
||||
this.selectionBox = null;
|
||||
|
||||
scene.events.on('selection-start', this.onStart, this);
|
||||
scene.events.on('selection-update', this.onUpdate, this);
|
||||
scene.events.on('selection-end', this.onEnd, this);
|
||||
scene.events.on('select-unit', this.onSelectUnit, this);
|
||||
}
|
||||
|
||||
onStart(pos) {
|
||||
@@ -20,6 +22,37 @@ export class SelectionSystem {
|
||||
}
|
||||
}
|
||||
|
||||
onUpdate(rect) {
|
||||
if (this.selectionBox && this.selectionBox.visible) {
|
||||
// 更新选择框的位置和大小
|
||||
this.selectionBox.setPosition(rect.centerX, rect.centerY);
|
||||
this.selectionBox.setSize(rect.width, rect.height);
|
||||
}
|
||||
}
|
||||
|
||||
onSelectUnit(unit) {
|
||||
// 清除所有单位的选中状态
|
||||
this.scene.unitGroup.getChildren().forEach(u => {
|
||||
if (u.setSelected) {
|
||||
u.setSelected(false);
|
||||
}
|
||||
});
|
||||
|
||||
// 清除当前选择
|
||||
clearSelection();
|
||||
|
||||
// 选择点击的单位
|
||||
setActiveUnit(unit);
|
||||
addToSelection(unit);
|
||||
|
||||
// 设置选中状态
|
||||
if (unit.setSelected) {
|
||||
unit.setSelected(true);
|
||||
}
|
||||
|
||||
this.scene.events.emit('units-selected', [unit]);
|
||||
}
|
||||
|
||||
onEnd(rect) {
|
||||
if (this.selectionBox) {
|
||||
this.selectionBox.setVisible(false);
|
||||
@@ -30,12 +63,28 @@ export class SelectionSystem {
|
||||
const unitRect = unit.getBounds();
|
||||
return Phaser.Geom.Rectangle.Overlaps(rect, unitRect);
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 先清除所有单位的选中状态
|
||||
units.forEach(unit => {
|
||||
if (unit.setSelected) {
|
||||
unit.setSelected(false);
|
||||
}
|
||||
});
|
||||
|
||||
clearSelection();
|
||||
selected.forEach(addToSelection);
|
||||
|
||||
if (selected.length > 0) {
|
||||
setActiveUnit(selected[0]); // 激活第一个
|
||||
// 先设置激活单位
|
||||
setActiveUnit(selected[0]);
|
||||
// 然后添加所有选中的单位(包括激活单位)
|
||||
selected.forEach(unit => {
|
||||
addToSelection(unit);
|
||||
if (unit.setSelected) {
|
||||
unit.setSelected(true);
|
||||
}
|
||||
});
|
||||
this.scene.events.emit('units-selected', selected);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user