Files

757 lines
25 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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'
});
}
});
}
});
}
});
});
}
}