سؤال

وأنا محاولة لخلق حلقة خطوة ثابتة في برنامجي، ولكن لسبب ما أنا فقط لا يمكن أن يبدو للحصول عليه للعمل بشكل صحيح. أساسا ما احتاج اليه هو حلقة أن يفعل:

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

وأو شيئا من هذا القبيل، مع أ. لقد حاولت استخدام Thread.Sleep لكنني لست متأكدا من ذلك أعطاني حقيقية حلقة خطوة ثابتة، وعندما حاولت تنفيذ الحل على <لأ href = "http://gafferongames.com/game-physics/ إصلاح الخاص بك بين خطوة زمنية / "يختلط =" نوفولو noreferrer "> هذا موقع كان لي مشاكل يرجع ذلك إلى حقيقة أن لم أستطع أن أرى وسيلة لانقاذ الدولة من الكائنات تتأثر الحلقة. هذا اجبرني على استبعاد هذا الجزء، مما أدى إلى تباطؤ عندما كانت هناك العديد من الكائنات في الحلقة.

وكيف يمكنني الحصول على حلقة خطوة ثابتة دون الحاجة باستمرار لانقاذ الدولة من كل كائن في الحلقة؟

هل كانت مفيدة؟

المحلول

إذا كنت تعمل على محرك اللعبة، والموقت وربما لا تعمل بشكل جيد. مؤقتات لم يكن لديك ما يكفي من الدقة لمعالجة حلقة خطوة ثابتة وابقائه العادية.

وستحتاج لتنفيذ ذلك باستخدام جهاز توقيت عالية الدقة. في هذه الحالة، سوف تحتاج إلى استخدام الطبقة ساعة توقيت. هذا سوف يسمح لك لديك ما يكفي من الدقة لتتبع elapsedTime الخاص بك بدقة.

وأنت تحتاج فقط لتتبع عدد المرات التي تريد تحديث (في القراد)، ثم استخدم ساعة توقيت لقياس الوقت الذي يستغرقه كل من التحديثات الخاصة بك. بعد ذلك، يمكنك يحتمل أن تستخدم مكالمة السكون () لمنع، ولكن ندرك أن النوم لن يكون لها سوى دقة من 14-15 مللي ثانية على معظم الأنظمة، حتى لو كنت أنام إلا ل0 أو 1 مللي ثانية. هذا قد تبطئ حلقة الخاصة بك كثيرا، لذلك قد تحتاج إلى تنفيذ تأمين زيادة ونقصان أو ما شابه ذلك (بينما (الانتظار) {تفعل شيئا}). النوم () هو لطيف لأنه يحفظ وحدة المعالجة المركزية إذا استطعت، وتأمين زيادة ونقصان سوف يأكل دورات CPU بينما كنت في انتظار، ولكن يمنحك المزيد من الدقة.

نصائح أخرى

هل طلب حلقة التي سوف تعمل أساسا كل n القراد؟ هذا يبدو وكأنه الموقت . وهناك زوجين من جهاز ضبط الوقت في BCL. A الموقت للخوادم أو واحد <أ href = على "HTTP : //msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx "يختلط =" نوفولو noreferrer "> لأشكال النافذة

ويمكنك استخدامها على طول هذه الخطوط. وفيما يلي كود الزائف وتهدف الى اثبات عموما كيف يتم ذلك. وبعبارة أخرى فإنه من المحتمل أن يتم ترجمة إذا كنت مجرد نسخ ولصق.

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.

تحرير

ولقد قمت بتحديث نموذج التعليمات البرمجية لي أن تظهر لك تفسيري لكن أساسا ما عليك فعله هو تحديد فاصل زمني لمحرك الفيزياء الخاصة بك، ثم ما عليك القيام به على كل تمر عبر الخاص بك "حلقة / الموقت مهما" هو تحديد مقدار الحقيقي بمرور الوقت منذ التكرار الماضي. يمكنك ثم تخزين تلك دلتا في Accumalator، والتي سوف تستخدم للعد التنازلي حتى كنت قد دعا محرك الفيزياء لجميع فترات ما فاتك منذ قمت بالاتصال بها.

ما أكافح مع هو في حالة استخدام جهاز ضبط الوقت هنا هو أفضل، ثم وجود النوم موضوع dedidicated، أو بعض تنفيذ آخرين.

وThread.Sleep لن تعطيك حلقة خطوة ثابتة، وسوف ببساطة الانتظار كمية معينة من الزمن قبل أن يتيح البرنامج متابعة. وتردد الفعلي سيتوقف على مدى دقة النوم هو وكيف يتفق البرنامج في تشغيل على نفس القدر من جدار الزمن على مدار الساعة في كل خطوة. إذا كنت يمكن أن تستوعب بعض الانجراف، على الرغم من أن هذا قد يكون كافيا وبالتأكيد أسهل.

لتحصل على حقيقية حلقة خطوة ثابتة، ما تحتاجه هو <وأ href = "http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx#" يختلط = "نوفولو noreferrer "> الفاصل الزمني الموقت الذي ينفذ التعليمات البرمجية الخاصة بك عن طريق الاستدعاء عند انتهاء الموقت. لاحظ أنه ليس حقا حلقة بعد الآن، ولكن يعدم لك كود بشكل دوري، والتي هي، كما أعتقد، ما تريد. مرة أخرى، قد يكون هناك بعض من الانجراف، ولذا قد تحتاج إلى ضبط الفاصل الزمني في كل خطوة بحيث وقع الحدث المقبلة في الوقت المناسب اذا كنت بحاجة الى مزيد من الدقة. ليس من الممكن حقا أن تجعل من دقيقة تماما - حتى الأجهزة القائمة على توقيت الفاصلة لها بدقة، بعد كل شيء - ولكن نأمل يمكنك ان تجعل دقيقة بما فيه الكفاية لأغراضك

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top