Ver código fonte

日常开发

林旭祥 2 meses atrás
pai
commit
60b2932602

BIN
public/static/images/animation/1.png


BIN
public/static/images/animation/2.png


BIN
public/static/images/animation/jumprope.png


+ 0 - 76
src/components/JumpRopeGame/index copy.vue

@@ -1,76 +0,0 @@
-<template>
-  <div ref="gameContainer" class="game-container"></div>
-</template>
-
-<script>
-import { onMounted, ref } from 'vue';
-import Phaser from 'phaser';
-
-export default {
-  name: 'JumpRope',
-  setup() {
-    const gameContainer = ref(null);
-
-    onMounted(() => {
-      // 创建 Phaser 游戏实例
-      const config = {
-        type: Phaser.AUTO,
-        parent: gameContainer.value,
-        width: 800,
-        height: 800,
-        transparent: true, // 设置为透明背景
-        scene: {
-          preload,
-          create,
-          update,
-        },
-      };
-
-      new Phaser.Game(config);
-
-      let rope, player;
-
-      function preload() {
-        this.load.image('rope', 'static/images/animation/2.png'); // 跳绳的图片
-        this.load.image('player', 'static/images/animation/1.png'); // 玩家角色的图片
-      }
-
-      function create() {
-        // 创建跳绳
-        rope = this.add.image(400, 300, 'rope').setOrigin(0.5, 0.5);
-        rope.angle = 0;
-
-        // 创建玩家角色
-        player = this.add.image(400, 450, 'player').setOrigin(0.5, 0.5);
-
-        // 创建动画
-        this.tweens.add({
-          targets: rope,
-          angle: 360,
-          duration: 1000,
-          repeat: -1,
-          yoyo: true,
-          ease: 'Sine.easeInOut',
-        });
-      }
-
-      function update() {
-        // 每帧更新的逻辑,如果有的话
-      }
-    });
-
-    return {
-      gameContainer,
-    };
-  },
-};
-</script>
-
-<style scoped>
-.game-container {
-  width: 100%;
-  height: 100%;
-  margin: 0 auto;
-  position: relative;
-}
-</style>

+ 65 - 60
src/components/JumpRopeGame/index.vue

@@ -1,76 +1,81 @@
 <template>
-  <div ref="gameContainer" class="game-container"></div>
+  <div ref="gameContainer" class="gameContainer"></div>
 </template>
 
-<script>
+<script setup name="JumpRope">
 import { onMounted, ref } from 'vue';
 import Phaser from 'phaser';
+const gameContainer = ref(null);
+const game = ref(null);
+const animatorProperty = ref(null);
+const player = ref(null);
+const frameRate = ref(null);
 
-export default {
-  name: 'JumpRope',
-  setup() {
-    const gameContainer = ref(null);
-
-    onMounted(() => {
-      // 创建 Phaser 游戏实例
-      const config = {
-        type: Phaser.AUTO,
-        parent: gameContainer.value,
-        width: 800,
-        height: 800,
-        transparent: true, // 设置为透明背景
-        scene: {
-          preload,
-          create,
-          update,
-        },
-      };
-
-      new Phaser.Game(config);
-
-      let rope, player;
-
-      function preload() {
-        this.load.image('rope', 'static/images/animation/2.png'); // 跳绳的图片
-        this.load.image('player', 'static/images/animation/1.png'); // 玩家角色的图片
-      }
+function preload() {
+  this.load.spritesheet('character', 'static/images/animation/jumprope.png', {
+    frameWidth: 480,
+    frameHeight: 480
+  });
+}
+function create() {
+  // 创建动画
+  animatorProperty.value = this.anims.create({
+    key: 'sports',
+    frames: this.anims.generateFrameNumbers('character', { start: 0, end: 2 }),
+    frameRate: 10,
+    repeat: -1 // -1表示无限循环
+  });
+  // 创建精灵并播放动画
+  player.value = this.add.sprite(240, 240, 'character');
+}
 
-      function create() {
-        // 创建跳绳
-        rope = this.add.image(400, 300, 'rope').setOrigin(0.5, 0.5);
-        rope.angle = 0;
+function update() {
+  animatorProperty.value.frameRate = frameRate.value;
+}
 
-        // 创建玩家角色
-        player = this.add.image(400, 450, 'player').setOrigin(0.5, 0.5);
+// 触发运动
+const sports = (data) => {
+  frameRate.value = data;
+  player.value.play('sports');
+};
 
-        // 创建动画
-        this.tweens.add({
-          targets: rope,
-          angle: 360,
-          duration: 1000,
-          repeat: -1,
-          yoyo: true,
-          ease: 'Sine.easeInOut',
-        });
-      }
+onMounted(() => {
+  // 创建 Phaser 游戏实例
+  const config = {
+    type: Phaser.AUTO,
+    parent: gameContainer.value,
+    width: 480,
+    height: 480,
+    transparent: true, // 设置为透明背景
+    scene: {
+      preload,
+      create,
+      update
+    }
+  };
+  game.value = new Phaser.Game(config);
+});
 
-      function update() {
-        // 每帧更新的逻辑,如果有的话
-      }
-    });
+onBeforeUnmount(() => {
+  if (game.value) {
+    game.value.destroy(true);
+  }
+});
 
-    return {
-      gameContainer,
-    };
-  },
-};
+//暴露给父组件用
+defineExpose({
+  sports
+});
 </script>
 
 <style scoped>
