mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-30 09:51:29 +08:00
refactor(SRC) 重构核心场景路径位置
This commit is contained in:
1 parent
942ba567f3
commit
cbbed1519e
18 files changed
+845
-473
No files matched your search
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* BreatheLife 场景类
|
||||
*
|
||||
* 交互场景,允许用户通过点击屏幕创建角色
|
||||
* 第二次点击设置纹理
|
||||
* 第三次点击赋予动画
|
||||
* 第四次点击移动角色
|
||||
* 当移动角色超过3个后再次点击,切换到下一个场景
|
||||
*/
|
||||
import WorldLand from './WorldLand.js'
|
||||
export default class BreatheLife extends WorldLand {
|
||||
constructor(sceneKey = 'BreatheLife') {
|
||||
// 场景相关
|
||||
super(sceneKey)
|
||||
this.nextScene = 'Control'
|
||||
|
||||
// 层级相关
|
||||
this.SpriteDepth = 10 // 角色层级
|
||||
}
|
||||
|
||||
preload() {
|
||||
super.preload()
|
||||
|
||||
// 加载角色动画和图片资源
|
||||
this.load.image(`player1-0`, `assets/PNG/Players/Tiles/tile_${String(8).padStart(4, '0')}.png`)
|
||||
|
||||
// 批量加载图片用于动画播放
|
||||
for (let i = 1; i < 8; i++) {
|
||||
this.load.image(`player0-${i}`, `assets/PNG/Players/Tiles/tile_${String(i).padStart(4, '0')}.png`);
|
||||
}
|
||||
for (let i = 9; i < 16; i++) {
|
||||
this.load.image(`player1-${i-8}`, `assets/PNG/Players/Tiles/tile_${String(i).padStart(4, '0')}.png`);
|
||||
}
|
||||
|
||||
// 加载音效资源
|
||||
this.load.audio('coin-a', 'assets/Sounds/move-a.ogg');
|
||||
this.load.audio('coin-b', 'assets/Sounds/coin-b.ogg');
|
||||
}
|
||||
|
||||
|
||||
create() {
|
||||
super.create()
|
||||
|
||||
// 覆盖场景切换条件
|
||||
this.initSceneTransition()
|
||||
|
||||
// 覆盖输入
|
||||
this.initInput()
|
||||
|
||||
// 添加随机小草
|
||||
this.addRandomSmallGrass()
|
||||
}
|
||||
initSceneTransition() {
|
||||
// 初始化角色计数器,用于跟踪创建的角色数量
|
||||
this.targetCount = 3 // 目标角色数量
|
||||
this.NPCObjects = [] // 维护角色集合
|
||||
this.smallGrassObjects = [] // 维护小草集合
|
||||
}
|
||||
initInput() {
|
||||
// 移除父类的输入事件监听器,避免重复监听
|
||||
super.removeListener()
|
||||
|
||||
// 监听鼠标点击事件,点击后创建一个新的角色
|
||||
this.input.on('pointerdown', () => {
|
||||
// 获取点击位置的坐标
|
||||
const { x, y } = this.input.activePointer
|
||||
this.handleClick(x, y)
|
||||
})
|
||||
|
||||
// 监听自定义收集完成事件,当所有小草都被收集时触发
|
||||
this.events.on('collectAllSmallGrass', () => {
|
||||
this.scene.start(this.nextScene)
|
||||
})
|
||||
}
|
||||
removeListener() {
|
||||
// 移除鼠标点击事件监听器
|
||||
this.input.off('pointerdown');
|
||||
// 移除自定义收集完成事件监听器
|
||||
this.events.off('collectAllSmallGrass')
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理点击事件
|
||||
* @param {number} x - 点击的 x 坐标
|
||||
* @param {number} y - 点击的 y 坐标
|
||||
*/
|
||||
handleClick(x, y) {
|
||||
// 获取点击位置的精灵
|
||||
const clickedSprite = this.getClickedSprite(x, y)
|
||||
console.log("点击到的精灵:", clickedSprite)
|
||||
// 如果满足条件则切换到下一场景
|
||||
if (clickedSprite && this.NPCObjects.includes(clickedSprite)) { // 如果点击到了角色
|
||||
this.handleSpriteClick(clickedSprite)
|
||||
}else if (this.NPCObjects.length >= this.targetCount) {
|
||||
// 如果角色列表中角色数量超过目标数量,且动态效果的数量也超过目标数量
|
||||
let moveCount = 0
|
||||
for (const sprite of this.NPCObjects) {
|
||||
// 如果角色当前的纹理在player-move的动画帧中,计数加一
|
||||
const moveAnimationFrames = ['player1-1', 'player1-2']
|
||||
if (moveAnimationFrames.includes(sprite.texture.key)) {
|
||||
moveCount++
|
||||
}
|
||||
}
|
||||
if (moveCount >= this.targetCount) {
|
||||
this.scene.start(this.nextScene)
|
||||
}
|
||||
}else if (this.NPCObjects.length < this.targetCount) {
|
||||
// 如果角色数量不足目标数量
|
||||
// 创建一个新的角色 sprite,缩放为1倍,并设置原点为中心底部
|
||||
const sprite = this.physics.add.sprite(x, y, 'player').setScale(1).setOrigin(0.5, 1)
|
||||
sprite.setDepth(this.SpriteDepth) // 设置角色层级
|
||||
|
||||
this.NPCObjects.push(sprite) // 加入角色集合
|
||||
|
||||
// // 设置角色碰撞世界边界
|
||||
// sprite.setCollideWorldBounds(true)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取鼠标点击位置的精灵
|
||||
* @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
|
||||
}
|
||||
|
||||
handleSpriteClick(clickedSprite) {
|
||||
console.log("当前精灵的纹理:", clickedSprite.texture.key) // 查看当前精灵的纹理
|
||||
// 如果纹理为默认值或纹理缺失
|
||||
if (clickedSprite.texture.key === 'player' || clickedSprite.texture.key === '__MISSING') {
|
||||
clickedSprite.setTexture(`player1-0`).setScale(1) // 设置指定的纹理
|
||||
this.spriteTextureCount++
|
||||
}else if (clickedSprite.texture.key === 'player1-0'){ // 如果点击的角色纹理已经是player1-0,则添加动画
|
||||
this.addSpriteAnimation(clickedSprite) // 添加角色动画
|
||||
}else if (['player1-1', 'player1-2'].includes(clickedSprite.texture.key)){ // 如果点击的角色纹理已经是player0-0,则添加音效
|
||||
this.sound.play('coin-b') // 播放移动音效
|
||||
// 添加搜索逻辑,自动检测最近的小草
|
||||
this.searchAndAddSmallGrass(clickedSprite)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为角色添加动画
|
||||
* @param {Phaser.GameObjects.Sprite} sprite - 要添加动画的角色精灵
|
||||
*/
|
||||
addSpriteAnimation(sprite) {
|
||||
// 检查角色是否已添加动画
|
||||
if (sprite.anims.exists('player-move')) {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建移动动画
|
||||
this.anims.create({
|
||||
key: 'player-move',
|
||||
frames: [
|
||||
{ key: 'player1-1' },
|
||||
{ key: 'player1-2' }
|
||||
],
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
});
|
||||
// 播放角色动画
|
||||
sprite.anims.play('player-move')
|
||||
this.spriteAnimCount++
|
||||
}
|
||||
|
||||
// 重写创建小草方法,移除条件判断和计数器
|
||||
createSmallGrass(x, y) {
|
||||
// 创建
|
||||
const smallGrass = this.add.image(x, y, 'smallGrass');
|
||||
smallGrass.setDepth(this.mapDepth); // 设置深度,确保在UI层级之下
|
||||
smallGrass.setScrollFactor(0); // 固定,不随相机移动
|
||||
return smallGrass
|
||||
}
|
||||
|
||||
// 新增方法:随机添加50个小草
|
||||
addRandomSmallGrass() {
|
||||
for (let i = 0; i < 50; i++) {
|
||||
// 屏幕范围内随机生成小草位置
|
||||
const x = Phaser.Math.Between(0, this.cameras.main.width)
|
||||
const y = Phaser.Math.Between(0, this.cameras.main.height)
|
||||
const smallGrass = this.createSmallGrass(x, y)
|
||||
// 保存小草对象到数组
|
||||
this.smallGrassObjects.push(smallGrass)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 搜索并添加小草
|
||||
* @param {Phaser.GameObjects.Sprite} clickedSprite - 点击的角色精灵
|
||||
*/
|
||||
searchAndAddSmallGrass(clickedSprite) {
|
||||
// 搜索所有小草
|
||||
// const smallGrass = this.children.getChildren().filter(child =>
|
||||
// child instanceof Phaser.GameObjects.Image && child.texture.key === 'smallGrass'
|
||||
// )
|
||||
const smallGrass = this.smallGrassObjects
|
||||
// 过滤未标记的小草
|
||||
const unmarkedGrass = smallGrass.filter(grass => grass.alpha === 1)
|
||||
|
||||
// 如果没有小草,直接返回
|
||||
if (smallGrass.length === 0) {
|
||||
// 所有小草都已收集,触发事件
|
||||
this.events.emit('collectAllSmallGrass')
|
||||
return
|
||||
}
|
||||
// 查找最近的小草
|
||||
let nearestGrass = null // 最近的小草
|
||||
let minDistance = Infinity // 最近距离,初始为无穷大
|
||||
// 遍历所有小草,找到最近的一个
|
||||
for (const grass of unmarkedGrass) {
|
||||
// 计算当前小草与角色的距离
|
||||
const distance = Phaser.Math.Distance.Between(
|
||||
clickedSprite.x, clickedSprite.y,
|
||||
grass.x, grass.y
|
||||
)
|
||||
// 如果当前小草距离更近,更新最近的小草
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance
|
||||
nearestGrass = grass
|
||||
}
|
||||
}
|
||||
// 如果找到最近的小草,移动角色到小草位置
|
||||
if (nearestGrass) {
|
||||
// 标记小草为已收集
|
||||
nearestGrass.setAlpha(0.5)
|
||||
// 角色移动到小草位置
|
||||
this.tweens.add({
|
||||
targets: clickedSprite, // 角色精灵
|
||||
x: nearestGrass.x, // 目标小草位置x
|
||||
y: nearestGrass.y, // 目标小草位置y
|
||||
duration: minDistance * 10, // 移动时间根据距离计算
|
||||
ease: 'Linear', // 匀速移动
|
||||
onComplete: () => {
|
||||
// 从数组中移除已收集的小草
|
||||
this.smallGrassObjects = this.smallGrassObjects.filter(
|
||||
obj => obj !== nearestGrass
|
||||
)
|
||||
nearestGrass.destroy() // 移动完成后销毁小草
|
||||
this.sound.play('coin-a') // 播放收集小草音效
|
||||
// 等待随机时间后,继续搜索下一个小草
|
||||
const delay = Phaser.Math.Between(500, 1000)
|
||||
this.time.delayedCall(delay, () => {
|
||||
this.searchAndAddSmallGrass(clickedSprite) // 递归调用,继续搜索下一个小草
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user