林旭祥 1 månad sedan
förälder
incheckning
ce0cfbf56f
1 ändrade filer med 88 tillägg och 8 borttagningar
  1. 88 8
      src/views/game/fruit.vue

+ 88 - 8
src/views/game/fruit.vue

@@ -1,6 +1,7 @@
 <template>
   <div class="game-container">
     <div id="game"></div>
+   <canvas ref="canvasRef" :width="clientObj.width" :height="clientObj.height" style="position:fixed;left: 0; top: 0;"></canvas>
   </div>
 </template>
 
@@ -13,6 +14,7 @@ const { proxy } = getCurrentInstance() as any;
 const router = useRouter();
 const { bodyposeWs, startDevice, checkBodypose, openBodypose, terminateBodypose, suspendBodypose, resumeBodypose, getBodyposeState, closeWS } = useWebSocket();
 const gameRef = ref(null); // 用于保存游戏实例的ref
+const canvasRef = ref(null);
 
 const data = reactive<any>({
   bodyposeData: {},//姿态信息
@@ -48,8 +50,9 @@ const getInit = async () => {
     return false;
   }
   speckText("正在姿态识别");
+  proxy?.$modal.msgWarning(`正在姿态识别`);
   bodyposeWs((e: any) => {
-    console.log("bodyposeWS", e)
+    //console.log("bodyposeWS", e)
     if (e?.wksid) {
       wsState.value = true;
       //获取设备信息
@@ -114,7 +117,7 @@ const getInit = async () => {
       for (let i = 0; i < arr.length; i += 3) {
         result.push(arr.slice(i, i + 2));
       }
-      console.log("result", result)
+      // console.log("result", result)
       bodyposeData.value = result;
       if (boxes.value.length == 0) {
         speckText("识别成功");
@@ -123,7 +126,7 @@ const getInit = async () => {
         boxes.value = [{ x: arr[0], y: arr[3] }, { x: arr[0], y: arr[1] }, { x: arr[2], y: arr[1] }, { x: arr[2], y: arr[3] }]
         proportion.value = (clientObj.value.height / (arr[3] - arr[1])).toFixed(2);
       }
-      getCanvas(result);
+      getCanvas();
     }
     if (e?.cmd == 'terminate_bodyposecontroller') {
       if (e?.code == 0) {
@@ -165,9 +168,87 @@ const getCloseBodypose = () => {
 /**
  * 绘图
 */
-const getCanvas = (data:any) => {
-  console.log("data", data)
-  externalMethod(data[10][0], data[10][1])
+const getCanvas = () => {
+  const canvas: any = canvasRef.value;
+  const ctx = canvas.getContext('2d');
+  // 清空整个画布
+  ctx.clearRect(0, 0, canvas.width, canvas.height);
+  // 保存当前状态 
+  ctx.save();
+  function calculateOffset(a: any, b: any) {
+    return {
+      x: b.x - a.x,
+      y: b.y - a.y
+    };
+  }
+  const pointA = { x: clientObj.value.width / 2, y: clientObj.value.height / 2 };
+  const pointB = { x: (boxes.value[2].x + boxes.value[0].x) / 2, y: (boxes.value[3].y + boxes.value[1].y) / 2 };
+  const offset = calculateOffset(pointA, pointB);
+  ctx.translate(-offset.x, -offset.y);
+  // console.log("Canvas分辨率", clientObj.value);
+  // console.log("人体图片四点坐标", boxes.value)
+  // console.log("Canvas中心", pointA);
+  // console.log("人体中心", pointB);
+  // console.log("offset", offset)
+  // console.log("proportion.value",proportion.value)
+  const originalPoints = bodyposeData.value;
+  // 计算缩放后坐标
+  const postData = originalPoints.map((point: any) => {
+    const newX = (point[0] - pointB.x) * proportion.value + pointB.x;
+    const newY = (point[1] - pointB.y) * proportion.value + pointB.y;
+    return [newX, newY];
+  });
+  // console.log("原始坐标:", originalPoints);
+  // console.log("缩放后坐标:", postData);
+  externalMethod(postData[10][0]-offset.x, postData[10][1]-offset.y)
+  //绘制头部
+  const point1 = { x: postData[4][0], y: postData[4][1] };
+  const point2 = { x: postData[3][0], y: postData[3][1] };
+  // 计算椭圆参数
+  const centerX = (point1.x + point2.x) / 2; // 椭圆中心X
+  const centerY = (point1.y + point2.y) / 2; // 椭圆中心Y
+  const distance = Math.sqrt(
+    Math.pow(point2.x - point1.x, 2) +
+    Math.pow(point2.y - point1.y, 2)
+  ); // 两个焦点之间的距离
+  const radiusX = distance * 0.5; // 水平半径(可调整)
+  const radiusY = distance * 0.6; // 垂直半径(可调整)
+  // 1. 绘制填充椭圆
+  ctx.beginPath();
+  ctx.ellipse(centerX, centerY, radiusX, radiusY, 0, 0, Math.PI * 2);
+  ctx.fillStyle = 'red'; // 填充颜色
+  ctx.fill(); // 填充
+  // 2. 绘制边框
+  ctx.strokeStyle = 'red';
+  ctx.lineWidth = 5;
+  ctx.stroke();
+  // 绘制每个点
+  postData.forEach((point: any) => {
+    const [x, y] = point;
+    ctx.beginPath();
+    ctx.arc(x, y, 5, 0, Math.PI * 2); // 绘制半径为5的圆点
+    ctx.fillStyle = 'red';
+    ctx.fill();
+    ctx.lineWidth = 1;
+    ctx.stroke();
+  });
+  // 根据点关系连线
+  const arr = [[10, 8], [8, 6], [6, 5], [5, 7], [7, 9], [6, 12], [5, 11], [12, 11], [12, 14], [14, 16], [11, 13], [13, 15]]
+  arr.forEach((point: any) => {
+    let index1 = point[0];
+    let index2 = point[1];
+    //连线
+    const dian1 = { x: postData[index1][0], y: postData[index1][1] };
+    const dian2 = { x: postData[index2][0], y: postData[index2][1] };
+    // 绘制连线
+    ctx.beginPath();
+    ctx.moveTo(dian1.x, dian1.y); // 起点
+    ctx.lineTo(dian2.x, dian2.y); // 终点
+    ctx.strokeStyle = 'red'; // 线条颜色
+    ctx.lineWidth = 3; // 线条宽度
+    ctx.stroke(); // 描边
+  });
+  ctx.restore(); // 恢复状态
 };
 
 
@@ -850,7 +931,7 @@ class PreloadScene extends Phaser.Scene {
   preload() {
     this.add.sprite(10, height / 2, 'loading').setPosition((width) / 2, height / 2);
     this.load.on('progress', (value) => {
-      console.log("进度", value)
+      // console.log("进度", value)
     });
     // 加载游戏资源
     this.load.image('apple', 'static/images/fruit/apple.png');
@@ -1533,7 +1614,6 @@ const externalMethod = (autoX, autoY) => {
     console.error("游戏未初始化");
     return;
   }
-  console.log("game", game)
   // 2. 获取目标场景(根据当前活跃场景选择'main'或'play')
   // 例如:获取PlayScene(场景key为'play')
   const currentScene = getActiveScene();