2013-06-23 2 views
5

델타 시간을 사용하고있어 프로그램 속도를 독립적으로 만들 수 있습니다. 그러나 점프 높이가 같지 않아 캐릭터가 항상 더 낮은 프레임 속도로 점프합니다.델타 시간을 사용할 때 어떻게 점프 높이를 동일하게 유지합니까?

변수 :

const float gravity = 0.0000000014f; 
const float jumpVel = 0.00000046f; 
const float terminalVel = 0.05f; 
bool readyToJump = false; 
float verticalVel = 0.00f; 

로직 코드 :

if(input.isKeyDown(sf::Keyboard::Space)){ 
    if(readyToJump){ 
     verticalVel = -jumpVel * delta; 
     readyToJump = false; 
    } 
} 

verticalVel += gravity * delta; 
y += verticalVel * delta; 

나는 캐릭터가 수평으로 잘 이동하기 때문에 델타 시간이 정확한지 확신합니다.

프레임 속도와 상관없이 캐릭터가 똑같이 뛰게하려면 어떻게해야합니까?

+0

"델타"란 어떤 단위/유형입니까? –

답변

6

새로운 위치를 계산하는 공식은 :

velocity = initial_velocity + (gravity^2 * time) 

참고 :

position = initial_position + velocity * time 

함수에 따라 속도를 감소 계정 중력에받는 중력이 경우는 동일하지 않다 중력으로. 최종 수식은 다음이된다 :

position = initial_position + (initial_velocity + (gravity^2 * time) * time 

위 방정식 initial_position 및 initial_velocity에서 보듯이 시간에 의해 영향을받지 않는다. 하지만 실제로는 초기 속도를 -jumpVelocity * delta으로 설정합니다.

프레임 속도가 낮을수록 delta 값이 커지므로 문자가 더 높게 이동합니다. 이 솔루션은

if(readyToJump){ 
    verticalVel = -jumpVel; 
    readyToJump = false; 
} 

편집에

if(readyToJump){ 
    verticalVel = -jumpVel * delta; 
    readyToJump = false; 
} 

을 변경하는 것입니다 :

은 위의 꽤 좋은 평가를 제공해야하지만, 그것은 완전히 정확하지 않습니다. 시간이 t 이후의 위치 (이 경우 높이)가 p(t)이라고 가정하면, v(t) = p'(t)', and the acceleration is given by에 주어진 속도는 다음과 같이 나타낼 수 있습니다. a (t) = v '(t) = p "(t)`. 우리는 가속도가 일정하다는 것을 알고 있기 때문에;

a(t) = g 
v(t) = v0 + g*t 
p(t) = p0 + v0*t + 1/2*g*t^2 

우리가 지금 우리가 다음받을 다른 시간에 하나 개의 인스턴스에서 위치의 변화, 즉 p(t+delta)-p(t)을 계산하는 경우 :

p(t+delta)-p(t) = p0 + v0*(t+delta) + 1/2*g*(t+delta)^2 - (p0 + v0*t + 1/2*g*t^2) 
       = v0*delta + 1/2*g*delta^2 + g*delta*t 

원래 코드는하지 않습니다 즉, 중력, 우리는 다음과 같은 수 delta 또는 추가 용어 g*delta*t*의 제곱을 고려하십시오. 보다 정확한 접근법은 델타의 증가를 저장 한 다음 위에서 주어진 p(t)의 수식을 사용하는 것입니다.

샘플 코드 :

const float gravity = 0.0000000014f; 
const float jumpVel = 0.00000046f; 
const float limit = ...; // limit for when to stop jumping 

bool isJumping = false; 
float jumpTime; 

if(input.isKeyDown(sf::Keyboard::Space)){ 
    if(!isJumping){ 
     jumpTime = 0; 
     isJumping = true; 
    } 
    else { 
     jumpTime += delta; 
     y = -jumpVel*jumpTime + gravity*sqr(jumpTime); 
     // stop jump 
     if(y<=0.0f) { 
      y = 0.0f; 
      isJumping = false; 
     } 
    } 
} 

참고 : 내가 컴파일 또는 위의 코드를 테스트하지 않았습니다.

+0

감사합니다! verticalVel이 어디에서 효과가 있었는지 전혀 알지 못했기 때문에 샘플 코드가 실제로 나에게 도움이되지는 못했지만. 그러나 귀하의 대답은 제가 여전히 제 문제에 대한 해결책을 찾는 데 도움이되었습니다. – user2513924

+0

죄송합니다, 그 라인을 놓쳤습니다. 그것은 효과가 없었습니다. 내 업데이트에서 제거되었습니다. – TAS

0

"델타 시간"이란 가변 시간 간격을 의미합니까? 에서처럼 모든 프레임에서 이전과 완전히 다른 시간 단계를 계산합니까?

만약 그렇다면 이 아닙니다.

이것을 읽어 http://gafferongames.com/game-physics/fix-your-timestep/

TL; DR은 : 내부 상태에 대한 고정 된 시간 간격을 사용한다; 필요한 경우 프레임을 보간합니다.