mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-29 22:51:29 +08:00
feat(SS) 添加故事场景
This commit is contained in:
1 parent
5e53dc3ef3
commit
201322d2e7
3 files changed
+266
No files matched your search
@@ -5,6 +5,8 @@ import gameConfig from './config/gameConfig.js';
|
||||
import BootScene from './scenes/BootScene.js';
|
||||
import GameScene from './scenes/GameScene.js';
|
||||
|
||||
|
||||
// 测试场景
|
||||
// 导入移动测试场景
|
||||
import KeyboardMovementTestScene from './scenes/testScenes/KeyboardMovementTestScene.js';
|
||||
import TargetMovementTestScene from './scenes/testScenes/TargetMovementTestScene.js';
|
||||
@@ -47,6 +49,12 @@ import CharacterClassTestScene from './scenes/testScenes/CharacterClassTestScene
|
||||
// 导入武器测试场景
|
||||
import WeaponTestScene from './scenes/testScenes/WeaponTestScene.js';
|
||||
|
||||
// 故事场景
|
||||
// 导入开天辟地
|
||||
import PrimordialDevide from './scenes/storeScenes/PrimordialDevide.js';
|
||||
// 导入女娲造人
|
||||
import BreatheLife from './scenes/storeScenes/BreatheLife.js';
|
||||
|
||||
// 创建游戏的最终配置对象
|
||||
const config = {
|
||||
// 使用扩展运算符(...)将gameConfig中的所有配置项复制到当前对象中
|
||||
@@ -54,6 +62,10 @@ const config = {
|
||||
...gameConfig,
|
||||
// 指定游戏使用的场景列表,包括主场景和所有测试场景
|
||||
scene: [
|
||||
PrimordialDevide,
|
||||
BreatheLife,
|
||||
|
||||
// 测试场景
|
||||
MenuScene,
|
||||
TmpScene,
|
||||
WeaponTestScene,
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* BreatheLife 场景类
|
||||
*
|
||||
* 交互场景,允许用户通过点击屏幕创建角色
|
||||
* 当创建的角色超过3个时,点击已存在的角色会为其设置纹理
|
||||
* 当设置纹理的角色超过3个时,自动切换到 MenuScene 场景
|
||||
*/
|
||||
export default class BreatheLife extends Phaser.Scene {
|
||||
/**
|
||||
* 构造函数
|
||||
* 初始化场景并设置场景键名为 'BreatheLife'
|
||||
*/
|
||||
constructor() {super('BreatheLife')}
|
||||
|
||||
preload() {
|
||||
// 加载角色动画和图片资源
|
||||
this.load.image(`player0-0`, `assets/PNG/Players/Tiles/tile_${String(0).padStart(4, '0')}.png`);
|
||||
this.load.image(`player1-0`, `assets/PNG/Players/Tiles/tile_${String(8).padStart(4, '0')}.png`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建场景
|
||||
* 设置背景颜色,添加用户交互监听和自动切换计时器
|
||||
*/
|
||||
create() {
|
||||
// 设置场景背景颜色为灰色
|
||||
this.cameras.main.setBackgroundColor('#999999')
|
||||
|
||||
// 初始化角色计数器,用于跟踪创建的角色数量
|
||||
this.spriteCount = 0
|
||||
this.spriteTextureCount = 0
|
||||
|
||||
// 监听鼠标点击事件,点击后创建一个新的角色
|
||||
this.input.on('pointerdown', () => {
|
||||
// 获取点击位置的坐标
|
||||
const { x, y } = this.input.activePointer
|
||||
this.createSprite(x, y)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个新的角色或获取点击的精灵
|
||||
* @param {number} x - 角色的 x 坐标
|
||||
* @param {number} y - 角色的 y 坐标
|
||||
*/
|
||||
createSprite(x, y) {
|
||||
// 获取点击位置的精灵
|
||||
const clickedSprite = this.getClickedSprite(x, y)
|
||||
console.log("点击到的精灵:", clickedSprite)
|
||||
console.log("已设置纹理的角色数量:", this.spriteTextureCount)
|
||||
console.log("已创建的角色数量:", this.spriteCount)
|
||||
if (this.spriteCount >= 3 && this.spriteTextureCount >= 3) {
|
||||
this.scene.start('MenuScene')
|
||||
return
|
||||
}else if (clickedSprite) { // 如果点击到了精灵
|
||||
// 显示当前精灵的纹理
|
||||
console.log("当前精灵的纹理:", clickedSprite.texture.key)
|
||||
// 如果没有纹理或纹理为默认值
|
||||
if (clickedSprite.texture.key === '__MISSING' || clickedSprite.texture.key === 'player') {
|
||||
// 设置纹理
|
||||
this.setSpriteTexture(clickedSprite, `player1-0`)
|
||||
}
|
||||
return
|
||||
}else if (this.spriteCount >= 3) {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个新的角色 sprite,缩放为1倍
|
||||
const sprite = this.physics.add.sprite(x, y, 'player').setScale(1)
|
||||
|
||||
// 设置角色碰撞世界边界
|
||||
sprite.setCollideWorldBounds(true)
|
||||
|
||||
// 增加角色计数器
|
||||
this.spriteCount++
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取鼠标点击位置的精灵
|
||||
* @param {number} x - 点击位置的 x 坐标
|
||||
* @param {number} y - 点击位置的 y 坐标
|
||||
* @returns {Phaser.GameObjects.Sprite|null} - 点击位置的精灵,如果没有则返回 null
|
||||
*/
|
||||
getClickedSprite(x, y) {
|
||||
// 获取场景中所有的精灵
|
||||
const sprites = this.children.getChildren().filter(child => child instanceof Phaser.GameObjects.Sprite)
|
||||
|
||||
// 检查每个精灵是否被点击
|
||||
for (const sprite of sprites) {
|
||||
// 检查点击位置是否在精灵的边界内
|
||||
if (sprite.getBounds().contains(x, y)) {
|
||||
return sprite
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
setSpriteTexture(sprite, textureKey) {
|
||||
// 检查角色已设置的纹理数量是否超过3个
|
||||
if (this.spriteTextureCount > 3) {
|
||||
// 当设置纹理的角色超过时,切换到 MenuScene 场景
|
||||
this.scene.start('MenuScene')
|
||||
}
|
||||
sprite.setTexture(textureKey).setScale(1)
|
||||
|
||||
this.spriteTextureCount++
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* PrimordialDevide 场景类
|
||||
*
|
||||
* 初始引导场景,显示空白背景并在用户交互或自动延迟后
|
||||
* 执行过渡动画切换到下一个场景
|
||||
*/
|
||||
export default class PrimordialDevide extends Phaser.Scene {
|
||||
/**
|
||||
* 构造函数
|
||||
* 初始化场景并设置场景键名为 'PrimordialDevide'
|
||||
*/
|
||||
constructor() {
|
||||
super('PrimordialDevide')
|
||||
this.nextScene = 'BreatheLife'
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建场景
|
||||
* 设置背景颜色,添加用户交互监听和自动切换计时器
|
||||
*/
|
||||
create() {
|
||||
// 设置场景背景颜色为深灰色
|
||||
this.cameras.main.setBackgroundColor('#333333')
|
||||
|
||||
// 设置动画播放状态为 false,避免多次触发
|
||||
this.animationPlaying = false
|
||||
|
||||
// 监听鼠标点击事件,点击后执行场景过渡动画
|
||||
this.input.on('pointerdown', () => {
|
||||
// 获取点击位置的坐标
|
||||
const { x, y } = this.input.activePointer
|
||||
this.transitionToScene(x, y)
|
||||
})
|
||||
|
||||
// 监听键盘按键事件,按键后执行场景过渡动画
|
||||
this.input.keyboard.on('keydown', () => {
|
||||
this.transitionToScene()
|
||||
})
|
||||
|
||||
// 设置1秒后自动执行场景过渡动画
|
||||
this.time.delayedCall(1000, () => {
|
||||
this.transitionToScene()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行到下一个场景的过渡动画
|
||||
*
|
||||
* 动画流程:
|
||||
* 1. 从屏幕中心向两侧延伸一条白色直线(横向扩展)
|
||||
* 2. 横向扩展完成后,直线向上下扩展铺满整个屏幕(纵向扩展)
|
||||
* 3. 纵向扩展完成后,切换到MenuScene场景
|
||||
*/
|
||||
transitionToScene(startX,startY) {
|
||||
// 如果动画正在播放,直接返回
|
||||
if (this.animationPlaying) {
|
||||
return
|
||||
}
|
||||
// 设置动画播放状态为 true
|
||||
this.animationPlaying = true
|
||||
|
||||
const graphics = this.add.graphics() // 创建图形对象,用于绘制过渡动画
|
||||
|
||||
const centerX = startX || this.cameras.main.centerX // 获取屏幕中心点的X坐标
|
||||
const centerY = startY || this.cameras.main.centerY // 获取屏幕中心点的Y坐标
|
||||
|
||||
const lineHeight = 2 // 初始线条高度(2像素)
|
||||
|
||||
const maxWidth = this.cameras.main.width // 屏幕最大宽度,用于横向扩展的目标值
|
||||
|
||||
graphics.fillStyle(0xffffff, 1) // 设置初始填充颜色为白色,透明度为1
|
||||
|
||||
// 创建线条对象,用于控制横向扩展动画的属性
|
||||
const line = {
|
||||
width: 0, // 初始宽度为0(仅中心点)
|
||||
x: centerX // 初始X坐标为屏幕中心
|
||||
}
|
||||
|
||||
// 创建横向扩展动画
|
||||
this.tweens.add({
|
||||
targets: line, // 动画目标对象
|
||||
width: maxWidth, // 目标宽度为屏幕宽度
|
||||
x: 0, // 目标X坐标为屏幕左侧
|
||||
duration: 300, // 动画持续时间(300毫秒)
|
||||
ease: 'Power2.easeOut', // 动画缓动函数
|
||||
onUpdate: function() { // 动画更新回调函数
|
||||
graphics.clear() // 清除之前的绘制
|
||||
graphics.fillStyle(0x999999, 1) // 设置填充颜色
|
||||
// 绘制当前状态的线条
|
||||
graphics.fillRect(line.x, centerY - lineHeight / 2, line.width, lineHeight)
|
||||
},
|
||||
onComplete: function() { // 动画完成回调函数
|
||||
// 横向动画完成后,调用纵向扩展动画方法
|
||||
this.expandVerticalAnimation(graphics, centerY, lineHeight, maxWidth)
|
||||
},
|
||||
callbackScope: this // 回调函数的作用域(指向当前场景实例)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行纵向扩展动画
|
||||
*
|
||||
* @param {Phaser.GameObjects.Graphics} graphics - 图形对象,用于绘制动画
|
||||
* @param {number} centerY - 屏幕中心点的Y坐标
|
||||
* @param {number} lineHeight - 初始线条高度
|
||||
* @param {number} maxWidth - 屏幕宽度,用于绘制横向铺满的矩形
|
||||
*/
|
||||
expandVerticalAnimation(graphics, centerY, lineHeight, maxWidth) {
|
||||
// 创建纵向线条对象,用于控制纵向扩展动画的属性
|
||||
const verticalLine = {
|
||||
height: lineHeight, // 初始高度为线条高度
|
||||
y: centerY - lineHeight / 2 // 初始Y坐标为屏幕中心减去线条高度的一半
|
||||
}
|
||||
|
||||
// 屏幕最大高度,用于纵向扩展的目标值
|
||||
const maxHeight = this.cameras.main.height
|
||||
|
||||
// 创建纵向扩展动画
|
||||
this.tweens.add({
|
||||
targets: verticalLine, // 动画目标对象
|
||||
height: maxHeight, // 目标高度为屏幕高度
|
||||
y: 0, // 目标Y坐标为屏幕顶部
|
||||
duration: 300, // 动画持续时间
|
||||
ease: 'Power2.easeOut', // 动画缓动函数
|
||||
onUpdate: function() { // 动画更新回调函数
|
||||
graphics.clear() // 清除之前的绘制
|
||||
graphics.fillStyle(0x999999, 1) // 设置填充颜色
|
||||
// 绘制当前状态的矩形(已横向铺满,正在纵向扩展)
|
||||
graphics.fillRect(0, verticalLine.y, maxWidth, verticalLine.height)
|
||||
},
|
||||
onComplete: function() { // 动画完成回调函数
|
||||
// 纵向动画完成后,切换到指定场景
|
||||
// 加上内置过渡动画
|
||||
this.cameras.main.fadeOut(300, 0, 0, 0);
|
||||
this.cameras.main.once('camerafadeoutcomplete', () => {
|
||||
// 切换到游戏场景
|
||||
this.scene.start(this.nextScene);
|
||||
});
|
||||
},
|
||||
callbackScope: this // 回调函数的作用域(指向当前场景实例)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user