2d Billiard power physics

时间:2017-09-10 08:53:52

标签: c# unity3d

我认为我的动力引擎存在数学问题,过去两天我一直试图解决这个问题。我对编程比较陌生,正在Unity中开发2D自上而下的台球游戏。

我的代码附在下方,但基本上玩家会点击球并向后拖动以产生力量。一旦它们达到所需的功率并放开,球将以所需的功率以所需的方向发射。为了这个例子,让我们说我将maxPower设置为100,并且玩家对象的线性拖动和平铺拖动保持不变。在下面的示例场景中,所有镜头都处于全功率状态,我从桌子的左下方拍摄:

  1. 我拍摄了一个纯粹的X轴镜头 - 球向右侧100次射击
  2. 我射击纯粹的Y轴射击 - 球以100次向上射击
  3. 我以45度角拍摄 - 我怎么能算出这里发生了什么?
  4. 如果你看下面的代码,我会释放鼠标后使用AddForce将球推到x和y轴上。我跟踪每个镜头在各个角度拍摄的距离,并尝试了以下电源管理:

    1. 在x轴和y轴之间分离功率 - 最终产生比纯x / y轴镜头(每轴50功率)弱得多的镜头
    2. 为每个轴提供全部功率 - 最终产生更强大的镜头(每轴100个功率)
    3. 感觉像金发姑娘一样,我试图让这个正确的计算机使用毕达哥拉斯定理进行计算,这就是我在努力的地方。
    4. 非常感谢任何帮助。

      下面的代码 - 定义了所有变量,我刚删除了不相关的代码。

          public float maxForce = 100;
          public float forceMultiplier = 2
      
      
          void Awake() {
      
              startPosition = transform.position;
      
          }
      
          void Update () {     
      
              /// Tracks distance (start vs current)
              distance = Vector3.Distance(transform.position,startPosition);
      
              //On Click
              if (Input.GetMouseButtonDown (0)) {   
      
                  startPosX = Input.mousePosition.x;
                  startPosY = Input.mousePosition.y;
              }
      
              /// While being clicked
              if (Input.GetMouseButton (0)) {
      
                  ///  Determines force to be applied based on mouse drag
                  current_xForce = (startPosX - Input.mousePosition.x);
                  current_yForce = (startPosY - Input.mousePosition.y);
      
                  // Stores the original drag angle
                  yCheck = current_yForce;
                  xCheck = current_xForce;
      
      
                  ///  if current x/y force is greater than maxForce, set to maxForce
                  if (current_yForce > 0 && current_yForce > maxForce)
                      current_yForce = maxForce;
                  if (current_yForce < 0 && current_yForce < -maxForce)
                      current_yForce = -maxForce;
                  if (current_xForce > 0 && current_xForce > maxForce)
                      current_xForce = maxForce;
                  if (current_xForce < 0 && current_xForce < -maxForce)
                      current_xForce = -maxForce;
      
                  //  Determines the % of x/y while aiming
                  current_xPercentage = Mathf.Abs (current_xForce) / (Mathf.Abs (current_xForce) + Mathf.Abs (current_yForce));
                  current_yPercentage = Mathf.Abs (current_yForce) / (Mathf.Abs (current_xForce) + Mathf.Abs (current_yForce));
      
                  //  Decides the Power bar% - power determined by highest powered axis (may need improvement)
                  current_powerPercent = Mathf.Max (Mathf.Abs (current_xForce)/maxForce, Mathf.Abs (current_yForce)/maxForce);
      
      
                  //  get angle from start position to relative mouse position... add relative mouse position   NOT WORKING... need degrees
                  shotAngle = Vector2.Angle(startPosition,Input.mousePosition);
              }
      
              // Mouse button released
              if (Input.GetMouseButtonUp (0)) {               
      
                  ///  Only shots with greater than % of total power count - allows you to cancel shots
                  if (current_powerPercent >= 0.10) {
      
                      ///  Increase force by public multiplier
                      xForce = current_xForce * forceMultiplier ;    
                      yForce = current_yForce * forceMultiplier ;
      
      
      
                      ///  Use % of absolute xCheck to determine shot angle 
                      float xForcePercent = Mathf.Abs (xCheck) / (Mathf.Abs (yCheck) + Mathf.Abs (xCheck));
                      float yForcePercent = Mathf.Abs (yCheck) / (Mathf.Abs (yCheck) + Mathf.Abs (xCheck));
      
                      ///  Adds force to x/y based off xForce and the shot angle
                      float x_addForce = xForce * xForcePercent;
                      float y_addForce = yForce * yForcePercent;
      
                      ///  Attempt at a-squared + b-squared = c-squared.... this is supposed to return c
                      powerVar = Mathf.Sqrt(Mathf.Pow (x_addForce*xForcePercent, 2) + Mathf.Pow (y_addForce*yForcePercent, 2));
      
      
                      ///  Applies the force to the player object.. .for each axis I take powerVar * angle * sign (to adjust for negative values)
                      GetComponent<Rigidbody2D>().AddForce(new Vector2(powerVar*xForcePercent*Mathf.Sign(x_addForce), powerVar*yForcePercent*Mathf.Sign(y_addForce)));
      
      
                      yForce = 0;
                      xForce = 0;
                      startPosX = 0;
                      startPosY = 0;   
                      distance = 0;
                      startPosition = transform.position;  /// resets Distance counter
      
      
                  }
              }
          }
      

1 个答案:

答案 0 :(得分:1)

Pythagorean theorem表示在直角三角形中,以下情况属实:

c

c是斜边。现在,在您的情况下,100cab45°之间的角度为c。这意味着你是平等的&#34;分裂&#34; ab之间的a = b, therefore: c * c = a * a + a * a, which means c * c = 2 * a * a 。好吧,让我们这样做:

c = sqrt(2) * a, and therefore
a = c / sqrt(2)

如果我们采取双方的平方根:

a = sqrt(2)/2 * c

您可能会看到以下形式写的相同关系:

c

你去吧。如果100a,那么b70,711将为d

如果使用trigonometric functions(基于毕达哥拉斯定理),您可以对任何角度进行概括。对于ca之间的任何角度 a = c * cos(d) b = c * sin(d) ,以下情况均属实:

 180 degrees = pi radians

如果您打算使用三角函数,请确保您的单位正确。角度通常以弧度给出,而不是度,两者之间的关系是:

{{1}}