From 2a5084ab2ef581593331c6092affbdaaef14d63c Mon Sep 17 00:00:00 2001 From: chicrobot Date: Fri, 30 Jan 2026 15:44:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(MTTS)=20=E6=B7=BB=E5=8A=A0=E5=A4=9A?= =?UTF-8?q?=E7=82=B9=E8=A7=A6=E6=8E=A7=E6=B5=8B=E8=AF=95=E5=9C=BA=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.js | 5 +- scenes/BootScene.js | 1 + scenes/testScenes/MultiTouchTestScene.js | 422 +++++++++++++++++++++++ 3 files changed, 427 insertions(+), 1 deletion(-) create mode 100644 scenes/testScenes/MultiTouchTestScene.js diff --git a/main.js b/main.js index ac9f7a8..e797c0f 100644 --- a/main.js +++ b/main.js @@ -34,6 +34,8 @@ import SkillTestScene from './scenes/testScenes/SkillTestScene.js'; import AttackSkillTestScene from './scenes/testScenes/AttackSkillTestScene.js'; // 导入迷雾测试场景 import FogOfWarTestScene from './scenes/testScenes/FogOfWarTestScene.js'; +// 导入多点触控测试场景 +import MultiTouchTestScene from './scenes/testScenes/MultiTouchTestScene.js'; // 导入菜单场景 import MenuScene from './scenes/MenuScene.js'; // 导入临时场景 @@ -68,7 +70,8 @@ const config = { FarmingTestScene, SkillTestScene, AttackSkillTestScene, - FogOfWarTestScene + FogOfWarTestScene, + MultiTouchTestScene ] }; diff --git a/scenes/BootScene.js b/scenes/BootScene.js index c420217..4e7cb0c 100644 --- a/scenes/BootScene.js +++ b/scenes/BootScene.js @@ -17,6 +17,7 @@ export default class BootScene extends Phaser.Scene { // 测试场景列表 const testScenes = [ + { key: 'MultiTouchTestScene', name: '测试场景20:多触摸测试' }, { key: 'TestObjectsScene', name: '测试场景19:测试对象场景' }, { key: 'TmpScene', name: '测试场景18:临时场景' }, { key: 'FogOfWarTestScene', name: '测试场景17:迷雾系统测试' }, diff --git a/scenes/testScenes/MultiTouchTestScene.js b/scenes/testScenes/MultiTouchTestScene.js new file mode 100644 index 0000000..59ec91f --- /dev/null +++ b/scenes/testScenes/MultiTouchTestScene.js @@ -0,0 +1,422 @@ +// 多点触控测试场景 +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(); + } + }); + } +}