Prechádzať zdrojové kódy

Merge branch 'dev' of http://git.trops-global.com/linxuxiang/tropsCode into dev

林旭祥 1 týždeň pred
rodič
commit
445661b6f1

+ 18 - 2
src/assets/styles/index.scss

@@ -223,10 +223,18 @@ i,em{
   }
 }
 
-.run50x8 {
+.run60 {
   .el-loading-spinner {
     &::before {
-      background-image: url('../static/images/train/run50x8.png');
+      background-image: url('../static/images/train/run60.png');
+    }
+  }
+}
+
+.run70 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('../static/images/train/run70.png');
     }
   }
 }
@@ -271,6 +279,14 @@ i,em{
   }
 }
 
+.run50x8 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('../static/images/train/run50x8.png');
+    }
+  }
+}
+
 .shotput {
   .el-loading-spinner {
     &::before {

+ 1 - 1
src/components/OptionWindow/index.vue

@@ -393,7 +393,7 @@ const confirm = () => {
   if (chooseArea.value.length > 1) {
     //多区域
     router.push({ path: '/train/multiple', query: optionForm.value });
-  } else if (['run50', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run10x4', 'run50x8'].includes(project.value.key)) {
+  } else if (['run50', 'run60', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run10x4', 'run50x8'].includes(project.value.key)) {
     //跑步项目
     router.push({ path: '/train/run', query: optionForm.value });
   } else if (['skiprope', 'heartbeat'].includes(project.value.key)) {

+ 1 - 1
src/components/ReportList/index.vue

@@ -86,7 +86,7 @@ const getReportList = () => {
         }
         let result = null;
         if (item.result.toString().indexOf(".") != -1) {
-          if (['jump', 'longjump', 'run50', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1', 'footballv1'].includes(type)) {
+          if (['jump', 'longjump', 'run50', 'run60', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1', 'footballv1'].includes(type)) {
             result = item.result.toFixed(2)
           } else {
             result = item.result.toFixed(1);

+ 2 - 0
src/utils/dataDictionary.ts

@@ -56,6 +56,7 @@ let data = {
     shotput: '米',
     trijump: '米',
     run50: '秒',
+    run60: '秒',
     run70: '秒',
     run100: '秒',
     run200: '秒',
@@ -98,6 +99,7 @@ let data = {
     solidball: 'distance',
     shotput: 'distance',
     run50: 'times',
+    run60: 'times',
     run70: 'times',
     run100: 'times',
     run200: 'times',

+ 2 - 2
src/views/analysis/detail.vue

@@ -324,7 +324,7 @@ const getDetails = () => {
       details.value.result :
       Number(details.value.result).toFixed(2);
     details.value.result = proxy?.runTime(myTime)
-  } else if (['run50', 'run70', 'run100', 'run200', 'run400', 'run15x4'].includes(query.value.exam_name)) {
+  } else if (['run50', 'run60', 'run70', 'run100', 'run200', 'run400', 'run15x4'].includes(query.value.exam_name)) {
     details.value.result =
       String(details.value.result).indexOf(".") == -1 ?
         details.value.result :
@@ -339,7 +339,7 @@ const getDetails = () => {
   }
 
   if (
-    ['runa800', 'runa1000', 'run50', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4']
+    ['runa800', 'runa1000', 'run50', 'run60', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4']
       .includes(query.value.exam_name) &&
     details.value.result == 0
   ) {

+ 1 - 0
src/views/analysis/index.vue

@@ -117,6 +117,7 @@ const getReportList = () => {
               'jump',
               'longjump',
               'run50',
+              'run60',
               'run70',
               'run100',
               'run200',

+ 129 - 93
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() {
@@ -846,7 +846,7 @@ class PlayScene extends Phaser.Scene {
     this.blade = null;
     this.fruits = [];
     this.score = 0;
-    this.playing = true;
+    this.playing = false; // 改为false,在初始化方法中设置为true
     this.bombExplode = false;
     this.lostCount = 0;
     this.scoreImage = null;
@@ -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({
@@ -880,9 +880,46 @@ class PlayScene extends Phaser.Scene {
     this.scoreTextAnim();
     this.bestAnim();
     this.xxxAnim();
+    
+    // 添加调试信息
+    console.log("PlayScene created");
+    
+    // 调用初始化方法,而不是直接开始生成水果
+    this.initGame();
+  }
+  
+  initGame() {
+    // 重置游戏状态
+    this.fruits = [];
+    this.score = 0;
+    this.lostCount = 0;
+    this.bombExplode = false;
+    this.scoreText.setText(this.score.toString());
+    
+    // 重置失去计数UI
+    if (this.xxxGroup) {
+      this.xxxGroup.removeAll(true);
+      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.xxxGroup.add([this.x, this.xx, this.xxx]);
+    }
+    
+    // 开始游戏
+    this.playing = true;
+    console.log("Game initialized and started");
+    
+    // 延迟一点时间再生成第一个水果,让玩家有准备
+    this.time.delayedCall(1000, () => {
+      this.startFruit();
+      console.log("First fruit spawned");
+    });
   }
 
   update() {
+    // 如果游戏未开始,不执行任何操作
+    if (!this.playing) return;
+    
     // 检查是否有水果出界
     if (!this.bombExplode) {
       for (let i = this.fruits.length - 1; i >= 0; i--) {
@@ -981,6 +1018,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;
@@ -1172,11 +1210,14 @@ class PlayScene extends Phaser.Scene {
       duration: 300,
       ease: 'Sine.InOut'
     });
+    setTimeout(()=>{
+      this.scene.start('main');
+    },2000)
 
     // 点击重新开始
-    this.input.once('pointerup', () => {
-      this.scene.start('main');
-    });
+    // this.input.once('pointerup', () => {
+    //   this.scene.start('main');
+    // });
   }
 }
 
@@ -1185,11 +1226,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();
 

+ 3 - 3
src/views/ranking/index.vue

@@ -445,7 +445,7 @@ const getGoodStudent = () => {
         }
         let result = null;
         if (item.result.toString().indexOf(".") != -1) {
-          if (['jump', 'longjump', 'run50', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1', 'basketballv1'].includes(projectObj.value.exam_name)) {
+          if (['jump', 'longjump', 'run50', 'run60', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1', 'basketballv1'].includes(projectObj.value.exam_name)) {
             result = item.result.toFixed(2)
           } else {
             result = item.result.toFixed(1);
@@ -495,7 +495,7 @@ const getStudentList = () => {
           }
           let result = null;
           if (item.result.toString().indexOf(".") != -1) {
-            if (['jump', 'longjump', 'run50', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1'].includes(projectObj.value.exam_name)) {
+            if (['jump', 'longjump', 'run50', 'run60', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1'].includes(projectObj.value.exam_name)) {
               result = item.result.toFixed(2)
             } else {
               result = item.result.toFixed(1);
@@ -555,7 +555,7 @@ const getGradeList = async (grade: any) => {
           }
           let result = null;
           if (item.result.toString().indexOf(".") != -1) {
-            if (['jump', 'longjump', 'run50', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1', 'basketballv1'].includes(projectObj.value.exam_name)) {
+            if (['jump', 'longjump', 'run50', 'run60', 'run70', 'run100', 'run200', 'run400', 'run800', 'run1000', 'run15x4', 'run50x8', 'run10x4', 'basketballv1', 'basketballv1'].includes(projectObj.value.exam_name)) {
               result = item.result.toFixed(2)
             } else {
               result = item.result.toFixed(1);