문제

프로그램에서 고정 된 단계 루프를 만들려고하지만 어떤 이유로 든 제대로 작동하지 않는 것 같습니다. 기본적으로 내가 필요한 것은 다음과 같은 루프입니다.

while(!over) {
    Update(elapsedtime);
    Draw(elapsedtime);
}

또는 비슷한 것, a. 나는 thread.sleep를 사용해 보았지만 그것이 고정 된 단계 루프를 주었고 솔루션을 구현하려고 할 때 확실하지 않습니다. 이것 웹 사이트 나는 루프의 영향을받는 객체의 상태를 저장하는 방법을 볼 수 없기 때문에 문제가있었습니다. 이로 인해 그 부분을 배제해야했기 때문에 루프에 많은 물체가있을 때 속도가 느려졌습니다.

루프의 모든 객체의 상태를 지속적으로 저장하지 않고 고정 된 스텝 루프를 어떻게 얻을 수 있습니까?

도움이 되었습니까?

해결책

게임 엔진에서 작업하는 경우 타이머가 잘 작동하지 않을 것입니다. 타이머는 고정 된 스텝 루프를 처리하고 규칙적으로 유지하기에 충분한 정확도가 없습니다.

높은 정밀 타이머를 사용하여이를 구현해야합니다. 이 경우 사용하고 싶을 것입니다 스톱워치 클래스. 이렇게하면 ELAPSED 시간을 정확하게 추적 할 수있는 충분한 정밀도가 있습니다.

업데이트가 얼마나 자주 업데이트하려고하는지 (진드기로) 추적 한 다음 스톱워치를 사용하여 각 업데이트에 걸리는 시간을 측정하면됩니다. 그 후에는 잠재적으로 수면 () 전화를 차단할 수 있지만, 0 또는 1ms에만 잠을 자더라도 대부분의 시스템에서 수면이 14-15ms의 정밀도가 있음을 깨달을 수 있습니다. 루프가 너무 느려질 수 있으므로 스핀 잠금 장치 또는 이와 유사한 (대기 (대기) {do something})를 구현해야 할 수도 있습니다. 수면 ()는 가능하면 CPU를 저장하기 때문에 좋습니다. 스핀 잠금 장치는 기다리는 동안 CPU 사이클을 먹지만 더 정밀도를 제공합니다.

다른 팁

기본적으로 모든 N 진드기를 실행할 루프를 요구하고 있습니까? 이것은 A처럼 들립니다 시간제 노동자. BCL에는 타이머가 몇 개 있습니다. ㅏ 서버의 타이머 또는 하나 창 양식의 경우.

이 라인을 따라 사용할 수 있습니다. 다음은 psuedo 코드이며 일반적으로 이것이 어떻게 수행되는지 보여주기위한 것입니다. 다시 말해서 복사하고 붙여 넣으면 컴파일하지 않을 것입니다.

public class RepeatingTask
{
    public MyObjectState _objectState;

    public RepeatingTask(Timespan interval)
    {
       Timer timer=new Timer(Timer_Tick); //This assumes we pass a delegate. Each timer is different. Refer to MSDN for proper usage
       timer.Interval=interval;
       timer.Start();

    }
    private DateTime _lastFire;
    private void Timer_Tick()
    {
       DateTime curTime=DateTime.Now();
       DateTime timeSinceLastFire = curTime-lastFireTime;
       _lastFire=DateTime.Now(); //Store when we last fired...

       accumulatedtime+=timeSinceLastFire
       while(accumulatedtime>=physicsInterval)
       {
          Update(physicsInterval);
          accumulated-=physicInterval;
       }

               }

}

폐쇄를 사용하여 타이머가 정의 된 메소드의 상태를 마무리 할 수도 있습니다.

편집하다

나는 기사를 읽고 문제를 이해합니다. 그러나 여전히 타이머를 사용할 수 있지만, 물리 엔진을 설정하는 각 간격의 엔진을 호출하도록 기능을 설정하므로 필요합니다.

WPF를 사용하고 있습니까? 그들은 Doign 애니메이션에 대해 꾸준한 속도로 발사되는 몇 가지 이벤트가 있습니다.

편집하다

내 해석을 보여주기 위해 내 코드 샘플을 업데이트했지만 기본적으로 당신이하는 일은 물리 엔진의 간격을 정의한 다음 "루프 / 타이머"를 통해 각 패스에서해야 할 일이 그 이후로 실시간이 얼마나 많은지를 결정합니다. 마지막 반복. 그런 다음 해당 델타를 축적자에 보관합니다.이 델타는 마지막으로 전화 한 이후로 놓친 모든 간격에 대해 물리 엔진을 불 때까지 계산하는 데 사용할 수 있습니다.

내가 어려움을 겪고있는 것은 여기에 타이머를 사용하는 것이 더 좋고, 헌신적 인 스레드가 잠을 자거나 다른 구현을하는 것입니다.

Thread.Sleep은 고정 된 단계 루프를 제공하지 않을 것입니다. 프로그램이 계속되기 전에 주어진 시간을 기다립니다. 실제 빈도는 수면이 얼마나 정확하고, 각 단계에서 동일한 양의 벽시계 시간을 실행하는 데 프로그램이 얼마나 일관된 지에 따라 다릅니다. 그러나 약간의 드리프트를 수용 할 수 있다면, 이것은 적절할 수 있으며 확실히 가장 쉬운 일입니다.

실제 고정 스텝 루프를 얻으려면 필요한 것은 간격 타이머 타이머가 만료되면 콜백을 통해 코드를 실행합니다. 더 이상 루프는 아니지만 코드는 정기적으로 실행됩니다. 즉, 원하는 것입니다. 다시 한 번 드리프트가있을 수 있으므로 각 단계에서 간격을 조정하여 다음 이벤트가 더 정확도가 필요한 경우 적시에 발사되도록해야 할 수도 있습니다. 하드웨어 기반 간격 타이머조차도 정확하게 정확하게 만드는 것은 실제로 불가능하지만, 결국 정밀도가 있지만 목적을 위해 충분히 정확하게 만들 수 있기를 바랍니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top