/** * BreatheLife 场景类 * * 交互场景,允许用户通过点击屏幕创建角色 * 当创建的角色超过3个时,点击已存在的角色会为其设置纹理 * 当设置纹理的角色超过3个时,自动切换到 MenuScene 场景 */ import WorldLand from './WorldLand.js' export default class BreatheLife extends WorldLand { constructor(sceneKey = 'BreatheLife') { // 场景相关 super(sceneKey) this.nextScene = 'MenuScene' // 层级相关 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() } initSceneTransition() { // 初始化角色计数器,用于跟踪创建的角色数量 this.spriteCount = 0 this.spriteTextureCount = 0 this.spriteAnimCount = 0 this.targetCount = 3 // 目标角色数量 } initInput() { // 移除父类的输入事件监听器,避免重复监听 super.removeListener() // 监听鼠标点击事件,点击后创建一个新的角色 this.input.on('pointerdown', () => { // 获取点击位置的坐标 const { x, y } = this.input.activePointer this.handleClick(x, y) }) } removeListener() { // 移除鼠标点击事件监听器 this.input.off('pointerdown'); } /** * 处理点击事件 * @param {number} x - 点击的 x 坐标 * @param {number} y - 点击的 y 坐标 */ handleClick(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) { // 如果点击到了精灵 this.handleSpriteClick(clickedSprite) }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 } 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') // 播放移动音效 } } /** * 为角色添加动画 * @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++ } }