2014-10-03 3 views
0

나는 매 프레임마다 tick() 메서드를 실행하는 프로그램을 가지고있다. 객체가 설정된 중력 상수에 따라 떨어지기를 원했기 때문에, 이전 프레임에서 y 속도를 뺀 위치로 위치를 업데이트하는 Ball 객체를 만들었습니다. y 속도는 각 틱마다 중력 상수만큼 감소합니다. 그러나 진드기가 곧바로 초로 변환되지 않기 때문에 가을이 너무 빠릅니다. 나는 기본적인 수학을 놓치고 있다고 생각하지만, 나는 그것이 무엇인지를 볼 수없는 많은 변수를 저글링하고있다.시간을 FPS와 독립적으로 만드는 방법은 무엇입니까?

편집 : 각 업데이트 프레임 추가 코드

@Override 
public void run(){ 
    init(); 

    long lastTime=System.nanoTime(), timer=System.currentTimeMillis(); 
    final double ticks=60.0; 
    double ns=1000000000/ticks, delta=0; 
    int updates=0, frames=0; 

    while(running){ 
     long now=System.nanoTime(); 
     delta+=(now-lastTime)/ns; 
     lastTime=now; 

     if(delta>=1){ 
      tick(); 
      updates++; 
      delta--; 
     } 

     render(); 
     frames++; 

     if((System.currentTimeMillis()-timer)>1000){ 
      timer+=1000; 
      System.out.println(updates+" ticks, FPS "+frames); 
      frame.setTitle("Ball -- "+SCALEWIDTH+"x"+SCALEHEIGHT+" at "+frames+" FPS"); 
      updates=0; 
      frames=0; 
     } 
    } 
    stop(); 
} 
+1

'tick()'함수는 시간 델타 (마지막 틱 이후 경과 한 시간)를 반환 할 수 있습니다. 그런 다음 새로운 y- 속도를 계산할 때이를 사용할 수 있습니다. – freshtop

+0

프로그램을 재분석해야한다고 생각합니다. 튜토리얼에서 수정되었습니다. 일반적으로 무엇을 찾고 있습니까? 진드기 사이의 시간 간격으로 프레임 속도를 나눠서 "실시간"을 얻으시겠습니까? – Insederec

+0

Java의 경우에는 아무 것도 나누지 않습니다. 방금 System.nanotime()을 호출하고이 차이를 사용하여 마지막 호출 이후 경과 한 시간을 확인합니다. 그 차이가 당신의 시간 단계입니다. – markspace

답변

2

, 당신은 현재와 이전 업데이트 사이의 시간을 초 단위로 계산해야합니다. float 또는 double 일 필요가 있습니다. 이것은 1 초의 순간 일 가능성이 높기 때문입니다. 이를 수행하려면 현재 시간을 밀리 초 또는 나노초 단위로 가져 와서 이전 시간을 빼고 초 단위로 변환하십시오.

그러면이라는 숫자 통합 이라는 프로세스를 사용하여 새 위치와 속도를 계산할 수 있습니다. 이것은 이전 프레임의 계산과 그 사이의 시간을 기반으로 현재 프레임의 위치와 속도를 계산하여 운동 방정식에 대한 근사를 찾는 것을 의미합니다. 이 같은 : dt 초 단위 프레임 사이의 시간입니다

position += velocity * dt; 
velocity += acceleration * dt; 

. 위치와 속도를 통합하는이 특별한 방법을 오일러 방법이라고합니다. 이 방법은 쉽고 응용 프로그램에서 잘 작동하지만 속도 나 가속도가 일정하지 않은 경우 시간이 지남에 따라 정확하지 않게됩니다. 이는 계산되는 값이 곡선의 근사값이기 때문입니다. 더 정확성을 필요로하는 경우

, 당신은 Verlet 또는 룽게 - 쿠타 같은 다른 통합 방법 보길 원하는 것입니다.

+0

내 코드의 델타가 초 사이의 시간이 아닌가요? 나는 그것이라고 생각했다. 그러나 내가 그것을 테스트했을 때 물건은 너무나 빨리 움직였다. – Insederec

+0

나는 발사체 움직임에 대한 실제 방정식을 맞추기 위해'velocity - = g/2 * (dt^2); '라는 코드를 변경 했으므로 제대로 보이지만, 수학적으로 옳지 않다고 확신한다. – Insederec

+0

몇 가지 문제가있는 것 같습니다. dt는 프레임 간의 차이이며 프레임 간의 누적이 아닙니다. 각 업데이트는 delta = (now-lastTime) /1000000000.0으로 계산합니다. 그런 다음 공을 업데이트 할 때마다 (tick()?) 위에이 값을 전달하고 위에 표시된대로 사용하십시오. 코드에 델타를 더하거나 빼거나 60으로 나누지 마십시오. – megadan

관련 문제