/** * TestObjectsScene - 测试场景,展示Phaser中的各种对象类型 */ export default class TestObjectsScene extends Phaser.Scene { constructor() { super('TestObjectsScene'); } preload() { // 注意:实际项目中需要先加载纹理 // 本示例使用内置图形,不需要加载外部资源 } create() { // 设置背景色 this.cameras.main.setBackgroundColor('#222222'); // 获取屏幕宽度,用于响应式布局 const screenWidth = this.cameras.main.width; const screenHeight = this.cameras.main.height; const centerX = screenWidth / 2; // 设置世界边界,允许滚动 this.cameras.main.setBounds(0, 0, screenWidth, 3000); // 滚动相关变量 this.scrollVelocity = 0; this.scrollAcceleration = 0.98; // 启用鼠标/触摸滚动 this.input.on('pointermove', (pointer) => { if (pointer.isDown) { // 调整滚动速度和方向:向上拖动时内容向上滚动,速度更快 this.scrollVelocity = -pointer.velocity.y * 0.15; this.cameras.main.scrollY += this.scrollVelocity; // 限制滚动范围 this.cameras.main.scrollY = Phaser.Math.Clamp(this.cameras.main.scrollY, 0, 2400); } }); // 停止触摸时应用惯性滚动 this.input.on('pointerup', () => { // 创建惯性滚动 this.tweens.add({ targets: this, scrollVelocity: 0, duration: 500, ease: 'Power2', onUpdate: (tween) => { this.cameras.main.scrollY += this.scrollVelocity; // 限制滚动范围 this.cameras.main.scrollY = Phaser.Math.Clamp(this.cameras.main.scrollY, 0, 2400); } }); }); // 1. 文本对象 this.createTextObjects(centerX); // 2. 图像和精灵 this.createImageObjects(centerX); // 3. 图形对象 this.createGraphicsObjects(centerX); // 4. 容器对象 this.createContainerObjects(centerX); // 5. 粒子系统 this.createParticles(centerX); // 6. 物理对象(简单示例) this.createPhysicsObjects(centerX); // 7. 精灵对象 this.createSpriteObjects(centerX); // 8. 瓦片地图 this.createTilemapObjects(centerX); // 9. 点阵文字 this.createBitmapTextObjects(centerX); // 10. 渲染纹理 this.createRenderTextureObjects(centerX); // 11. 形状对象 this.createShapeObjects(centerX); // 12. 多相机系统 this.createCameraObjects(centerX); // 13. 灯光系统 this.createLightObjects(centerX); // 14. 路径系统 this.createPathObjects(centerX); // 15. 网格系统 this.createGridObjects(centerX); // 16. 时间线 this.createTimelineObjects(centerX); // 添加滚动指示器 this.add.text(centerX, 2850, '↓ 向下滚动查看更多 ↓', { fontSize: '14px', fill: '#aaaaaa', backgroundColor: '#333333', padding: { x: 15, y: 8 } }) .setOrigin(0.5) .setScrollFactor(0); // 固定在屏幕底部 // 添加顶部指示器 this.add.text(centerX, 10, '↑ 向上滚动返回顶部 ↑', { fontSize: '14px', fill: '#aaaaaa', backgroundColor: '#333333', padding: { x: 15, y: 8 } }) .setOrigin(0.5) .setScrollFactor(0); // 固定在屏幕顶部 // 添加返回按钮 this.add.text(20, 20, '按 ESC 返回', { fontSize: '16px', fill: '#ffffff' }) .setInteractive() .on('pointerdown', () => { this.scene.start('TmpScene'); }); } // 创建文本对象 createTextObjects(centerX) { // 基本文本 this.add.text(centerX, 50, '1. 文本对象示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 带样式的文本 this.add.text(centerX, 90, '普通文本', { fontSize: '16px', fill: '#cccccc' }).setOrigin(0.5); // 彩色文本 this.add.text(centerX, 120, '彩色文本', { fontSize: '16px', fill: '#ff0000' }).setOrigin(0.5); // 带背景的文本 this.add.text(centerX, 150, '带背景的文本', { fontSize: '16px', fill: '#ffffff', backgroundColor: '#444444', padding: { x: 10, y: 5 } }).setOrigin(0.5); } // 创建图像和精灵 createImageObjects(centerX) { // 标题 this.add.text(centerX, 200, '2. 图像和精灵示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 使用图形替代图像 const logo = this.add.graphics() .fillStyle(0x3498db, 1) .fillRect(0, 0, 100, 50) .setPosition(centerX - 50, 255) .setInteractive(new Phaser.Geom.Rectangle(0, 0, 100, 50), Phaser.Geom.Rectangle.Contains) .on('pointerdown', function() { this.scaleX *= 1.1; this.scaleY *= 1.1; }); // 添加文本标签 this.add.text(centerX, 270, 'Phaser Logo', { fontSize: '12px', fill: '#ffffff' }).setOrigin(0.5); // 精灵(使用圆形替代纹理) const redDot = this.add.circle(centerX, 320, 10, 0xff0000, 1) .setInteractive() .on('pointerdown', function() { this.angle += 45; }); } // 创建图形对象 createGraphicsObjects(centerX) { // 标题 this.add.text(centerX, 350, '3. 图形对象示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 矩形 this.add.rectangle(centerX - 80, 420, 100, 60, 0xff0000, 0.5) .setInteractive() .on('pointerdown', function() { this.fillColor = Phaser.Math.Between(0x000000, 0xffffff); }); // 圆形 this.add.circle(centerX, 420, 30, 0x00ff00, 0.5) .setInteractive() .on('pointerdown', function() { this.radius = Phaser.Math.Between(20, 40); }); // 线段 this.add.line(centerX + 80, 420, 0, -30, 0, 30, 0xffff00, 1) .setInteractive() .on('pointerdown', function() { this.angle += 15; }); } // 创建容器对象 createContainerObjects(centerX) { // 标题 this.add.text(centerX, 480, '4. 容器对象示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 创建容器 const container = this.add.container(centerX, 550); // 容器背景 const bg = this.add.rectangle(0, 0, 200, 100, 0x444444, 0.8); container.add(bg); // 容器内的文本 const text = this.add.text(0, 0, '容器示例', { fontSize: '16px', fill: '#ffffff' }).setOrigin(0.5); container.add(text); // 容器内的圆形 const circle = this.add.circle(0, 30, 10, 0x00ffff, 1); container.add(circle); // 使容器可交互 container.setInteractive(new Phaser.Geom.Rectangle(-100, -50, 200, 100), Phaser.Geom.Rectangle.Contains) .on('pointerdown', () => { container.angle += 10; }); } // 创建粒子系统 createParticles(centerX) { // 标题 this.add.text(centerX, 650, '5. 粒子系统示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 注意:粒子系统需要纹理,实际项目中需要先加载 // 本示例使用图形替代粒子效果 const particles = this.add.graphics() .fillStyle(0x3498db, 1) .fillCircle(0, 0, 5) .setPosition(centerX, 720) .setVisible(false); // 添加交互,点击时显示粒子效果 this.add.text(centerX, 750, '点击显示粒子效果', { fontSize: '14px', fill: '#ffffff', backgroundColor: '#444444', padding: { x: 10, y: 5 } }) .setOrigin(0.5) .setInteractive() .on('pointerdown', () => { // 创建多个圆形模拟粒子效果 for (let i = 0; i < 20; i++) { const particle = this.add.circle(centerX, 720, 3, 0x3498db, 1); this.tweens.add({ targets: particle, x: centerX + Phaser.Math.Between(-100, 100), y: 720 + Phaser.Math.Between(-100, -50), alpha: 0, scale: 0, duration: 1000, onComplete: function() { particle.destroy(); } }); } }); } // 创建物理对象(简单示例) createPhysicsObjects(centerX) { // 标题 this.add.text(centerX, 800, '6. 物理对象示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 注意:物理系统需要在游戏配置中启用 // 本示例使用图形替代物理对象 const ground = this.add.rectangle(centerX, 880, 300, 20, 0x666666, 1); // 创建圆形图形 const ball = this.add.circle(centerX, 820, 10, 0xe74c3c, 1) .setInteractive() .on('pointerdown', function() { // 模拟物理效果 this.setY(this.y - 50); this.scene.tweens.add({ targets: this, y: 820, duration: 500, ease: 'Bounce.easeOut' }); }); // 添加交互,点击时给球一个向上的力 this.add.text(centerX, 880, '点击小球', { fontSize: '14px', fill: '#ffffff' }) .setOrigin(0.5); } update() { // 可以在这里添加对象的更新逻辑 } // 7. 精灵对象 createSpriteObjects(centerX) { // 标题 this.add.text(centerX, 950, '7. 精灵对象示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 注意:精灵需要纹理,实际项目中需要先加载 // 本示例使用图形替代精灵 const sprite = this.add.graphics() .fillStyle(0x9b59b6, 1) .fillCircle(0, 0, 20) .setPosition(centerX, 1020) .setInteractive(new Phaser.Geom.Circle(0, 0, 20), Phaser.Geom.Circle.Contains) .on('pointerdown', function() { this.angle += 30; }); // 添加文本标签 this.add.text(centerX, 1060, '精灵示例', { fontSize: '14px', fill: '#ffffff' }).setOrigin(0.5); } // 8. 瓦片地图 createTilemapObjects(centerX) { // 标题 this.add.text(centerX, 1100, '8. 瓦片地图示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 注意:瓦片地图需要纹理,实际项目中需要先加载 // 本示例使用图形替代瓦片地图 const tilemap = this.add.graphics() .fillStyle(0x27ae60, 0.8) .fillRect(0, 0, 200, 100) .setPosition(centerX - 100, 1140); // 添加模拟瓦片 for (let i = 0; i < 5; i++) { for (let j = 0; j < 10; j++) { this.add.rectangle( centerX - 90 + j * 20, 1150 + i * 20, 18, 18, 0x2ecc71, 0.6 ); } } // 添加文本标签 this.add.text(centerX, 1260, '瓦片地图示例', { fontSize: '14px', fill: '#ffffff' }).setOrigin(0.5); } // 9. 点阵文字 createBitmapTextObjects(centerX) { // 标题 this.add.text(centerX, 1300, '9. 点阵文字示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 注意:点阵文字需要字体纹理,实际项目中需要先加载 // 本示例使用普通文本替代 this.add.text(centerX, 1340, '点阵文字示例', { fontSize: '16px', fill: '#f1c40f', fontFamily: 'monospace' }).setOrigin(0.5); // 添加文本标签 this.add.text(centerX, 1380, '(使用普通文本模拟)', { fontSize: '12px', fill: '#cccccc' }).setOrigin(0.5); } // 10. 渲染纹理 createRenderTextureObjects(centerX) { // 标题 this.add.text(centerX, 1420, '10. 渲染纹理示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 创建渲染纹理 const rt = this.add.renderTexture(centerX - 100, 1460, 200, 100); // 绘制一些内容到渲染纹理 const graphics = this.add.graphics().setVisible(false); graphics.fillStyle(0xe74c3c, 1); graphics.fillCircle(100, 50, 30); graphics.lineStyle(2, 0xffffff, 1); graphics.lineBetween(50, 50, 150, 50); // 将图形绘制到渲染纹理 rt.draw(graphics, 0, 0); // 添加交互,点击时清除并重新绘制 rt.setInteractive(new Phaser.Geom.Rectangle(0, 0, 200, 100), Phaser.Geom.Rectangle.Contains) .on('pointerdown', function() { this.clear(); this.draw(graphics, Phaser.Math.Between(0, 100), Phaser.Math.Between(0, 50)); }); } // 11. 形状对象 createShapeObjects(centerX) { // 标题 this.add.text(centerX, 1550, '11. 形状对象示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 创建三角形(使用graphics) const triangle = this.add.graphics() .fillStyle(0x3498db, 0.8) .beginPath() .moveTo(0, -40) .lineTo(-30, 40) .lineTo(30, 40) .closePath() .fillPath() .setPosition(centerX - 40, 1620) .setInteractive(new Phaser.Geom.Triangle(-30, 40, 30, 40, 0, -40), Phaser.Geom.Triangle.Contains) .on('pointerdown', function() { this.angle += 30; }); // 创建圆角矩形 this.add.rectangle(centerX + 40, 1620, 80, 60, 0xe74c3c, 0.8) .setInteractive() .on('pointerdown', function() { this.setScale(this.scaleX * 1.1); }); } // 12. 多相机系统 createCameraObjects(centerX) { // 标题 this.add.text(centerX, 1750, '12. 多相机系统示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 添加说明文本 this.add.text(centerX, 1790, '多相机系统可以同时显示不同视角的内容', { fontSize: '14px', fill: '#aaaaaa' }).setOrigin(0.5); // 创建第二个相机(左侧) const camera2 = this.cameras.add(centerX - 110, 1830, 180, 120); camera2.setBackgroundColor(0x2c3e50); // 创建第三个相机(右侧) const camera3 = this.cameras.add(centerX + 10, 1830, 180, 120); camera3.setBackgroundColor(0x34495e); // 在第二个相机中创建对象 const leftText = this.add.text(camera2.x + camera2.width / 2, camera2.y + camera2.height / 2 - 20, '左侧相机', { fontSize: '14px', fill: '#ffffff' }).setOrigin(0.5); const leftCircle = this.add.circle(camera2.x + camera2.width / 2, camera2.y + camera2.height / 2 + 20, 15, 0x3498db, 1); // 在第三个相机中创建对象 const rightText = this.add.text(camera3.x + camera3.width / 2, camera3.y + camera3.height / 2 - 20, '右侧相机', { fontSize: '14px', fill: '#ffffff' }).setOrigin(0.5); const rightSquare = this.add.rectangle(camera3.x + camera3.width / 2, camera3.y + camera3.height / 2 + 20, 30, 30, 0xe74c3c, 1); // 添加交互,点击时控制相机 this.add.text(centerX, 1970, '点击切换相机视角', { fontSize: '14px', fill: '#ffffff', backgroundColor: '#444444', padding: { x: 15, y: 8 } }) .setOrigin(0.5) .setInteractive() .on('pointerdown', () => { // 移动左侧相机中的圆形 this.tweens.add({ targets: leftCircle, x: leftCircle.x + 50, duration: 800, yoyo: true, repeat: 1 }); // 旋转右侧相机中的正方形 this.tweens.add({ targets: rightSquare, angle: 360, duration: 1600, ease: 'Linear' }); // 改变相机背景色 camera2.setBackgroundColor(Phaser.Display.Color.RandomRGB(50, 100).color); camera3.setBackgroundColor(Phaser.Display.Color.RandomRGB(50, 100).color); }); // 添加相机功能说明 this.add.text(centerX, 2010, '相机1: 主视角 | 相机2: 左侧视角 | 相机3: 右侧视角', { fontSize: '12px', fill: '#aaaaaa' }).setOrigin(0.5); } // 13. 灯光系统 createLightObjects(centerX) { // 标题 this.add.text(centerX, 2050, '13. 灯光系统示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 注意:实际灯光系统需要特殊配置 // 本示例使用图形模拟灯光效果 // 创建灯光图形 const light = this.add.graphics() .fillStyle(0xffffff, 0.3) .fillCircle(0, 0, 100) .setPosition(centerX, 2130); // 创建一些对象来展示灯光效果 this.add.rectangle(centerX - 50, 2110, 30, 30, 0x666666, 1); this.add.rectangle(centerX + 50, 2110, 30, 30, 0x666666, 1); this.add.rectangle(centerX, 2150, 30, 30, 0x666666, 1); // 添加交互,点击时移动灯光 this.add.text(centerX, 2200, '点击移动灯光', { fontSize: '14px', fill: '#ffffff' }) .setOrigin(0.5) .setInteractive() .on('pointerdown', () => { const x = centerX + Phaser.Math.Between(-50, 50); const y = 2100 + Phaser.Math.Between(-30, 30); light.setPosition(x, y); }); } // 14. 路径系统 createPathObjects(centerX) { // 标题 this.add.text(centerX, 2250, '14. 路径系统示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 绘制路径 const graphics = this.add.graphics(); graphics.lineStyle(2, 0xffffff, 0.5); graphics.strokeRect(centerX - 100, 2300, 200, 100); // 创建一个对象沿着路径移动 const follower = this.add.circle(centerX - 100, 2300, 10, 0xff0000, 1); // 创建路径动画 this.tweens.add({ targets: { pos: 0 }, pos: 1, duration: 4000, repeat: -1, ease: 'Linear', onUpdate: (tween) => { const progress = tween.targets[0].pos; // 矩形路径:右 -> 下 -> 左 -> 上 if (progress < 0.25) { // 右 follower.x = centerX - 100 + (progress * 4) * 200; follower.y = 2300; } else if (progress < 0.5) { // 下 follower.x = centerX + 100; follower.y = 2300 + ((progress - 0.25) * 4) * 100; } else if (progress < 0.75) { // 左 follower.x = centerX + 100 - ((progress - 0.5) * 4) * 200; follower.y = 2400; } else { // 上 follower.x = centerX - 100; follower.y = 2400 - ((progress - 0.75) * 4) * 100; } } }); } // 15. 网格系统 createGridObjects(centerX) { // 标题 this.add.text(centerX, 2450, '15. 网格系统示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 创建网格 const grid = this.add.grid(centerX, 2520, 200, 100, 20, 20, 0x444444, 0, 0x666666, 0.3); // 在网格上添加一些对象 for (let i = 0; i < 5; i++) { const x = centerX - 90 + i * 40; for (let j = 0; j < 2; j++) { const y = 2490 + j * 40; this.add.circle(x, y, 5, 0x2ecc71, 1); } } } // 16. 时间线 createTimelineObjects(centerX) { // 标题 this.add.text(centerX, 2600, '16. 时间线示例', { fontSize: '20px', fill: '#ffffff', fontWeight: 'bold' }).setOrigin(0.5); // 创建对象 const obj1 = this.add.rectangle(centerX - 40, 2670, 40, 40, 0x3498db, 1); const obj2 = this.add.circle(centerX, 2670, 20, 0xe74c3c, 1); const obj3 = this.add.graphics() .fillStyle(0xf1c40f, 1) .beginPath() .moveTo(0, -20) .lineTo(-20, 20) .lineTo(20, 20) .closePath() .fillPath() .setPosition(centerX + 40, 2670); // 添加交互,点击时播放动画序列 this.add.text(centerX, 2750, '点击播放动画', { fontSize: '14px', fill: '#ffffff' }) .setOrigin(0.5) .setInteractive() .on('pointerdown', () => { // 动画序列 this.tweens.add({ targets: obj1, y: 2620, duration: 500, ease: 'Power2', onComplete: () => { this.tweens.add({ targets: obj2, scale: 1.5, duration: 500, ease: 'Power2', onComplete: () => { this.tweens.add({ targets: obj3, angle: 360, duration: 1000, ease: 'Linear', onComplete: () => { this.tweens.add({ targets: obj1, y: 950, duration: 500, ease: 'Power2' }); this.tweens.add({ targets: obj2, scale: 1, duration: 500, ease: 'Power2' }); this.tweens.add({ targets: obj3, angle: 0, duration: 500, ease: 'Power2' }); } }); } }); } }); }); } }