2013-06-26 2 views
0

XNA 게임에서 화살표를 던지려고하지만 좋은 포물선을 구현하는 데 어려움을 겪고 있습니다.고정 된 각도로 포물선 궤도 만들기

내가 필요한 것 :

  • 은 더 당신은 화살표가가는 강한를 입력 개최.
  • 화살표 각도는 항상 같을 것입니다. 45도입니다. 이것은 내가 이미 가지고있는 것입니다

있습니다

가 나는 그것이 속도 ( timeHeld를) 손실로 바닥을 갈 수있는 화살표를 만들기 위해해야 ​​할 일을 내 질문은
private float velocityHeld = 1f; 
protected override void Update(GameTime gameTime) 
{ 

    if (Keyboard.GetState().IsKeyDown(Keys.Enter) && !released) 
    { 
     timeHeld += velocityHeld; 
     holding = true; 
    } 
    else 
    { 
     if (holding) 
     { 
      released = true; 
      holding = false; 
      lastTimeHeld = timeHeld; 
     } 
    } 


    if (released && timeHeld > 0) 
    { 
     float alpha = MathHelper.ToRadians(45f); 
     double vy = timeHeld * Math.Sin(alpha); 
     double vx = timeHeld * Math.Cos(alpha); 

     ShadowPosition.Y -= (int)vy; 
     ShadowPosition.X += (int)vx; 
     timeHeld -= velocityHeld; 
    } 
    else 
    { 
     released = false; 
    } 
} 

가 완벽한 포물선을 만들기 위해 ?

+0

힌트 : 던져진 물체는 포물선을 지나가는 경향이 있습니다. 왜냐하면 중력 때문에 * 가속도가 * 물체의 * 속도 *를 계속 변경하기 때문입니다. – Kevin

+0

중력 방법을 올바르게 구현해야한다는 것을 알 수 있습니까? – Moondustt

+0

현실적인 동작을 만들려고 할 때 중력을 갖는 것이 좋습니다. – mcmonkey4eva

답변

0

참고 : 지금까지는 XNA에 대해 들어 본 적이 없지만 C#을 사용합니다. 비록 이것이 효과가 없다면 알려주지 만, 그것의 요지가 있어야한다.

마지막 if 문에서 Enter 키를 놓은 후 업데이트를 호출 할 때마다 하향 속도를 일정한 (작은 상수)만큼 늘리려는 경우 (y 좌표를 늘리면 물건이 "아래로 이동합니다"라고 가정 함) " 화면에). 이 작업을 수행하려면 Enter 키를 누를 때마다 매번 double vy = timeHeld * Math.Sin(alpha)을 호출하는 대신 나중에 참조 할 수있는 변수에 결과를 저장 한 다음 bool 값을 사용하여 해당 값을 계산할 시점을 추적하십시오.이 값은 Enter 공개되었다. 즉

, 그것은 이런 식입니다 :이 작업을 수행하는 더 효율적인 방법이있을 수 있지만

// extra variables 
bool justReleased = false; 
double vy, vx; 
... 
protected override void Update(GameTime gameTime) 
{ 
    // ... 
     if (holding) 
     { 
      released = true; 
      holding = false; 
      lastTimeHeld = timeHeld; 
      justReleased = true; // add this here 
     } 
    // ... 

    if (released && timeHeld > 0) 
    { 
     float alpha = MathHelper.ToRadians(45f); 

     // not local variables anymore. Also I flipped the sign - my intention is that initial vertical velocity is "upwards" 
     if(justReleased) 
     { 
      vy = -1 * timeHeld * Math.Sin(alpha); 
      vx = timeHeld * Math.Cos(alpha); 
      justReleased = false; 
     } 

     ShadowPosition.Y += (int)vy; // Note: I flipped this operator 
     ShadowPosition.X += (int)vx; 
     timeHeld -= velocityHeld; 

     // increase the downward velocity 
     vy += 2; // or some constant. I can't test this. :\ 
    } 
    else 
    { 
     released = false; 
    } 
} 

는 희망이, 작동합니다. 이것은 물리 사이트는 아니지만 참조 용으로는

0

을 참조하십시오. 위에서 설명한 솔루션은 모든 반복에서 새 속도를 계산 한 다음 이전 위치에서 델타 (변경)를 계산하여 현재 위치.

게임 루프의 일반적인 논리에 맞습니다. 그러나 연산이 복잡하기 때문에 필요 이상으로 복잡하며 반올림 오류로 인해 불안정 할 수 있습니다.

더 간단하고 안정적인 해결 방법은 포물선의 방정식을 결정하고 발사 후 시간 t에서 위치를 직접 계산하는 것입니다.

화살표가 x = 0, y = 0에서 시작하도록합시다. 발사 속도를 v로 놓는다. 발사 후 시간 t에서, 화살표의 좌표는 x = kt이고, 여기서 k = v * cos (45) = v/sqrt (2)이다.

y 위치는 a, b, c를 모르는 2 차, y = at^2 + bt + c입니다.

그러나 t = 0 인 경우, Y는 = 0이므로 C = 초기 하향 속도는 사용 브이 * 죄 (45) = V/SQRT (2)

0

t = 0이고 치석 작은 비트 = 0

V/SQRT t에서, (속도를 얻는 위치를 미분) (2) = 2AT + B = B

가속도를 얻을 속도를 미분하면, ​​우리는 t의 초기 가속을 얻을 = 0은 2a입니다. 그러나 오직 가속은 중력에 기인합니다. 그래서 2a = -g 여기서 g는 중력 상수입니다.

시간 t

X (t)에서,이 두 방정식을 씌우고는 V/SQRT을 = (2); y (t) = - (g/2) t^2 + vt/sqrt (2)

v 및 t는 g를 정의하므로 시간에 x 및 y 좌표를 계산할 수 있습니다. 이 방정식으로부터 직접 t.

이 방법은보다 직관적이며 더 강력합니다 (반올림 오류는 누적되지 않습니다). 그것은 내가 개인적으로하는 방식입니다. 내 수류탄은 항상 완벽한 파라볼 릭 아크를 따르고 계산 효율적인 방식으로 그렇게합니다.