You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Canvas JS游戏中实现身体部位随头部旋转并保持相对位置

问题描述

我正在开发一款基于Canvas的简易JS游戏,游戏里的生物由多个身体部位组成。目前只设置了头部和身体两个圆形部位,初始状态下身体位于头部正后方。我已经实现了身体部位朝向鼠标旋转的功能,但现在需要让身体始终紧贴在头部后方,跟着头部同步朝向鼠标旋转。

创建生物对象的代码

this.testCreature = new TestingRotation([new BodyTest(2000, 2000, 100, 100), new BodyTest(2000, 2100, 100, 100)])

TestingRotation类的rotate函数

rotate(movement, cameraX, cameraY) {
    if (movement.mousedown && movement.mousemove) {
      const mouseX = movement.mouseX;
      const mouseY = movement.mouseY;

   this.bodyParts.forEach(bodypart => {

      console.log(bodypart.rotationAngle)
    if(bodypart == this.bodyParts[0]){
      const centerX = bodypart.x + bodypart.width / 2
      const centerY = bodypart.y + bodypart.height / 2


      const deltaX = mouseX - centerX;
      const deltaY = mouseY - centerY;

         
  
      bodypart.targetRotationAngle = Math.atan2(deltaY, deltaX) - Math.PI / 2;  // 调整朝向
  
      // 逐步将旋转角度调整到目标角度
      const diff = bodypart.targetRotationAngle - bodypart.rotationAngle
  
      // 计算角度的最小差值
      const shortestDiff = ((diff % (Math.PI * 2)) + (Math.PI * 2)) % (Math.PI * 2) - Math.PI;
  
      if (Math.abs(shortestDiff) > 0.01) {
        
          bodypart.rotationAngle += shortestDiff * this.rotationSpeed;
      }
  
    }

    else{

      const centerX = this.bodyParts[0].x + this.bodyParts[0].width / 2
      const centerY = this.bodyParts[0].y + this.bodyParts[0].height / 2

      const deltaX = mouseX - centerX;
      const deltaY = mouseY - centerY;

  
      bodypart.targetRotationAngle = Math.atan2(deltaY, deltaX) - Math.PI / 2;  // 调整朝向
  
      // 逐步将旋转角度调整到目标角度
      const diff = bodypart.targetRotationAngle - bodypart.rotationAngle
  
      // 计算角度的最小差值
      const shortestDiff = ((diff % (Math.PI * 2)) + (Math.PI * 2)) % (Math.PI * 2) - Math.PI;
  
      if (Math.abs(shortestDiff) > 0.01) {
        
          bodypart.rotationAngle += shortestDiff * this.rotationSpeed;
      }

    }

   });
  }
}

身体部位绘制类BodyTest

export class BodyTest {
    constructor(x, y, width, height) {
      this.x = x;
      this.y = y;
      this.width = width;
      this.height = height;
      this.rotationAngle = 0; // 添加旋转属性
      this.targetRotationAngle = 0;
    }
  
    getBodyPos() {
      let x = this.x;
      let y = this.y;
      let radius = this.height / 2;
  
      return { x, y, radius };
    }
  
    draw(ctx) {
      const bodyPos = this.getBodyPos();
      const centerX = bodyPos.x 
      const centerY = bodyPos.y 
      const radius = bodyPos.radius;
  
      ctx.save(); // 保存当前绘图状态
      ctx.translate(centerX, centerY); // 平移到身体部位中心
      ctx.rotate(this.rotationAngle); // 应用旋转
  
      ctx.lineWidth = 2;
      ctx.beginPath();
      ctx.arc(0, 0, radius, 0, Math.PI * 2);
      ctx.closePath();
      ctx.fillStyle = 'purple';
      ctx.fill();

      ctx.lineWidth = 2;
      ctx.beginPath();
      ctx.arc(0, -30, 5, 0, Math.PI * 2);
      ctx.closePath();
      ctx.fillStyle = 'orange';
      ctx.fill();
  
      ctx.restore(); // 恢复之前的绘图状态
    }
  }

内容的提问来源于stack exchange,提问作者Fernando Marturet Jr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 18:57:54