林旭祥 vor 10 Stunden
Ursprung
Commit
e2d7ddb854
2 geänderte Dateien mit 71 neuen und 52 gelöschten Zeilen
  1. BIN
      public/static/images/fruit/ninja.png
  2. 71 52
      src/views/game/fruit.vue

BIN
public/static/images/fruit/ninja.png


+ 71 - 52
src/views/game/fruit.vue

@@ -260,61 +260,69 @@ class Bomb {
 
   explode(onWhite, onComplete) {
     const lights = [];
-    const startDeg = Math.floor(Math.random() * 360);
-    const tweens = [];
+    const startDeg = Math.floor(Math.random() * 360); // 随机初始角度(备用)
 
+    // 1. 创建8个灯光图形(爆炸扩散效果)
     for (let i = 0; i < 8; i++) {
       const light = this.game.add.graphics({
-        x: this.sprite.x,
+        x: this.sprite.x, // 基于炸弹位置定位
         y: this.sprite.y
       });
-
-      // 省略灯光绘制代码...
-
+      light.fillStyle(0xffffff, 0); // 初始透明
+      light.beginPath();
+      light.arc(0, 0, 15 + i * 10, 0, Math.PI * 2); // 半径递增的圆形灯光
+      light.closePath();
+      light.fill();
+      light.setDepth(2000); // 确保在其他元素上方
       lights.push(light);
-
-      const tween = this.game.tweens.add({
-        targets: light,
-        alpha: 1,
-        duration: 100,
-        paused: true
-      });
-
-      tweens.push(tween);
     }
 
+    // 2. 打乱灯光顺序(与动画顺序匹配)
     mathTool.shuffle(lights);
 
-    // 使用 Phaser 的 TweenChain 创建链式动画
+    // 3. 构建链式动画配置(每个灯光的闪烁动画)
+    const tweenConfigs = lights.map(light => ({
+      targets: light,
+      alpha: { value: [0, 1, 0], duration: 500 }, // 淡入淡出
+      scale: { value: 2, duration: 500 }, // 缩放扩散
+      onComplete: () => {
+        light.destroy(); // 单个灯光动画结束后销毁
+      }
+    }));
+
+    // 4. 执行链式动画(按打乱后的顺序播放灯光效果)
     this.game.tweens.chain({
-      tweens: tweens,
+      tweens: tweenConfigs,
       onComplete: () => {
+        // 5. 所有灯光动画结束后,执行白屏效果
         const whiteScreen = this.game.add.graphics({
           x: 0,
           y: 0,
           fillStyle: { color: 0xffffff, alpha: 0 }
         });
-        whiteScreen.fillRect(0, 0, width, height);
+        whiteScreen.fillRect(0, 0, width, height); // 覆盖全屏
+        whiteScreen.setDepth(3000); // 确保在最上层
 
+        // 白屏动画:淡入后淡出
         this.game.tweens.add({
           targets: whiteScreen,
-          alpha: 1,
-          duration: 100,
+          alpha: { value: [0, 1, 0], duration: 400 }, // 100ms淡入 + 300ms淡出
+          onUpdate: (tween) => {
+            // 白屏峰值时触发onWhite回调(替代原分步逻辑)
+            if (tween.progress >= 0.25 && tween.progress <= 0.3) {
+              onWhite(); // 白屏最亮时执行(原逻辑中的"白屏显示时")
+            }
+          },
           onComplete: () => {
-            onWhite();
-            lights.forEach(light => light.destroy());
-
-            // 添加延迟确保视觉效果完成
-            this.game.time.delayedCall(300, () => {
-              whiteScreen.destroy();
+            whiteScreen.destroy();
+            // 确保回调有效后执行
+            if (typeof onComplete === 'function') {
               onComplete();
-            });
+            }
           }
         });
       }
     });
-
-    tweens[0].play();
   }
 
   getSprite() {
@@ -635,7 +643,6 @@ class PreloadScene extends Phaser.Scene {
     this.load.image('logo', 'static/images/fruit/logo.png');
     this.load.image('lose', 'static/images/fruit/lose.png');
     this.load.image('new-game', 'static/images/fruit/new-game.png');
-    this.load.image('ninja', 'static/images/fruit/ninja.png');
     this.load.image('peach', 'static/images/fruit/peach.png');
     this.load.image('peach-1', 'static/images/fruit/peach-1.png');
     this.load.image('peach-2', 'static/images/fruit/peach-2.png');
@@ -901,6 +908,9 @@ class PlayScene extends Phaser.Scene {
       this.x = this.add.image(0, 0, 'x');
       this.xx = this.add.image(22, 0, 'xx');
       this.xxx = this.add.image(49, 0, 'xxx');
+      this.x.setOrigin(0, 0);
+      this.xx.setOrigin(0, 0);
+      this.xxx.setOrigin(0, 0);
       this.xxxGroup.add([this.x, this.xx, this.xxx]);
     }
 
@@ -971,6 +981,7 @@ class PlayScene extends Phaser.Scene {
 
   scoreAnim() {
     this.scoreImage = this.add.image(-100, 8, 'score');
+    this.scoreImage.setOrigin(0, 0);
     this.tweens.add({
       targets: this.scoreImage,
       x: 8,
@@ -981,6 +992,7 @@ class PlayScene extends Phaser.Scene {
 
   bestAnim() {
     this.best = this.add.image(-100, 52, 'best');
+    this.best.setOrigin(0, 0);
     this.tweens.add({
       targets: this.best,
       x: 5,
@@ -991,6 +1003,7 @@ class PlayScene extends Phaser.Scene {
 
   scoreTextAnim() {
     this.scoreText = this.add.bitmapText(-100, 40, 'number', this.score.toString(), 32);
+    this.scoreText.setOrigin(0, 0);
     this.tweens.add({
       targets: this.scoreText,
       x: 75,
@@ -1146,20 +1159,20 @@ class PlayScene extends Phaser.Scene {
 
     // 停止所有水果的物理运动
     this.fruits.forEach(fruit => {
-      const sprite = fruit.getSprite();
-      if (sprite && sprite.body) {
-        sprite.body.setVelocity(0);
-        sprite.body.setGravity(0);
+      if (fruit.getSprite() && fruit.getSprite().body) {
+        fruit.getSprite().body.setVelocity(0);
+        fruit.getSprite().body.setGravity(0);
       }
     });
 
     // 炸弹爆炸
     bomb.explode(
       () => {
-        // 爆炸白光显示时的回调
+        // 白屏显示时的回调:销毁所有水果
         this.fruits.forEach(fruit => {
-          const sprite = fruit.getSprite();
-          if (sprite) sprite.destroy();
+          if (fruit.getSprite()) {
+            fruit.getSprite().destroy();
+          }
         });
         this.fruits = [];
       },
@@ -1184,7 +1197,7 @@ class PlayScene extends Phaser.Scene {
   lostAnim(removeObj, addKey) {
     removeObj.destroy();
     const newObj = this.add.sprite(removeObj.x, removeObj.y, addKey);
-    newObj.setOrigin(0.5, 0.5);
+    newObj.setOrigin(0, 0);
     newObj.setScale(0);
     this.xxxGroup.add(newObj);
 
@@ -1198,29 +1211,35 @@ class PlayScene extends Phaser.Scene {
 
   gameOver() {
     this.playing = false;
-    // 显示游戏结束图片
+
+    // 1. 确保所有其他元素停止更新,避免干扰
+    this.blade.allowBlade = false; // 禁用刀光
+
+    // 2. 创建game-over图片,并设置最高层级
     const gameOverSprite = this.add.sprite(width / 2, height / 2, 'game-over');
     gameOverSprite.setOrigin(0.5, 0.5);
     gameOverSprite.setScale(0);
+    gameOverSprite.setDepth(1000); // 设置最高层级,确保不被覆盖
 
-    // 添加入场动画
+    // 3. 优化入场动画,确保平滑显示
     this.tweens.add({
       targets: gameOverSprite,
       scale: 1,
-      duration: 400,
-      ease: 'Sine.InOut'
+      duration: 500, // 延长动画时间,确保可见
+      ease: 'Elastic.Out', // 更明显的弹性动画,增强视觉效果
+      onComplete: () => {
+        // 动画完成后再设置自动返回,确保用户有足够时间看到画面
+        setTimeout(() => {
+          console.log('游戏结束,返回首页');
+          this.scene.start('main');
+        }, 3000); // 延长至3秒,给用户足够时间观察
+      }
     });
 
-    // 确保2秒后自动返回首页,增加日志确认执行
-    console.log('游戏结束,准备返回首页...');
-    setTimeout(() => {
-      console.log('执行返回首页操作');
-      this.scene.start('main'); // 切换到主场景(首页)
-    }, 2000);
-
-    // 保留点击立即返回的逻辑(可选)
-    this.input.once('pointerup', () => {
-      console.log('点击立即返回首页');
+    // 4. 支持点击立即返回,提升交互体验
+    gameOverSprite.setInteractive();
+    gameOverSprite.on('pointerdown', () => {
+      console.log('点击返回首页');
       this.scene.start('main');
     });
   }