diff --git a/scenes/MenuScene.js b/scenes/MenuScene.js index ffa37cb..3b545bd 100644 --- a/scenes/MenuScene.js +++ b/scenes/MenuScene.js @@ -25,6 +25,9 @@ export default class MenuScene extends Phaser.Scene { // 初始化setTimeout ID数组,用于管理所有与涟漪相关的延迟调用 this.rippleTimeouts = []; + // 创建文本container + this.textContainer = this.add.container(0, 0); + // 添加落雨落效果 this.createRainEffect(); @@ -36,34 +39,43 @@ export default class MenuScene extends Phaser.Scene { cam.centerX, // 文本在x轴上的位置,相机中心 cam.centerY - this.unit * 8, // 文本在y轴上的位置,相机中心上方 LanguageManager.t('title'), - { fontSize: this.unit * 2.4, color: '#ffffff' } + { fontSize: this.unit * 2.4, color: '#ffffff', fontFamily: 'monospace'} ).setOrigin(0.5, 0.5); + // 为标题文本添加倒影 + this.createTextReflection(this.titleText); + // 添加菜单文本 - 使用多语言 this.startText = this.add.text( cam.centerX, // 文本在x轴上的位置,相机中心 cam.centerY, // 文本在y轴上的位置,相机中心 LanguageManager.t('start'), - { fontSize: this.unit * 3.2, color: '#ffffff' } + { fontSize: this.unit * 3.2, color: '#ffffff', fontFamily: 'monospace'} ).setOrigin(0.5, 0.5); - + + // 为开始文本添加倒影 + this.createTextReflection(this.startText); + // 添加退出按钮文本 - 使用多语言 this.exitText = this.add.text( cam.centerX, // 文本在x轴上的位置,相机中心 cam.centerY + this.unit * 5, // 文本在y轴上的位置,开始按钮下方 LanguageManager.t('exit'), - { fontSize: this.unit * 2.4, color: '#ffffff' } + { fontSize: this.unit * 2.4, color: '#ffffff', fontFamily: 'monospace'} ).setOrigin(0.5, 0.5); - + + // 为退出文本添加倒影 + this.createTextReflection(this.exitText); + // 为开始和退出按钮添加点击功能 this.addButtonClickHandlers(); - + // 添加语言切换按钮(仅用于测试) this.createLanguageToggle(); - + // 添加雨天效果控制按钮 this.createRainControlButton(); - + // 添加页面可见性变化监听,处理页面切出和切回的情况 this.setupVisibilityChangeHandler(); } @@ -75,33 +87,21 @@ export default class MenuScene extends Phaser.Scene { const cam = this.cameras.main; const languages = LanguageManager.getAvailableLanguages(); let currentLangIndex = languages.indexOf(LanguageManager.currentLanguage); - + // 按钮基础位置(在退出按钮下方) const baseY = cam.centerY + this.unit * 11; - + // 创建主按钮文本 const toggleText = this.add.text( cam.centerX, baseY, `${LanguageManager.currentLanguage}`, - { fontSize: this.unit * 1.6, color: '#ffffff' } + { fontSize: this.unit * 1.6, color: '#ffffff', fontFamily: 'monospace'} ).setOrigin(0.5, 0.5); - - // 创建倒影文本 - const reflectionText = this.add.text( - cam.centerX, - baseY + this.unit * 2, // 倒影位置在主文本下方 - `${LanguageManager.currentLanguage}`, - { fontSize: this.unit * 1.6, color: '#ffffff' } - ).setOrigin(0.5, 0.5); - - // 设置倒影效果 - reflectionText.setScale(1, -1); // 垂直翻转 - reflectionText.setAlpha(0.3); // 半透明效果 - - // 添加动态波纹效果 - this.createRippleEffect(reflectionText); - + + // 使用createTextReflection方法创建倒影 + const reflectionText = this.createTextReflection(toggleText); + // 创建透明的点击区域(与文本大小匹配) const clickArea = this.add.rectangle( cam.centerX, @@ -111,30 +111,30 @@ export default class MenuScene extends Phaser.Scene { 0x000000, 0 // 完全透明 ).setOrigin(0.5, 0.5); - + // 设置点击区域可交互 clickArea.setInteractive({ useHandCursor: true }); - + // 添加点击事件 clickArea.on('pointerdown', () => { currentLangIndex = (currentLangIndex + 1) % languages.length; const newLang = languages[currentLangIndex]; LanguageManager.setLanguage(newLang); - + // 更新文本 const newText = `${newLang}`; toggleText.setText(newText); reflectionText.setText(newText); - + // 重新计算点击区域大小 clickArea.width = toggleText.width + 20; clickArea.height = toggleText.height + 40; - + // 直接更新菜单文本以显示新语言 this.titleText.setText(LanguageManager.t('title')); this.startText.setText(LanguageManager.t('start')); this.exitText.setText(LanguageManager.t('exit')); - + // 更新雨天控制按钮文本 const rainText = LanguageManager.t('rain'); const stateText = this.isRainEnabled ? LanguageManager.t('on') : LanguageManager.t('off'); @@ -147,18 +147,21 @@ export default class MenuScene extends Phaser.Scene { */ createRainControlButton() { const cam = this.cameras.main; - + // 按钮基础位置(在语言切换按钮下方) const baseY = cam.centerY + this.unit * 17; - + // 创建主按钮文本 this.rainToggleText = this.add.text( cam.centerX, baseY, LanguageManager.t('rain')+" "+LanguageManager.t('on'), - { fontSize: this.unit * 1.6, color: '#ffffff' } + { fontSize: this.unit * 1.6, color: '#ffffff', fontFamily: 'monospace'} ).setOrigin(0.5, 0.5); - + + // 使用createTextReflection方法创建倒影 + this.createTextReflection(this.rainToggleText); + // 创建透明的点击区域(与文本大小匹配) this.rainClickArea = this.add.rectangle( cam.centerX, @@ -168,10 +171,10 @@ export default class MenuScene extends Phaser.Scene { 0x000000, 0 // 完全透明 ).setOrigin(0.5, 0.5); - + // 设置点击区域可交互 this.rainClickArea.setInteractive({ useHandCursor: true }); - + // 添加点击事件 this.rainClickArea.on('pointerdown', () => { this.toggleRainEffect(); @@ -289,15 +292,8 @@ export default class MenuScene extends Phaser.Scene { * 更新雨天效果的可见性 */ updateRainEffectVisibility() { - // 控制雨滴的显示/隐藏 - this.rainGroup.children.each(raindrop => { - raindrop.visible = this.isRainEnabled; - }); - - // 控制涟漪的显示/隐藏 - this.rippleGroup.children.each(ripple => { - ripple.visible = this.isRainEnabled; - }); + // 控制雨滴container的显示/隐藏 + this.rainContainer.visible = this.isRainEnabled; } /** @@ -481,7 +477,7 @@ export default class MenuScene extends Phaser.Scene { // 保存原始位置 const originalX = text.x; const originalY = text.y; - + // 创建波纹动画 this.tweens.add({ targets: text, @@ -491,7 +487,7 @@ export default class MenuScene extends Phaser.Scene { yoyo: true, repeat: -1 // 无限重复 }); - + // 添加轻微的缩放动画 this.tweens.add({ targets: text, @@ -501,7 +497,7 @@ export default class MenuScene extends Phaser.Scene { yoyo: true, repeat: -1 // 无限重复 }); - + // 添加透明度变化 this.tweens.add({ targets: text, @@ -512,22 +508,52 @@ export default class MenuScene extends Phaser.Scene { repeat: -1 // 无限重复 }); } + + /** + * 为文本创建倒影效果 + * @param {Phaser.GameObjects.Text} text - 要创建倒影的文本 + */ + createTextReflection(text) { + // 创建倒影文本 + const reflectionText = this.add.text( + text.x, + text.y + text.height + this.unit * 0.5, // 倒影位置在主文本下方 + text.text, + { fontSize: text.style.fontSize, color: '#ffffff', fontFamily: text.style.fontFamily} + ).setOrigin(0.5, 0.5); + + // 设置倒影效果 + reflectionText.setScale(1, -1); // 垂直翻转 + reflectionText.setAlpha(0.3); // 半透明效果 + + // 将主文本和倒影文本添加到container中 + this.textContainer.add(text); + this.textContainer.add(reflectionText); + + // 添加动态波纹效果 + this.createRippleEffect(reflectionText); + + return reflectionText; + } /** * 创建雨落下效果 */ createRainEffect() { + // 创建雨滴container + this.rainContainer = this.add.container(0, 0); + // 创建雨滴精灵组 this.rainGroup = this.add.group(); - + // 创建涟漪组,用于管理所有涟漪效果 this.rippleGroup = this.add.group(); - + // 雨的参数 const rainCount = 50; // 雨滴数量 const screenWidth = this.sys.game.config.width; const screenHeight = this.sys.game.config.height; - + // 创建雨滴 for (let i = 0; i < rainCount; i++) { // 创建雨滴精灵(使用简单的白色矩形) @@ -539,14 +565,17 @@ export default class MenuScene extends Phaser.Scene { 0xffffff, // 白色 0.3 // 半透明 ); - + + // 将雨滴添加到container中 + this.rainContainer.add(raindrop); + // 添加到组 this.rainGroup.add(raindrop); - + // 设置雨滴动画 - 斜向落下(固定方向) // 水平方向的位移量(相对单位),固定向左下方倾斜 const horizontalOffset = -this.unit * Phaser.Math.Between(15, 17); // 固定向左方向,8-12单位 - + // 设置雨滴动画 this.tweens.add({ targets: raindrop, @@ -563,14 +592,14 @@ export default class MenuScene extends Phaser.Scene { const initialX = Phaser.Math.Between(-this.unit * 10, screenWidth + this.unit * 10); targets[0].x = initialX; targets[0].y = -this.unit * 2; - + // 更新动画的x目标值 tween.data[0].value = initialX + horizontalOffset; } } }); } - + // 添加雨滴涟漪效果 this.createRainRipples(screenWidth, screenHeight); } @@ -610,11 +639,11 @@ export default class MenuScene extends Phaser.Scene { // 随机位置 const x = Phaser.Math.Between(0, screenWidth); const y = Phaser.Math.Between(0, screenHeight); // 整个屏幕高度 - + // 每个雨滴产生多个同心涟漪 const rippleLayers = 3; const baseDelay = 100; - + for (let i = 0; i < rippleLayers; i++) { // 延迟创建后续的涟漪层 const timeoutId = setTimeout(() => { @@ -628,18 +657,21 @@ export default class MenuScene extends Phaser.Scene { 0xffffff, // 白色 0 // 透明填充 ).setStrokeStyle(this.unit * 0.08, 0xffffff, 0.3); // 更细的边框,更高的透明度 - + + // 将涟漪添加到雨滴container中 + this.rainContainer.add(ripple); + // 将涟漪添加到涟漪组中 this.rippleGroup.add(ripple); - + // 随机化每个涟漪的参数,增加自然感 const maxRadius = this.unit * Phaser.Math.Between(2, 3); const duration = Phaser.Math.Between(800, 1500); const startAlpha = Phaser.Math.Between(0.3, 0.5); - + // 设置初始透明度 ripple.setAlpha(startAlpha); - + // 创建扩散动画 this.tweens.add({ targets: ripple, @@ -657,17 +689,17 @@ export default class MenuScene extends Phaser.Scene { }); } }, i * baseDelay); - + // 将timeout ID保存到数组中 this.rippleTimeouts.push(timeoutId); } - + // 只有在雨天效果开启时,才递归创建新的涟漪 if (this.isRainEnabled) { const timeoutId = setTimeout(() => { this.createSingleRipple(screenWidth, screenHeight); }, Phaser.Math.Between(500, 1500)); - + // 将递归调用的timeout ID保存到数组中 this.rippleTimeouts.push(timeoutId); }