feat(control) 多角色控制

This commit is contained in:
chicrobot committed 2025-12-30 21:45:25 +08:00
1 parent be5ee91328
commit f86e5f3a79
11 files changed
+431

No files matched your search

+78
View File
@@ -0,0 +1,78 @@
// ui/VirtualJoystick.js
export class VirtualJoystick {
constructor(scene) {
this.scene = scene;
this.isActive = false;
this.base = null;
this.knob = null;
this.pointer = null;
this.centerX = 0;
this.centerY = 0;
this.radius = 50;
// 仅在触屏设备显示
if ('ontouchstart' in window) {
this.create();
this.bindEvents();
}
}
create() {
const x = 100;
const y = this.scene.scale.height - 100;
this.centerX = x;
this.centerY = y;
this.base = this.scene.add.circle(x, y, this.radius, 0x444444, 0.5);
this.knob = this.scene.add.circle(x, y, this.radius * 0.5, 0xff0000, 0.8);
this.base.setScrollFactor(0); // 不随相机移动
this.knob.setScrollFactor(0);
}
bindEvents() {
this.scene.input.on('pointerdown', (ptr) => {
if (this.isInBase(ptr)) {
this.pointer = ptr;
this.isActive = true;
}
});
this.scene.input.on('pointermove', (ptr) => {
if (this.isActive && this.pointer === ptr) {
const dx = ptr.x - this.centerX;
const dy = ptr.y - this.centerY;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance > this.radius) {
// 限制在圆内
const angle = Math.atan2(dy, dx);
ptr.x = this.centerX + Math.cos(angle) * this.radius;
ptr.y = this.centerY + Math.sin(angle) * this.radius;
}
this.knob.setPosition(ptr.x, ptr.y);
// 发送相对方向(归一化)
const dirX = dx / this.radius;
const dirY = dy / this.radius;
this.scene.events.emit('move-relative', { x: dirX, y: dirY });
}
});
this.scene.input.on('pointerup', (ptr) => {
if (this.pointer === ptr) {
this.isActive = false;
this.pointer = null;
this.knob.setPosition(this.centerX, this.centerY);
this.scene.events.emit('move-relative', { x: 0, y: 0 }); // 停止
}
});
}
isInBase(pointer) {
const dx = pointer.x - this.centerX;
const dy = pointer.y - this.centerY;
return Math.sqrt(dx * dx + dy * dy) <= this.radius + 20; // 容差
}
}