From 3863cfe1f6969dde3796eff5e34b7e465f6999b6 Mon Sep 17 00:00:00 2001 From: chicrobot Date: Wed, 31 Dec 2025 00:48:54 +0800 Subject: [PATCH] =?UTF-8?q?feat(control)=20=E6=91=87=E6=9D=86=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scenes/GameScene.js | 11 ++++++++++- systems/InputSystem.js | 39 +++++++++++++++++++++++++++++++++------ ui/VirtualJoystick.js | 31 +++++++++++++++++++++++++------ 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/scenes/GameScene.js b/scenes/GameScene.js index 34b6c1e..32eebb3 100644 --- a/scenes/GameScene.js +++ b/scenes/GameScene.js @@ -24,10 +24,14 @@ export default class GameScene extends Phaser.Scene { this.textures.addCanvas('player', canvas); } - // === 2. 扩大物理世界和相机边界(关键!)=== + // === 2. 扩大物理世界和相机边界(关键!)=== const worldSize = 2000; this.physics.world.setBounds(-worldSize, -worldSize, worldSize * 2, worldSize * 2); this.cameras.main.setBounds(-worldSize, -worldSize, worldSize * 2, worldSize * 2); + + // 设置相机起始位置在地图中心 + // 使用centerOn方法将相机中心定位在地图坐标(0, 0) + this.cameras.main.centerOn(0, 0); // 地图中心坐标是(0, 0) // === 3. 创建单位组 === this.unitGroup = this.add.group(); @@ -72,6 +76,11 @@ export default class GameScene extends Phaser.Scene { if (this.miniMap) { this.miniMap.update(); } + + // 更新虚拟摇杆 + if (this.virtualJoystick) { + this.virtualJoystick.update(); + } } /** diff --git a/systems/InputSystem.js b/systems/InputSystem.js index 26b93d7..341d4a7 100644 --- a/systems/InputSystem.js +++ b/systems/InputSystem.js @@ -42,8 +42,8 @@ export class InputSystem { } onPointerDown(pointer) { - // 检查鼠标是否在小地图上,如果是则不处理框选 - if (this.isMouseOnMiniMap(pointer)) { + // 检查鼠标是否在小地图或摇杆上,如果是则不处理框选 + if (this.isMouseOnMiniMap(pointer) || this.isMouseOnJoystick(pointer)) { return; } @@ -79,8 +79,8 @@ export class InputSystem { } onPointerMove(pointer) { - // 检查鼠标是否在小地图上,如果是则不处理框选 - if (this.isMouseOnMiniMap(pointer)) { + // 检查鼠标是否在小地图或摇杆上,如果是则不处理框选 + if (this.isMouseOnMiniMap(pointer) || this.isMouseOnJoystick(pointer)) { return; } @@ -103,8 +103,8 @@ export class InputSystem { } onPointerUp(pointer) { - // 检查鼠标是否在小地图上,如果是则不处理框选 - if (this.isMouseOnMiniMap(pointer)) { + // 检查鼠标是否在小地图或摇杆上,如果是则不处理框选 + if (this.isMouseOnMiniMap(pointer) || this.isMouseOnJoystick(pointer)) { this.selectionStart = null; return; } @@ -158,4 +158,31 @@ export class InputSystem { return mouseX >= mapLeft && mouseX <= mapRight && mouseY >= mapTop && mouseY <= mapBottom; } + + /** + * 检查鼠标是否在摇杆上 + * @param {Phaser.Input.Pointer} pointer + * @returns {boolean} + */ + isMouseOnJoystick(pointer) { + // 检查场景中是否有虚拟摇杆 + if (!this.scene.virtualJoystick) { + return false; + } + + const joystick = this.scene.virtualJoystick; + const mouseX = pointer.x; + const mouseY = pointer.y; + + // 计算摇杆的边界(包括摇杆和操作区域) + const joystickRadius = joystick.radius * 2; // 操作区域是摇杆半径的两倍 + const joystickLeft = joystick.centerX - joystickRadius; + const joystickRight = joystick.centerX + joystickRadius; + const joystickTop = joystick.centerY - joystickRadius; + const joystickBottom = joystick.centerY + joystickRadius; + + // 检查鼠标是否在摇杆边界内 + return mouseX >= joystickLeft && mouseX <= joystickRight && + mouseY >= joystickTop && mouseY <= joystickBottom; + } } \ No newline at end of file diff --git a/ui/VirtualJoystick.js b/ui/VirtualJoystick.js index c18bdec..08bd689 100644 --- a/ui/VirtualJoystick.js +++ b/ui/VirtualJoystick.js @@ -11,15 +11,19 @@ export class VirtualJoystick { this.radius = 50; // 仅在触屏设备显示 - if ('ontouchstart' in window) { - this.create(); - this.bindEvents(); - } + // if ('ontouchstart' in window) { + // this.create(); + // this.bindEvents(); + // } + + // 在所有设备上都显示摇杆 + this.create(); + this.bindEvents(); } create() { - const x = 100; - const y = this.scene.scale.height - 100; + const x = 200; + const y = this.scene.scale.height - 200; this.centerX = x; this.centerY = y; @@ -75,4 +79,19 @@ export class VirtualJoystick { const dy = pointer.y - this.centerY; return Math.sqrt(dx * dx + dy * dy) <= this.radius + 20; // 容差 } + + /** + * 更新方法,用于在游戏循环中持续发送移动指令 + */ + update() { + if (this.isActive && this.pointer) { + const dx = this.pointer.x - this.centerX; + const dy = this.pointer.y - this.centerY; + + // 发送相对方向(归一化) + const dirX = dx / this.radius; + const dirY = dy / this.radius; + this.scene.events.emit('move-relative', { x: dirX, y: dirY }); + } + } } \ No newline at end of file