Files
CINC/scenes/storeScenes/BreatheLife.js
T
2026-02-04 21:48:37 +08:00

186 lines
7.1 KiB
JavaScript

/**
* BreatheLife 场景类
*
* 交互场景,允许用户通过点击屏幕创建角色
* 当创建的角色超过3个时,点击已存在的角色会为其设置纹理
* 当设置纹理的角色超过3个时,自动切换到 MenuScene 场景
*/
import WorldLand from './WorldLand.js'
export default class BreatheLife extends WorldLand {
/**
* 构造函数
* 初始化场景并设置场景键名
* @param {string} sceneKey - 场景键名,默认值为 'BreatheLife'
*/
constructor(sceneKey = 'BreatheLife') {
super(sceneKey)
this.nextScene = 'MenuScene'
this.UIDepth = 100 // UI层级深度,确保在其他元素之上
this.maskDepth = 99 // 黑夜遮罩层级,低于UI层级
this.SpriteDepth = 98 // 角色层级,确保在地图层级之上
this.mapDepth = 97 // 地图层级,确保在UI层级之下
this.tileCount = 234 // 瓦片总数,从tile_0000到tile_0233
this.tileSize = 16 // 瓦片大小
this.mapWidth = 18; // 瓦片图行数
this.mapHeight = 13; // 瓦片图列数
}
preload() {
// 加载草地瓦片图
this.load.image(`grass`, `assets/PNG/Tiles/Tiles/tile_0024.png`)
this.load.image(`smallGrass`, `assets/PNG/Tiles/Tiles/tile_0044.png`)
// 加载角色动画和图片资源
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`)
// 批量加载图片用于动画播放
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() {
// 设置场景背景颜色为灰色
this.cameras.main.setBackgroundColor('#999999')
// 初始化角色计数器,用于跟踪创建的角色数量
this.spriteCount = 0
this.spriteTextureCount = 0
this.spriteAnimCount = 0
this.targetCount = 3 // 目标角色数量
this.createTilemap() // 创建瓦片地图
this.initFrameRateText() // 初始化帧率显示文本
this.initDayNight(this.toGameTime('2000-01-01 12:00:00')) // 初始化时间,白天黑夜状态
// 监听鼠标点击事件,点击后创建一个新的角色
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)
// 如果满足条件则切换到下一场景
if (
this.spriteCount >= this.targetCount
&& this.spriteTextureCount >= this.targetCount
&& this.spriteAnimCount >= this.targetCount
) {
this.scene.start(this.nextScene)
}else if (clickedSprite) { // 如果点击到了精灵
console.log("当前精灵的纹理:", clickedSprite.texture.key) // 查看当前精灵的纹理
// 如果纹理为默认值或纹理缺失
if (clickedSprite.texture.key === 'player' || clickedSprite.texture.key === '__MISSING') {
this.setSpriteTexture(clickedSprite, `player1-0`) // 设置指定的纹理
}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') // 播放移动音效
}
}else if (this.spriteCount < 3) {
// 创建一个新的角色 sprite,缩放为1倍,并设置原点为中心底部
const sprite = this.physics.add.sprite(x, y, 'player').setScale(1).setOrigin(0.5, 1)
sprite.setDepth(this.SpriteDepth) // 设置角色层级
// 设置角色碰撞世界边界
sprite.setCollideWorldBounds(true)
// 增加角色计数器
this.spriteCount++
console.log("已设置纹理的角色数量:", this.spriteTextureCount)
console.log("已创建的角色数量:", 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++
}
/**
* 为角色添加动画
* @param {Phaser.GameObjects.Sprite} sprite - 要添加动画的角色精灵
*/
addSpriteAnimation(sprite) {
// 检查角色是否已添加动画
if (sprite.anims.exists('player-move')) {
return
}
// 创建角色动画
// sprite.anims.create({
// key: 'player1-0',
// frames: sprite.anims.generateFrameNumbers('player1-0', { start: 0, end: 7 }),
// frameRate: 10,
// repeat: -1
// })
// 创建移动动画
this.anims.create({
key: 'player-move',
frames: [
{ key: 'player1-1' },
{ key: 'player1-2' }
],
frameRate: 10,
repeat: -1
});
// 播放角色动画
sprite.anims.play('player-move')
this.spriteAnimCount++
}
}