mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-30 00:31:29 +08:00
feat(item) 优化移动及添加测试场景
This commit is contained in:
1 parent
2f7210f47e
commit
b9a5180293
15 files changed
+1428
-62
No files matched your search
+145
-38
@@ -7,7 +7,8 @@ import { clearSelection, setActiveUnit } from './ControlMode.js';
|
||||
export class InputSystem {
|
||||
// 构造函数:初始化输入系统
|
||||
// @param {Object} scene - 游戏场景实例
|
||||
constructor(scene) {
|
||||
// @param {Object} config - 输入配置选项
|
||||
constructor(scene, config = {}) {
|
||||
// 保存场景引用,用于访问游戏世界和发送事件
|
||||
this.scene = scene;
|
||||
|
||||
@@ -15,6 +16,14 @@ export class InputSystem {
|
||||
// 初始值为null,表示当前没有进行框选操作
|
||||
this.selectionStart = null;
|
||||
|
||||
// 移动方式开关配置
|
||||
this.enabledModes = {
|
||||
keyboard: config.keyboard !== false, // 键盘控制
|
||||
mouse: config.mouse !== false, // 鼠标点击移动
|
||||
joystick: config.joystick !== false, // 虚拟摇杆控制
|
||||
selection: config.selection !== false // 框选功能
|
||||
};
|
||||
|
||||
// 初始化键盘输入
|
||||
// 获取Phaser的键盘输入管理器
|
||||
const kb = scene.input.keyboard;
|
||||
@@ -53,28 +62,31 @@ export class InputSystem {
|
||||
|
||||
// update方法:每帧自动调用(约60次/秒),用于处理持续的输入
|
||||
update() {
|
||||
// 创建一个方向对象,用于存储移动方向
|
||||
const dir = { x: 0, y: 0 };
|
||||
|
||||
// 检查左移键是否被按下,如果是则x方向减1(向左移动)
|
||||
if (this.isKeyDown(this.keys.left)) dir.x -= 1;
|
||||
// 检查右移键是否被按下,如果是则x方向加1(向右移动)
|
||||
if (this.isKeyDown(this.keys.right)) dir.x += 1;
|
||||
// 检查上移键是否被按下,如果是则y方向减1(向上移动)
|
||||
if (this.isKeyDown(this.keys.up)) dir.y -= 1;
|
||||
// 检查下移键是否被按下,如果是则y方向加1(向下移动)
|
||||
if (this.isKeyDown(this.keys.down)) dir.y += 1;
|
||||
// 只有在键盘模式启用时才处理键盘输入
|
||||
if (this.enabledModes.keyboard) {
|
||||
// 创建一个方向对象,用于存储移动方向
|
||||
const dir = { x: 0, y: 0 };
|
||||
|
||||
// 检查左移键是否被按下,如果是则x方向减1(向左移动)
|
||||
if (this.isKeyDown(this.keys.left)) dir.x -= 1;
|
||||
// 检查右移键是否被按下,如果是则x方向加1(向右移动)
|
||||
if (this.isKeyDown(this.keys.right)) dir.x += 1;
|
||||
// 检查上移键是否被按下,如果是则y方向减1(向上移动)
|
||||
if (this.isKeyDown(this.keys.up)) dir.y -= 1;
|
||||
// 检查下移键是否被按下,如果是则y方向加1(向下移动)
|
||||
if (this.isKeyDown(this.keys.down)) dir.y += 1;
|
||||
|
||||
// 无论是否有按键按下,都发送移动事件
|
||||
// 当dir.x和dir.y都为0时,单位会停止移动
|
||||
this.scene.events.emit('move-relative', dir);
|
||||
// 无论是否有按键按下,都发送移动事件
|
||||
// 当dir.x和dir.y都为0时,单位会停止移动
|
||||
this.scene.events.emit('move-relative', dir);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理鼠标/触摸按下事件
|
||||
// @param {Object} pointer - 指针事件对象,包含鼠标/触摸的位置等信息
|
||||
onPointerDown(pointer) {
|
||||
// 检查鼠标是否在小地图或摇杆上,如果是则不处理框选
|
||||
if (this.isMouseOnMiniMap(pointer) || this.isMouseOnJoystick(pointer)) {
|
||||
// 检查鼠标是否在小地图、摇杆或侧边栏上,如果是则不处理
|
||||
if (this.isMouseOnMiniMap(pointer) || this.isMouseOnJoystick(pointer) || this.isMouseOnSidebar(pointer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -98,34 +110,60 @@ export class InputSystem {
|
||||
}
|
||||
});
|
||||
|
||||
// 检查是否点中了某个物品
|
||||
let clickedItem = null;
|
||||
// 遍历场景中的所有物品
|
||||
if (this.scene.itemManager && this.scene.itemManager.getActiveItems) {
|
||||
this.scene.itemManager.getActiveItems().forEach(item => {
|
||||
// 获取物品的边界矩形
|
||||
const bounds = item.getBounds();
|
||||
// 检查鼠标世界坐标是否在物品的边界内
|
||||
if (worldX >= bounds.x && worldX <= bounds.right &&
|
||||
worldY >= bounds.y && worldY <= bounds.bottom) {
|
||||
// 如果点中了物品,存储该物品
|
||||
clickedItem = item;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (clickedUnit) {
|
||||
// 如果点中了单位,发送选择单位事件
|
||||
this.scene.events.emit('select-unit', clickedUnit);
|
||||
} else {
|
||||
// 如果没有点中单位,开始框选或移动指令
|
||||
// 存储点击位置,用于判断是否是拖动操作
|
||||
this.dragStart = { x: worldX, y: worldY, clickedUnit: clickedUnit };
|
||||
// 不设置selectionStart,避免触发框选
|
||||
this.selectionStart = null;
|
||||
} else if (clickedItem) {
|
||||
// 如果点中了物品,不执行后续操作,避免触发移动
|
||||
this.selectionStart = null;
|
||||
this.dragStart = null;
|
||||
} else if (this.enabledModes.selection && !this.isCameraLocked()) {
|
||||
// 如果没有点中单位,且框选功能启用,且相机未锁定,开始框选操作
|
||||
// 存储框选开始时的世界坐标
|
||||
this.selectionStart = { x: worldX, y: worldY };
|
||||
// 发送选择开始事件
|
||||
this.scene.events.emit('selection-start', this.selectionStart);
|
||||
// 没有点中单位,清除dragStart
|
||||
this.dragStart = null;
|
||||
}
|
||||
} else if (pointer.rightButtonDown()) {
|
||||
// 如果是右键按下,发送移动到指定点的事件
|
||||
} else if (pointer.rightButtonDown() && this.enabledModes.mouse) {
|
||||
// 如果是右键按下且鼠标模式启用,发送移动到指定点的事件
|
||||
const worldX = pointer.worldX;
|
||||
const worldY = pointer.worldY;
|
||||
this.scene.events.emit('move-to-point', worldX, worldY);
|
||||
// 右键点击,清除dragStart
|
||||
this.dragStart = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理鼠标/触摸移动事件
|
||||
// @param {Object} pointer - 指针事件对象
|
||||
onPointerMove(pointer) {
|
||||
// 检查鼠标是否在小地图或摇杆上,如果是则不处理框选
|
||||
if (this.isMouseOnMiniMap(pointer) || this.isMouseOnJoystick(pointer)) {
|
||||
// 检查鼠标是否在小地图、摇杆或侧边栏上,如果是则不处理
|
||||
if (this.isMouseOnMiniMap(pointer) || this.isMouseOnJoystick(pointer) || this.isMouseOnSidebar(pointer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果当前正在进行框选操作
|
||||
if (this.selectionStart) {
|
||||
// 如果当前正在进行框选操作且框选功能启用
|
||||
if (this.selectionStart && this.enabledModes.selection) {
|
||||
// 获取当前鼠标在游戏世界中的坐标
|
||||
const currentWorldX = pointer.worldX;
|
||||
const currentWorldY = pointer.worldY;
|
||||
@@ -143,23 +181,48 @@ export class InputSystem {
|
||||
Math.abs(currentWorldY - this.selectionStart.y)
|
||||
);
|
||||
|
||||
// 发送选择更新事件,更新框选区域的显示
|
||||
this.scene.events.emit('selection-update', rect);
|
||||
// 只有当框选区域足够大时才发送选择更新事件
|
||||
if (rect.width > 5 || rect.height > 5) {
|
||||
// 发送选择更新事件,更新框选区域的显示
|
||||
this.scene.events.emit('selection-start', this.selectionStart);
|
||||
this.scene.events.emit('selection-update', rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理鼠标/触摸释放事件
|
||||
// @param {Object} pointer - 指针事件对象
|
||||
onPointerUp(pointer) {
|
||||
// 检查鼠标是否在小地图或摇杆上,如果是则不处理框选
|
||||
if (this.isMouseOnMiniMap(pointer) || this.isMouseOnJoystick(pointer)) {
|
||||
// 重置框选起始点
|
||||
// 检查鼠标是否在小地图、摇杆或侧边栏上,如果是则不处理
|
||||
if (this.isMouseOnMiniMap(pointer) || this.isMouseOnJoystick(pointer) || this.isMouseOnSidebar(pointer)) {
|
||||
// 重置框选起始点和拖动状态
|
||||
this.selectionStart = null;
|
||||
this.dragStart = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果当前正在进行框选操作
|
||||
if (this.selectionStart) {
|
||||
// 处理拖动单位的逻辑
|
||||
if (this.dragStart) {
|
||||
// 获取当前鼠标在游戏世界中的坐标
|
||||
const currentWorldX = pointer.worldX;
|
||||
const currentWorldY = pointer.worldY;
|
||||
|
||||
// 计算拖动距离
|
||||
const dx = currentWorldX - this.dragStart.x;
|
||||
const dy = currentWorldY - this.dragStart.y;
|
||||
const dragDistance = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
// 如果拖动距离超过阈值(10像素),视为拖动操作
|
||||
if (dragDistance > 10 && this.enabledModes.mouse) {
|
||||
// 发送移动到指定点的事件,让单位移动到释放位置
|
||||
this.scene.events.emit('move-to-point', currentWorldX, currentWorldY);
|
||||
}
|
||||
|
||||
// 重置拖动状态
|
||||
this.dragStart = null;
|
||||
}
|
||||
// 如果当前正在进行框选操作且框选功能启用
|
||||
else if (this.selectionStart && this.enabledModes.selection) {
|
||||
// 获取当前鼠标在游戏世界中的坐标
|
||||
const currentWorldX = pointer.worldX;
|
||||
const currentWorldY = pointer.worldY;
|
||||
@@ -173,8 +236,8 @@ export class InputSystem {
|
||||
);
|
||||
|
||||
// 如果框选区域太小(宽度和高度都小于10像素),视为点击地面移动
|
||||
if (rect.width < 10 && rect.height < 10) {
|
||||
// 发送移动到指定点的事件
|
||||
if (rect.width < 10 && rect.height < 10 && this.enabledModes.mouse) {
|
||||
// 发送移动到指定点的事件(仅在鼠标模式启用时)
|
||||
this.scene.events.emit('move-to-point', pointer.worldX, pointer.worldY);
|
||||
} else {
|
||||
// 否则执行框选操作
|
||||
@@ -203,11 +266,12 @@ export class InputSystem {
|
||||
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; // 小地图下边界
|
||||
// 小地图下边界,包括锁定按钮(按钮高度25,边距5)
|
||||
const mapBottom = miniMap.y + miniMap.mapSize + 30;
|
||||
|
||||
// 检查鼠标坐标是否在小地图边界内
|
||||
return mouseX >= mapLeft && mouseX <= mapRight &&
|
||||
@@ -242,4 +306,47 @@ export class InputSystem {
|
||||
return mouseX >= joystickLeft && mouseX <= joystickRight &&
|
||||
mouseY >= joystickTop && mouseY <= joystickBottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查相机是否被锁定到某个角色
|
||||
* @returns {boolean} - 如果相机被锁定返回true,否则返回false
|
||||
*/
|
||||
isCameraLocked() {
|
||||
// 检查ControlMode模块是否存在且cameraLocked属性已定义
|
||||
if (typeof window !== 'undefined' && window.cameraLocked !== undefined) {
|
||||
return window.cameraLocked;
|
||||
}
|
||||
|
||||
// 检查场景中是否有小地图且处于锁定状态
|
||||
if (this.scene.miniMap && this.scene.miniMap.isLocked) {
|
||||
return this.scene.miniMap.isLocked;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查鼠标是否在侧边栏上
|
||||
* @param {Phaser.Input.Pointer} pointer - 指针事件对象
|
||||
* @returns {boolean} - 如果鼠标在侧边栏上返回true,否则返回false
|
||||
*/
|
||||
isMouseOnSidebar(pointer) {
|
||||
// 检查场景中是否有侧边栏
|
||||
if (!this.scene.sidebar) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取侧边栏实例
|
||||
const sidebar = this.scene.sidebar;
|
||||
// 获取鼠标在屏幕上的坐标
|
||||
const mouseX = pointer.x;
|
||||
const mouseY = pointer.y;
|
||||
|
||||
// 获取侧边栏的边界
|
||||
const bounds = sidebar.getBounds();
|
||||
|
||||
// 检查鼠标坐标是否在侧边栏边界内
|
||||
return mouseX >= bounds.x && mouseX <= bounds.right &&
|
||||
mouseY >= bounds.y && mouseY <= bounds.bottom;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user