-.game-container {
-  width: 100%;
-  height: 100%;
-  margin: 0 auto;
-  position: relative;
+.gameContainer {
+  width: 480px;
+  height: 480px;
+  position: fixed;
+  z-index: 999;
+  left: 50%;
+  margin-left: -240px;
+  bottom: 1vh;
 }
 </style>

+ 0 - 2
src/types/components.d.ts

@@ -9,7 +9,6 @@ declare module 'vue' {
   export interface GlobalComponents {
     AddItemWindow: typeof import('./../components/AddItemWindow/index.vue')['default']
     ChooseStudent: typeof import('./../components/ChooseStudent/index.vue')['default']
-    copy: typeof import('./../components/JumpRopeGame/index copy.vue')['default']
     ElAvatar: typeof import('element-plus/es')['ElAvatar']
     ElButton: typeof import('element-plus/es')['ElButton']
     ElIcon: typeof import('element-plus/es')['ElIcon']
@@ -22,7 +21,6 @@ declare module 'vue' {
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
     FaceWindow: typeof import('./../components/FaceWindow/index.vue')['default']
     Header: typeof import('./../components/Header/index.vue')['default']
-    'Index copy': typeof import('./../components/JumpRopeGame/index copy.vue')['default']
     JumpRopeGame: typeof import('./../components/JumpRopeGame/index.vue')['default']
     MultipleItem: typeof import('./../components/MultipleItem/index.vue')['default']
     OptionWindow: typeof import('./../components/OptionWindow/index.vue')['default']

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

@@ -1,7 +1,6 @@
 <template>
   <div class="set">
     <Header @confirmExit="confirmExit"></Header>
-    <!-- <JumpRopeGame /> -->
     <div class="main">
       <div class="li" @click="getConfig">
         <div class="liBox">

+ 25 - 9
src/views/train/test.vue

@@ -36,7 +36,7 @@
             >
               <div class="scoreBox">
                 <div class="score" v-if="currentResultObj?.count && currentResultObj.count>=0">{{ currentResultObj.count }}</div>
-                <div class="prompt" v-else>请开始测试</div>
+                <div class="prompt" v-if="currentResultObj?.count && currentResultObj.count==0 && examState == 42">请开始测试</div>
                 <div class="unit" v-if="!['basketballv1', 'footballv1'].includes(parameter.project) && currentResultObj.count && !needStart">
                   {{ unit }}
                 </div>
@@ -116,8 +116,9 @@
     </div>
     <FaceWindow ref="faceWindowRef" :faceCheckStu="faceCheckStu" :gesture="parameter.gesture" />
     <ChooseStudent ref="chooseStudentRef" @returnData="returnStudent" />
+    <JumpRopeGame ref="gameContainer" v-if="!readyState || [42].includes(examState)" />
+    <div class="close" @click="confirmExit"></div>
   </div>
-  <div class="close" @click="confirmExit"></div>
 </template>
 
 <script setup name="TrainTest" lang="ts">
@@ -147,6 +148,7 @@ const route = useRoute();
 const faceWindowRef = ref();
 const chooseStudentRef = ref();
 const reportListRef = ref();
+const gameContainer = ref();
 const myInfo: any = localStorage.getItem('userInfo');
 const dic: any = dataDictionary;
 const data = reactive<any>({
@@ -1007,6 +1009,20 @@ watch(
   { immediate: true }
 );
 
+/**
+ * 播报时间
+ */
+watch(
+  () => currentResultObj.value.count,
+  (newData) => {
+    if (newData > 0) {
+      let frameRate = (newData / time.value.countdownNum) * 10;
+      gameContainer.value.sports(frameRate);
+    }
+  },
+  { immediate: true }
+);
+
 /**
  * 时间转换
  */
@@ -1507,11 +1523,11 @@ $waiPadding: 6.51rem;
   }
 }
 .close {
-    position: absolute;
-    // right: calc($waiPadding - 3.2rem);
-    left: auto;
-    right: calc($topPadding / 2  - 3.2rem / 4);
-    top: auto;
-    bottom: calc($topPadding / 2  - 3.2rem / 4);
-  }
+  position: absolute;
+  // right: calc($waiPadding - 3.2rem);
+  left: auto;
+  right: calc($topPadding / 2 - 3.2rem / 4);
+  top: auto;
+  bottom: calc($topPadding / 2 - 3.2rem / 4);
+}
 </style>