diff --git a/scenes/storeScenes/BreatheLife.js b/scenes/storeScenes/BreatheLife.js index b94a2a3..8a6d71a 100644 --- a/scenes/storeScenes/BreatheLife.js +++ b/scenes/storeScenes/BreatheLife.js @@ -7,34 +7,19 @@ */ 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; // 瓦片图列数 + // 层级相关 + this.SpriteDepth = 10 // 角色层级 } preload() { - // 加载草地瓦片图 - this.load.image(`grass`, `assets/PNG/Tiles/Tiles/tile_0024.png`) - this.load.image(`smallGrass`, `assets/PNG/Tiles/Tiles/tile_0044.png`) + super.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`) // 批量加载图片用于动画播放 @@ -50,58 +35,54 @@ export default class BreatheLife extends WorldLand { this.load.audio('coin-b', 'assets/Sounds/coin-b.ogg'); } - /** - * 创建场景 - * 设置背景颜色,添加用户交互监听和自动切换计时器 - */ + create() { - // 设置场景背景颜色为灰色 - this.cameras.main.setBackgroundColor('#999999') + super.create() + // 覆盖场景切换条件 + this.initSceneTransition() + + // 覆盖输入 + this.initInput() + + } + initSceneTransition() { // 初始化角色计数器,用于跟踪创建的角色数量 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')) // 初始化时间,白天黑夜状态 + } + initInput() { + // 移除父类的输入事件监听器,避免重复监听 + super.removeListener() // 监听鼠标点击事件,点击后创建一个新的角色 this.input.on('pointerdown', () => { // 获取点击位置的坐标 const { x, y } = this.input.activePointer - this.createSprite(x, y) + this.handleClick(x, y) }) } + removeListener() { + // 移除鼠标点击事件监听器 + this.input.off('pointerdown'); + } /** - * 创建一个新的角色或获取点击的精灵 - * @param {number} x - 角色的 x 坐标 - * @param {number} y - 角色的 y 坐标 + * 处理点击事件 + * @param {number} x - 点击的 x 坐标 + * @param {number} y - 点击的 y 坐标 */ - createSprite(x, 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 - ) { + 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') // 播放移动音效 - } + 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) @@ -138,16 +119,17 @@ export default class BreatheLife extends WorldLand { return null } - setSpriteTexture(sprite, textureKey) { - // 检查角色已设置的纹理数量是否超过3个 - if (this.spriteTextureCount > 3) { - // 当设置纹理的角色超过时,切换到 MenuScene 场景 - this.scene.start('MenuScene') + 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') // 播放移动音效 } - sprite.setTexture(textureKey).setScale(1) - - this.spriteTextureCount++ - } /** diff --git a/scenes/storeScenes/WorldLand.js b/scenes/storeScenes/WorldLand.js index 03cdaa3..4d61193 100644 --- a/scenes/storeScenes/WorldLand.js +++ b/scenes/storeScenes/WorldLand.js @@ -7,43 +7,76 @@ import WorldTime from './WorldTime.js' export default class WorldLand extends WorldTime { - /** - * 构造函数 - * 初始化场景并设置场景键名 - * @param {string} sceneKey - 场景键名 - */ constructor(sceneKey = 'WorldLand') { + // 场景相关 super(sceneKey) this.nextScene = 'BreatheLife' - this.UIDepth = 100 // UI层级深度,确保在其他元素之上 - this.maskDepth = 99 // 黑夜遮罩层级,低于UI层级 - this.mapDepth = 98 // 地图层级,确保在UI层级之下 + // 层级相关 + this.mapDepth = 0 // 地图层级 + // 地图相关 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`) } - create() { - // 设置场景背景颜色为深灰色 - this.cameras.main.setBackgroundColor('#999999') - // 初始化计数器,用于跟踪创建的小草数量 - this.smallGrassCount = 0 - this.initInput() // 初始化输入事件 - this.initDayNight(this.toGameTime('2000-01-01 17:57:00')) // 初始化时间,白天黑夜状态 - + create() { + super.create() + + // 初始化场景切换条件 + this.initSceneTransition() + + // 覆盖输入 + this.initInput() + this.createTilemap() // 创建瓦片地图 this.initFrameRateText() // 初始化帧率显示文本 } - + initSceneTransition() { + // 初始化计数器,用于跟踪创建的小草数量 + this.smallGrassCount = 0 + } + initInput() { + // 移除父类的输入事件监听器,避免重复监听 + super.removeListener() + + // 监听鼠标点击事件,点击后创建一个新的小草 + this.input.on('pointerdown', () => { + // 获取点击位置的坐标 + const { x, y } = this.input.activePointer + this.createTile(x, y) + }) + + // 监听键盘按键事件,按键后执行场景过渡动画 + this.input.keyboard.on('keydown', () => { + this.scene.start(this.nextScene); + }) + } + removeListener() { + // 移除鼠标点击事件监听器 + this.input.off('pointerdown'); + // 移除键盘按键事件监听器 + this.input.keyboard.off('keydown'); + } + + + update() { + this.showFrameRate() // 显示当前帧率 + this.updateGameTime() // 更新游戏时间 + this.displayTime() // 显示当前游戏时间 + this.updateDayNight() // 更新昼夜状态 + } + + createTilemap() { // 获取当前屏幕大小 const screenWidth = this.cameras.main.width; @@ -69,29 +102,8 @@ export default class WorldLand extends WorldTime { console.log(`草地铺满屏幕完成,使用了 ${tilesX}x${tilesY} 个瓦片`) } - update() { - this.showFrameRate() // 显示当前帧率 - this.updateGameTime() // 更新游戏时间 - this.displayTime() // 显示当前游戏时间 - this.updateDayNight() // 更新昼夜状态 - } - - initInput() { - // 监听鼠标点击事件,点击后创建一个新的小草 - this.input.on('pointerdown', () => { - // 获取点击位置的坐标 - const { x, y } = this.input.activePointer - this.createTile(x, y) - }) - - // 监听键盘按键事件,按键后执行场景过渡动画 - this.input.keyboard.on('keydown', () => { - this.scene.start(this.nextScene); - }) - } - createTile(x, y) { - if (this.smallGrassCount >= 10) { + if (this.smallGrassCount >= 5) { this.scene.start(this.nextScene); } // 创建瓦片图实例 diff --git a/scenes/storeScenes/WorldTime.js b/scenes/storeScenes/WorldTime.js index 9b8978f..4627654 100644 --- a/scenes/storeScenes/WorldTime.js +++ b/scenes/storeScenes/WorldTime.js @@ -11,33 +11,39 @@ export default class WorldTime extends Phaser.Scene { * @param {string} sceneKey - 场景键名 */ constructor(sceneKey = 'WorldTime') { + // 场景相关 super(sceneKey) this.nextScene = 'WorldLand' + // 游戏时间相关 this.gameTime = 0 // 游戏中的时间戳(单位:秒) - // 固定为60秒/分钟,60分钟/小时,24小时/天,30天/月,12月/年 + // 固定60秒/分钟,60分钟/小时,24小时/天,30天/月,12月/年 this.minuteSec = 60 this.hourSec = 60 * this.minuteSec this.daySec = 24 * this.hourSec this.monthSec = 30 * this.daySec this.yearSec = 12 * this.monthSec - + this.dayStartHour = 6 // 每天开始的小时(24小时制) + this.dayEndHour = 18 // 每天结束的小时(24小时制) + this.gameStartTime = this.toGameTime('1999-12-30 ' + (this.dayStartHour-1).toString().padStart(2, '0') + ':55:00') // 游戏开始时间 this.lastRealTime = 0 // 上一次更新的现实时间戳(毫秒) this.gameTimeUpdateInterval = 1000/60 // 游戏中的每秒时间更新间隔(毫秒) - this.isDay = true // 昼夜状态 + // 层级相关 this.UIDepth = 100 // UI层级深度,确保在其他元素之上 this.maskDepth = 99 // 黑夜遮罩层级,低于UI层级 } create() { - // 设置场景背景颜色为深灰色 + // 设置场景背景颜色 this.cameras.main.setBackgroundColor('#999999') - this.initInput() // 初始化输入事件 + // 初始化输入 + this.initInput() - this.initDayNight(this.toGameTime('1999-12-30 23:57:00')) // 初始化时间,白天黑夜状态 + // 初始化时间 + this.initDayNight(this.gameStartTime) } /** * 初始化输入事件 @@ -54,6 +60,18 @@ export default class WorldTime extends Phaser.Scene { this.scene.start(this.nextScene); }) } + /** + * 移除输入事件监听器 + * 场景切换时调用,避免内存泄漏 + */ + removeListener() { + // 移除鼠标点击事件监听器 + this.input.off('pointerdown'); + // 移除键盘按键事件监听器 + this.input.keyboard.off('keydown'); + } + + /** * 更新游戏时间 * 每帧调用,刷新游戏时间