Frage

Ich bin versucht, einen festen Schritt Schleife in meinem Programm zu erstellen, aber aus irgendeinem Grund, den ich kann nicht scheinen, um es zu bekommen richtig zu arbeiten. Im Grunde, was ich brauche, ist eine Schleife, die funktioniert:

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

oder etwas ähnliches, mit a. Ich habe versucht, Thread.Sleep verwenden, aber ich bin nicht so sicher, es gab mir eine echte festen Schritt Schleife, und als ich versuchte, die Lösung auf

War es hilfreich?

Lösung

Wenn Sie auf einer Game-Engine arbeiten, wird ein Timer wahrscheinlich nicht gut funktionieren. Timer nicht genügend Genauigkeit haben einen festen Schritt Schleife zu behandeln und regelmäßig zu halten.

Sie müssen dies implementieren eine hohe Präzision Timer. In diesem Fall sollten Sie die Stoppuhr-Klasse verwenden. Dies ermöglicht es Ihnen präzise genug, um Ihre elapsedTime genau zu verfolgen.

Sie müssen nur, um zu verfolgen, wie oft wollen Sie (in Ticks) zu aktualisieren, verwenden Sie eine Stoppuhr, die Zeit zu messen, es für jede Ihres Updates nimmt. Danach können Sie möglicherweise einen Sleep () Aufruf verwenden zu blockieren, aber dass der Schlaf erkennen werden nur eine Genauigkeit von 14-15 ms auf den meisten Systemen, auch wenn Sie nur für 0 oder 1 ms schlafen. Dies kann Ihre Schleife zu viel verlangsamen, so dass Sie einen Spin-Lock oder ähnliches können implementieren müssen (während (Warte) {etwas tun}). Sleep () ist schön, weil es CPU wenn spart können Sie, die Spin-Lock wird CPU-Zyklen essen, während Sie warten, sondern gibt Ihnen mehr Präzision.

Andere Tipps

Sind Sie für eine Schleife zu fragen, die im Grunde Zecken alle n laufen? Das klingt wie ein Timer . Es gibt ein paar Timers in der BCL. Ein Timer für Server oder ein für Fensterformen

Sie können sie entlang dieser Linien verwenden. Hier finden Sie Pseudo-Code und bedeutet im Allgemeinen zu zeigen, wie das gemacht wird. Mit anderen Worten wird es wahrscheinlich nicht kompilieren, wenn Sie kopieren und einfügen nur.

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;
       }

               }

}

Sie können auch einen Verschluss verwenden, um Ihren Zustand des Verfahrens einpacken, die der Timer definiert ist.

Bearbeiten

Ich las den Artikel und ich verstehe das Problem; jedoch konnte man noch einen Timer verwenden, aber Sie müssen, wie er Ihre Funktion gesetzt gibt an, bis die Motoren für jedes Intervall Sie Ihr Physik-Engine gesetzt zu rufen.

Sind Sie mit WPF sie haben einige Ereignisse, die ich glaube, die für doign Animationen im stationären Raten gefeuert werden.

Bearbeiten

ich mein Codebeispiel aktualisiert, um Ihnen meine Interpretation zu zeigen, aber im Grunde, was Sie tun, ist ein Intervall für die Physik-Engine zu definieren, und dann, was Sie auf jedem Durchlauf durch Ihren „Loop / Timer, was“ tun müssen, bestimmen, wie viel Echt Zeit seit der letzten Iteration übergeben. Sie speichern dann das Delta in einem Accumalator, die Sie nach unten zählen wird, bis Sie Ihr Physik-Engine für alle Intervalle genannt haben, die Sie verpasst haben seit dem letzten genannt.

Was ich mit kämpfen, wenn ein Timer hier verwendet, ist besser, dann ein dedidicated Faden Schlaf hat, oder eine andere Implementierung.

Thread.Sleep wird nicht Sie einen festen Schritt Schleife geben, es wird einfach die bestimmte Zeit warten, bevor sie das Programm fortgesetzt werden kann. Die tatsächliche Frequenz hängt davon ab, wie genau der Schlaf ist und wie konsistent Ihr Programm ist bei jedem Schritt die gleiche Menge an Wanduhr Zeit in Laufen. Wenn Sie einige Drift aufnehmen können, aber dies könnte angemessen sein und ist sicherlich die einfachste.

eine echte festen Schritt Schleife zu bekommen, was Sie brauchen, ist ein Intervall-Timer , die Ihren Code über einen Rückruf wird ausgeführt, wenn der Timer abläuft. Beachten Sie, dass nicht mehr wirklich eine Schleife ist, aber Sie Code wird periodisch ausgeführt, das ist, glaube ich, was Sie wollen. Auch hier kann es eine gewisse Drift sein und so können Sie bei jedem Schritt das Intervall anpassen müssen, so dass die nächste Ereignis ausgelöst wird zur richtigen Zeit, wenn Sie eine höhere Genauigkeit benötigen. Es ist nicht wirklich möglich, es absolut genau zu machen - auch hardwarebasierte Intervall-Timer hat eine Genauigkeit, schließlich -. Aber hoffentlich können Sie es genug für Ihre Zwecke genau machen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top