林旭祥 1 hete
szülő
commit
346e18d3d7
1 módosított fájl, 85 hozzáadás és 89 törlés
  1. 85 89
      src/views/game/fruit.vue

+ 85 - 89
src/views/game/fruit.vue

@@ -4,31 +4,22 @@
   </div>
 </template>
 
-<script setup name="Fruit" lang="ts">
+<script setup name="Fruit">
 import { onMounted, ref } from 'vue';
 import Phaser from 'phaser';
-const { proxy } = getCurrentInstance() as any;
+const { proxy } = getCurrentInstance();
 const router = useRouter();
 // 游戏容器和尺寸相关
+
+const width = document.documentElement.clientWidth;
+const height = document.documentElement.clientHeight;
+const wRatio = document.documentElement.clientWidth / 640;
+const hRatio = document.documentElement.clientHeight / 480;
 const gameContainer = ref(null);
 let game = null;
-let width = 0;
-let height = 0;
-let wRatio = 1;
-let hRatio = 1;
-
 // 工具类
 const mathTool = {
-  width: 0,
-  height: 0,
-  wRatio: 1,
-  hRatio: 1,
-
   init() {
-    this.width = width;
-    this.height = height;
-    this.wRatio = width / 640;
-    this.hRatio = height / 480;
   },
 
   // 计算延长线,p2往p1延长
@@ -403,55 +394,66 @@ class Fruit {
 
     // 粒子发射器
     this.emitter = this.game.add.particles(0, 0, 'flameParticle', {
-      });
+    });
   }
 
