mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-30 05:31:29 +08:00
423 lines
12 KiB
JavaScript
423 lines
12 KiB
JavaScript
// 多点触控测试场景
|
|
import { VirtualJoystick } from '../../ui/VirtualJoystick.js';
|
|
|
|
export default class MultiTouchTestScene extends Phaser.Scene {
|
|
constructor() {
|
|
super({ key: 'MultiTouchTestScene' });
|
|
|
|
// 多点触控相关变量
|
|
this.activeTouches = new Map(); // 存储活跃的触摸点
|
|
this.maxTouchPoints = 10; // 最大触摸点数量
|
|
this.touchVisualizations = []; // 触摸点可视化元素
|
|
this.joysticks = []; // 多个虚拟摇杆
|
|
this.dualJoystickEnabled = true; // 是否启用双摇杆
|
|
|
|
// 测试对象
|
|
this.testObjects = [];
|
|
}
|
|
|
|
create() {
|
|
// 设置物理世界和相机边界
|
|
const worldSize = 1000;
|
|
this.physics.world.setBounds(-worldSize, -worldSize, worldSize * 2, worldSize * 2);
|
|
this.cameras.main.setBounds(-worldSize, -worldSize, worldSize * 2, worldSize * 2);
|
|
this.cameras.main.centerOn(0, 0);
|
|
|
|
// 创建测试网格
|
|
this.createGrid();
|
|
|
|
// 创建测试对象
|
|
this.createTestObjects();
|
|
|
|
// 初始化多点触控处理
|
|
this.initMultiTouch();
|
|
|
|
// 创建双虚拟摇杆(如果启用)
|
|
if (this.dualJoystickEnabled) {
|
|
this.createDualJoysticks();
|
|
}
|
|
|
|
// 创建触摸点可视化
|
|
this.createTouchVisualizations();
|
|
|
|
// 添加场景说明文本
|
|
this.createUI();
|
|
|
|
// 添加返回菜单按钮
|
|
this.createReturnButton();
|
|
}
|
|
|
|
createGrid() {
|
|
const graphics = this.add.graphics();
|
|
graphics.lineStyle(1, 0x555555, 0.3);
|
|
|
|
const gridSize = 50;
|
|
const worldSize = 1000;
|
|
|
|
// 绘制垂直线
|
|
for (let x = -worldSize; x <= worldSize; x += gridSize) {
|
|
graphics.moveTo(x, -worldSize);
|
|
graphics.lineTo(x, worldSize);
|
|
}
|
|
|
|
// 绘制水平线
|
|
for (let y = -worldSize; y <= worldSize; y += gridSize) {
|
|
graphics.moveTo(-worldSize, y);
|
|
graphics.lineTo(worldSize, y);
|
|
}
|
|
|
|
graphics.strokePath();
|
|
graphics.setDepth(-10);
|
|
graphics.setScrollFactor(1);
|
|
}
|
|
|
|
createTestObjects() {
|
|
// 创建多个测试对象
|
|
const colors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff];
|
|
|
|
for (let i = 0; i < 5; i++) {
|
|
const x = Phaser.Math.Between(-500, 500);
|
|
const y = Phaser.Math.Between(-500, 500);
|
|
const color = colors[i % colors.length];
|
|
|
|
const testObject = this.add.circle(x, y, 20, color, 0.8);
|
|
testObject.setInteractive({ useHandCursor: true });
|
|
testObject.id = i;
|
|
testObject.isDragging = false;
|
|
testObject.dragPointerId = null;
|
|
|
|
// 添加拖拽事件
|
|
testObject.on('pointerdown', (pointer) => {
|
|
testObject.isDragging = true;
|
|
testObject.dragPointerId = pointer.id;
|
|
testObject.setScale(1.2);
|
|
testObject.setDepth(10);
|
|
});
|
|
|
|
this.testObjects.push(testObject);
|
|
}
|
|
}
|
|
|
|
initMultiTouch() {
|
|
// 启用多点触控
|
|
this.input.addPointer(this.maxTouchPoints - 1); // 默认为1,所以需要添加9个
|
|
|
|
// 监听触摸开始事件
|
|
this.input.on('pointerdown', (pointer) => {
|
|
this.activeTouches.set(pointer.id, {
|
|
x: pointer.x,
|
|
y: pointer.y,
|
|
time: Date.now()
|
|
});
|
|
this.updateTouchVisualization();
|
|
});
|
|
|
|
// 监听触摸移动事件
|
|
this.input.on('pointermove', (pointer) => {
|
|
if (this.activeTouches.has(pointer.id)) {
|
|
this.activeTouches.set(pointer.id, {
|
|
x: pointer.x,
|
|
y: pointer.y,
|
|
time: Date.now()
|
|
});
|
|
|
|
// 更新触摸点可视化
|
|
this.updateTouchVisualization();
|
|
|
|
// 处理测试对象的拖拽
|
|
this.handleObjectDrag(pointer);
|
|
}
|
|
});
|
|
|
|
// 监听触摸结束事件
|
|
this.input.on('pointerup', (pointer) => {
|
|
this.activeTouches.delete(pointer.id);
|
|
this.updateTouchVisualization();
|
|
this.endObjectDrag(pointer.id);
|
|
});
|
|
|
|
// 监听触摸离开屏幕事件
|
|
this.input.on('pointerout', (pointer) => {
|
|
this.activeTouches.delete(pointer.id);
|
|
this.updateTouchVisualization();
|
|
this.endObjectDrag(pointer.id);
|
|
});
|
|
}
|
|
|
|
createDualJoysticks() {
|
|
// 创建左侧移动摇杆
|
|
const leftJoystick = new VirtualJoystick(this, true);
|
|
leftJoystick.centerX = 150;
|
|
leftJoystick.centerY = this.scale.height - 150;
|
|
leftJoystick.base.setPosition(leftJoystick.centerX, leftJoystick.centerY);
|
|
leftJoystick.knob.setPosition(leftJoystick.centerX, leftJoystick.centerY);
|
|
this.joysticks.push(leftJoystick);
|
|
|
|
// 创建右侧操作摇杆
|
|
const rightJoystick = new VirtualJoystick(this, true);
|
|
rightJoystick.centerX = this.scale.width - 150;
|
|
rightJoystick.centerY = this.scale.height - 150;
|
|
rightJoystick.base.setPosition(rightJoystick.centerX, rightJoystick.centerY);
|
|
rightJoystick.knob.setPosition(rightJoystick.centerX, rightJoystick.centerY);
|
|
this.joysticks.push(rightJoystick);
|
|
|
|
// 重写右侧摇杆的事件处理,使其发送不同的事件
|
|
rightJoystick.bindEvents = function() {
|
|
this.scene.input.on('pointerdown', (ptr) => {
|
|
if (this.isInBase(ptr)) {
|
|
if (!this.isActive) {
|
|
this.activePointer = ptr;
|
|
this.isActive = true;
|
|
}
|
|
}
|
|
});
|
|
|
|
this.scene.input.on('pointermove', (ptr) => {
|
|
if (this.isActive && this.activePointer === 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);
|
|
const knobX = this.centerX + Math.cos(angle) * this.radius;
|
|
const knobY = this.centerY + Math.sin(angle) * this.radius;
|
|
this.knob.setPosition(knobX, knobY);
|
|
} else {
|
|
this.knob.setPosition(ptr.x, ptr.y);
|
|
}
|
|
|
|
// 发送右侧摇杆事件
|
|
const dirX = dx / this.radius;
|
|
const dirY = dy / this.radius;
|
|
this.scene.events.emit('right-joystick-move', { x: dirX, y: dirY });
|
|
}
|
|
});
|
|
|
|
this.scene.input.on('pointerup', (ptr) => {
|
|
if (this.activePointer === ptr) {
|
|
this.isActive = false;
|
|
this.activePointer = null;
|
|
this.knob.setPosition(this.centerX, this.centerY);
|
|
this.scene.events.emit('right-joystick-move', { x: 0, y: 0 });
|
|
}
|
|
});
|
|
|
|
this.scene.input.on('pointerout', (ptr) => {
|
|
if (this.activePointer === ptr) {
|
|
this.isActive = false;
|
|
this.activePointer = null;
|
|
this.knob.setPosition(this.centerX, this.centerY);
|
|
this.scene.events.emit('right-joystick-move', { x: 0, y: 0 });
|
|
}
|
|
});
|
|
};
|
|
|
|
// 重新绑定右侧摇杆事件
|
|
rightJoystick.bindEvents();
|
|
|
|
// 监听右侧摇杆事件
|
|
this.events.on('right-joystick-move', (direction) => {
|
|
this.handleRightJoystickInput(direction);
|
|
});
|
|
}
|
|
|
|
createTouchVisualizations() {
|
|
// 创建触摸点可视化元素
|
|
for (let i = 0; i < this.maxTouchPoints; i++) {
|
|
const visualization = this.add.circle(0, 0, 30, 0xffffff, 0.5);
|
|
visualization.setStrokeStyle(2, 0x00ff00, 1);
|
|
visualization.setVisible(false);
|
|
visualization.setScrollFactor(0);
|
|
visualization.setDepth(100);
|
|
|
|
const label = this.add.text(0, 0, i.toString(), {
|
|
fontSize: '14px',
|
|
fill: '#000000',
|
|
fontFamily: 'Arial',
|
|
fontWeight: 'bold'
|
|
});
|
|
label.setOrigin(0.5, 0.5);
|
|
label.setVisible(false);
|
|
label.setScrollFactor(0);
|
|
label.setDepth(101);
|
|
|
|
this.touchVisualizations.push({ circle: visualization, label: label });
|
|
}
|
|
}
|
|
|
|
updateTouchVisualization() {
|
|
// 重置所有可视化元素
|
|
this.touchVisualizations.forEach(viz => {
|
|
viz.circle.setVisible(false);
|
|
viz.label.setVisible(false);
|
|
});
|
|
|
|
// 更新活跃触摸点的可视化
|
|
let i = 0;
|
|
for (const [id, touch] of this.activeTouches.entries()) {
|
|
if (i < this.touchVisualizations.length) {
|
|
const viz = this.touchVisualizations[i];
|
|
viz.circle.setPosition(touch.x, touch.y);
|
|
viz.circle.setVisible(true);
|
|
viz.label.setPosition(touch.x, touch.y);
|
|
viz.label.setText(id.toString());
|
|
viz.label.setVisible(true);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
handleObjectDrag(pointer) {
|
|
// 处理测试对象的拖拽
|
|
this.testObjects.forEach(obj => {
|
|
if (obj.isDragging && obj.dragPointerId === pointer.id) {
|
|
obj.setPosition(pointer.x, pointer.y);
|
|
}
|
|
});
|
|
}
|
|
|
|
endObjectDrag(pointerId) {
|
|
// 结束测试对象的拖拽
|
|
this.testObjects.forEach(obj => {
|
|
if (obj.dragPointerId === pointerId) {
|
|
obj.isDragging = false;
|
|
obj.dragPointerId = null;
|
|
obj.setScale(1);
|
|
obj.setDepth(0);
|
|
}
|
|
});
|
|
}
|
|
|
|
handleRightJoystickInput(direction) {
|
|
// 处理右侧摇杆输入
|
|
// 这里可以实现攻击、技能释放等操作
|
|
if (Math.abs(direction.x) > 0.1 || Math.abs(direction.y) > 0.1) {
|
|
// 创建一个临时的指示箭头
|
|
this.createDirectionIndicator(direction);
|
|
}
|
|
}
|
|
|
|
createDirectionIndicator(direction) {
|
|
// 创建方向指示箭头
|
|
const centerX = this.scale.width - 150;
|
|
const centerY = this.scale.height - 150;
|
|
|
|
const length = 100;
|
|
const endX = centerX + direction.x * length;
|
|
const endY = centerY + direction.y * length;
|
|
|
|
// 检查是否已存在指示箭头
|
|
if (this.directionIndicator) {
|
|
this.directionIndicator.clear();
|
|
} else {
|
|
this.directionIndicator = this.add.graphics();
|
|
this.directionIndicator.setScrollFactor(0);
|
|
this.directionIndicator.setDepth(9);
|
|
}
|
|
|
|
// 绘制箭头
|
|
this.directionIndicator.lineStyle(3, 0xffff00, 1);
|
|
this.directionIndicator.beginPath();
|
|
this.directionIndicator.moveTo(centerX, centerY);
|
|
this.directionIndicator.lineTo(endX, endY);
|
|
this.directionIndicator.strokePath();
|
|
|
|
// 3秒后清除箭头
|
|
this.time.delayedCall(300, () => {
|
|
if (this.directionIndicator) {
|
|
this.directionIndicator.clear();
|
|
}
|
|
});
|
|
}
|
|
|
|
createUI() {
|
|
// 添加场景标题
|
|
const titleText = this.add.text(10, 10, '测试场景:多点触控', {
|
|
fontSize: '24px',
|
|
fill: '#ffffff',
|
|
fontFamily: 'Arial',
|
|
fontWeight: 'bold'
|
|
});
|
|
titleText.setScrollFactor(0);
|
|
titleText.setDepth(100);
|
|
|
|
// 添加操作说明
|
|
const instructions = this.add.text(10, 50, [
|
|
'操作说明:',
|
|
'• 用多个手指同时触摸屏幕',
|
|
'• 拖动彩色圆形对象',
|
|
'• 使用左侧摇杆移动视角',
|
|
'• 使用右侧摇杆查看方向指示',
|
|
'• 按空格键返回菜单'
|
|
], {
|
|
fontSize: '16px',
|
|
fill: '#ffffff',
|
|
fontFamily: 'Arial',
|
|
lineSpacing: 8
|
|
});
|
|
instructions.setScrollFactor(0);
|
|
instructions.setDepth(100);
|
|
|
|
// 添加触摸点计数
|
|
this.touchCountText = this.add.text(10, 200, '触摸点数量:0', {
|
|
fontSize: '18px',
|
|
fill: '#00ff00',
|
|
fontFamily: 'Arial',
|
|
fontWeight: 'bold'
|
|
});
|
|
this.touchCountText.setScrollFactor(0);
|
|
this.touchCountText.setDepth(100);
|
|
|
|
// 添加空格键返回菜单
|
|
this.input.keyboard.on('keydown-SPACE', () => {
|
|
this.scene.start('BootScene');
|
|
});
|
|
}
|
|
|
|
createReturnButton() {
|
|
// 创建返回菜单按钮
|
|
const button = this.add.rectangle(10, this.scale.height - 60, 150, 40, 0x333333);
|
|
button.setOrigin(0, 0);
|
|
button.setScrollFactor(0);
|
|
button.setDepth(100);
|
|
button.setInteractive({ useHandCursor: true });
|
|
|
|
// 按钮文本
|
|
const buttonText = this.add.text(25, this.scale.height - 50, '返回菜单', {
|
|
fontSize: '16px',
|
|
fill: '#ffffff',
|
|
fontFamily: 'Arial'
|
|
});
|
|
buttonText.setScrollFactor(0);
|
|
buttonText.setDepth(101);
|
|
|
|
// 按钮事件
|
|
button.on('pointerdown', () => {
|
|
this.scene.start('BootScene');
|
|
});
|
|
|
|
button.on('pointerover', () => {
|
|
button.setFillStyle(0x555555);
|
|
});
|
|
|
|
button.on('pointerout', () => {
|
|
button.setFillStyle(0x333333);
|
|
});
|
|
}
|
|
|
|
update() {
|
|
// 更新触摸点计数
|
|
if (this.touchCountText) {
|
|
this.touchCountText.setText(`触摸点数量:${this.activeTouches.size}`);
|
|
}
|
|
|
|
// 更新虚拟摇杆
|
|
this.joysticks.forEach(joystick => {
|
|
if (joystick.update) {
|
|
joystick.update();
|
|
}
|
|
});
|
|
}
|
|
}
|