+  // 水果类中的half方法
   half(deg, shouldEmit = false) {
-    // 创建两半水果
+    // 手动计算世界坐标 (替代getWorldPosition)
+    const transform = this.sprite.getWorldTransformMatrix();
+    const worldPos = new Phaser.Math.Vector2(
+      transform.getX(0, 0),
+      transform.getY(0, 0)
+    );
+
+    // 创建两半水果,位置严格等于原水果的世界坐标
     this.halfOne = this.game.add.sprite(
-      this.sprite.x,
-      this.sprite.y,
+      worldPos.x,  // 使用计算出的世界坐标x
+      worldPos.y,  // 使用计算出的世界坐标y
       this.sprite.texture.key + '-1'
     );
     this.halfOne.setOrigin(0.5, 0.5);
     this.halfOne.rotation = Phaser.Math.DegToRad(deg + 45);
 
+    // 物理属性:初始速度归零,避免瞬间偏移
     this.game.physics.add.existing(this.halfOne);
-    this.halfOne.body.velocity.x = 100 + this.sprite.body.velocity.x;
+    this.halfOne.body.velocity.x = this.sprite.body.velocity.x; // 仅继承原速度
     this.halfOne.body.velocity.y = this.sprite.body.velocity.y;
     this.halfOne.body.gravity.y = 2000;
     this.halfOne.body.setCollideWorldBounds(false);
-    this.halfOne.body.onWorldBounds = true;
     this.halfOne.checkWorldBounds = true;
     this.halfOne.outOfBoundsKill = true;
 
+    // 第二半水果同理
     this.halfTwo = this.game.add.sprite(
-      this.sprite.x,
-      this.sprite.y,
+      worldPos.x,  // 使用计算出的世界坐标x
+      worldPos.y,  // 使用计算出的世界坐标y
       this.sprite.texture.key + '-2'
     );
     this.halfTwo.setOrigin(0.5, 0.5);
     this.halfTwo.rotation = Phaser.Math.DegToRad(deg + 45);
 
     this.game.physics.add.existing(this.halfTwo);
-    this.halfTwo.body.velocity.x = -100 + this.sprite.body.velocity.x;
+    this.halfTwo.body.velocity.x = this.sprite.body.velocity.x; // 仅继承原速度
     this.halfTwo.body.velocity.y = this.sprite.body.velocity.y;
     this.halfTwo.body.gravity.y = 2000;
     this.halfTwo.body.setCollideWorldBounds(false);
     this.halfTwo.checkWorldBounds = true;
     this.halfTwo.outOfBoundsKill = true;
 
-    this.sprite.destroy();
+    // 延迟销毁原水果,确保视觉上"替换"而非"突然消失"
+    setTimeout(() => {
+      this.sprite.destroy();
+    }, 50);
 
+    // 粒子效果
     if (shouldEmit) {
       const emitColor = this.emitterMap[this.sprite.texture.key];
       this.generateFlame(this.bitmap, emitColor);
       const texture = this.bitmap.generateTexture('fruitParticle', 60, 60);
-
-
       this.emitter = this.game.add.particles(0, 0, texture.key, {
-        x: this.sprite.x,
-        y: this.sprite.y,
+        x: worldPos.x,
+        y: worldPos.y,
         speed: { min: -400, max: 400 },
         scale: { start: 1, end: 0.1 },
         alpha: { start: 1, end: 0.1 },
@@ -616,11 +618,10 @@ class PreloadScene extends Phaser.Scene {
   }
 
   preload() {
-    const preloadSprite = this.add.sprite(10, height / 2, 'loading');
+    this.add.sprite(10, height / 2, 'loading').setPosition((width) / 2, height / 2);
     this.load.on('progress', (value) => {
-      preloadSprite.setX(10 + (width - 20) * value);
+      console.log("进度", value)
     });
-
     // 加载游戏资源
     this.load.image('apple', 'static/images/fruit/apple.png');
     this.load.image('apple-1', 'static/images/fruit/apple-1.png');
@@ -708,9 +709,9 @@ class MainScene extends Phaser.Scene {
     this.updateRotate();
 
     // 检查是否该跳转到游戏场景
-    if (this.start) {
-      this.gotoNextScene();
-    }
+    // if (this.start) {
+    //   this.gotoNextScene();
+    // }
 
     // 更新刀光
     this.blade.update();
@@ -727,46 +728,48 @@ class MainScene extends Phaser.Scene {
   }
 
   homeGroupAnim() {
+    //创建组合默认先隐藏
     this.homeGroup = this.add.container(0, -height);
-
+    //背景蒙版
     this.home_mask = this.add.image(0, 0, "home-mask");
-    this.home_mask.setY(-200);
+    this.home_mask.setOrigin(0, 0);
     this.home_mask.setScale(wRatio);
-
+    this.home_mask.y = -200;
+    //logo
     this.logo = this.add.image(20, 50, "logo");
-
-    this.homeGroup.add([this.home_mask, this.logo]);
-
+    this.logo.setOrigin(0, 0);
+    //提示语
+    this.home_desc = this.add.image(0, 0, "home-desc");
+    this.home_desc.setPosition((width - this.home_desc.width / 2) - 20, 70);
+    //合并图层
+    this.homeGroup.add([this.home_mask, this.logo, this.home_desc]);
+    // 退出按钮
+    this.lose = this.add.image(0, 0, "lose");
+    this.lose.setPosition(width - this.lose.width - 30, height - this.lose.height - 30);
+    this.lose.setInteractive();
+    // 绑定点击事件
+    this.lose.on('pointerdown', () => this.getExit());
+    //动画效果,接着展示西瓜
     this.tweens.add({
       targets: this.homeGroup,
       y: 0,
       duration: 400,
       ease: 'Sine.InOut',
-      onComplete: () => this.homeDescAnim()
+      onComplete: () => this.fruitAnim()
     });
   }
 
-  homeDescAnim() {
-    this.home_desc = this.add.image(0, 0, "home-desc");
-    this.home_desc.setPosition(width - this.home_desc.width - 10, 25);
-    this.fruitAnim();
-  }
-
   fruitAnim() {
     // 西瓜组
     this.sandiaGroup = this.add.container(323 * wRatio, 373 * hRatio);
     this.sandiaGroup.setScale(0);
-
+    //圆圈
     this.new_game = this.add.sprite(0, 0, "new-game");
     this.new_game.setOrigin(0.5, 0.5);
-
-    this.sandia = new Fruit({
-      scene: this,
-      key: "sandia"
-    });
-
+    //西瓜
+    this.sandia = new Fruit({ scene: this, key: "sandia" });
     this.sandiaGroup.add([this.new_game, this.sandia.getSprite()]);
-
+    //动画效果,接着开放鼠标事件
     this.tweens.add({
       targets: this.sandiaGroup,
       scale: 1,
@@ -774,19 +777,13 @@ class MainScene extends Phaser.Scene {
       ease: 'Linear.None',
       onComplete: () => this.allowBlade()
     });
-
-    // 退出按钮
-    this.lose = this.add.image(0, 0, "lose");
-    this.lose.setPosition(width - this.lose.width - 30, height - this.lose.height - 30);
-    this.lose.setInteractive();
-    this.lose.on('pointerdown', () => this.getExit());
   }
 
   updateRotate() {
+    //西瓜外框圆圈图片旋转
     if (this.new_game) {
       this.new_game.rotation += this.newGameRotateSpeed * 0.016;
     }
-
     if (this.sandia && this.sandia.getSprite()) {
       this.sandia.getSprite().rotation += this.sandiaRotateSpeed * 0.016;
     }
@@ -797,29 +794,32 @@ class MainScene extends Phaser.Scene {
   }
 
   startGame() {
-    this.start = true;
+    // this.start = true;
 
-    // 隐藏主界面元素
-    this.tweens.add({
-      targets: this.homeGroup,
-      y: -height,
-      duration: 200,
-      ease: 'Sine.InOut'
-    });
+    // // 隐藏主界面元素
+    // this.tweens.add({
+    //   targets: this.homeGroup,
+    //   y: -height,
+    //   duration: 200,
+    //   ease: 'Sine.InOut'
+    // });
 
-    this.tweens.add({
-      targets: this.home_desc,
-      x: -this.home_desc.width,
-      duration: 200,
-      ease: 'Sine.InOut'
-    });
+    // // 隐藏按钮
+    // this.new_game.destroy();
+    // this.lose.destroy();
+    // // 切开西瓜
+    // const deg = this.blade.collideDeg();
+    // this.sandia.half(deg);
 
-    // 隐藏按钮
-    this.new_game.destroy();
 
-    // 切开西瓜
+    this.start = false; // 先禁用立即切换
     const deg = this.blade.collideDeg();
-    this.sandia.half(deg);
+    this.sandia.half(deg); // 切开西瓜,生成两半
+
+    // 延迟1秒(1000ms)后再切换场景,等待动画展示
+    setTimeout(() => {
+      this.gotoNextScene();
+    }, 1000);
   }
 
   gotoNextScene() {
@@ -829,7 +829,7 @@ class MainScene extends Phaser.Scene {
 
   getExit() {
     console.log("退出");
-    history.back(-1);
+    router.push({ path: '/game' });
   }
 
   resetScene() {
@@ -867,7 +867,7 @@ class PlayScene extends Phaser.Scene {
     this.bg = this.add.image(0, 0, 'background');
     this.bg.setScale(wRatio, hRatio);
     this.bg.setPosition(width / 2, height / 2);
-    this.bg.setOrigin(0.5, 0.5);
+    this.bg.setOrigin(0, 0);
 
     // 刀光
     this.blade = new Blade({
@@ -981,6 +981,7 @@ class PlayScene extends Phaser.Scene {
   }
 
   startFruit() {
+
     const number = Math.floor(mathTool.randomMinMax(1, 5));
     const hasBomb = Math.random() > 0.7; // 30%概率有炸弹
     const bombIndex = hasBomb ? Math.floor(Math.random() * number) : -1;
@@ -1185,11 +1186,6 @@ class PlayScene extends Phaser.Scene {
 onMounted(() => {
   // 获取容器尺寸
   const container = document.getElementById('game');
-  width = container.clientWidth || window.innerWidth;
-  height = container.clientHeight || window.innerHeight;
-  wRatio = width / 640;
-  hRatio = height / 480;
-
   // 初始化工具类
   mathTool.init();