اردت كتابة هذا الموضوع فقط للتذكير و لاعلام من لا يعلم, ليس فيه الكثير من المعلومات الجديدة, و لكن قد يوفر علي جهود الاجابة على بعض الاسئلة مستقبلا ان شاء الله. الـ game loop هي عبارة عن حلقة تكرارية (كما هو اضح من الاسم) تحصل فيها احداث اللعبة, و كل دورة من هذه الحلقة تعبر عادة عن frame واحد في اللعبة. في كل دورة من دورات هذه الحلقة, تحصل الأشياء التالية (اقل او اكثر ..ليس بالضرورة بهذا الترتيب .. حسب النوع اللعبة .. نحن هنا نتكلم بشكل عام): - اخذ الـ input من المستخدم (من الماوس و الكيبورد, و ايضا من الجويستك اذا كان مستخدما في اللعبة) - معالجة الـ input و تفعيل الـ game logic من أجل تغيير حالة اللعبة - رسم الحالة على الشاشة الـ game logic بدوره قد يتكون من عدة اقسام: - الذكاء الصناعي (logic بسيط او متوسط للتحكم بكائنات اللعبة) - تحريك الكائنات و كشف التصادم - نظام محاكاة فيزيائي physics system/engine للتحكم في كيفية حركة الأشياء هذه قائمة مقتضبة و لا تعبر مطلقا عن كل شيء يجري خلف الكواليس في الالعاب الحقيقية, الهدف هنا هو فقط اعطاء انطباع مبدئي. لماذا نحتاج game loop؟ بسيطة, اي برنامج يعمل لفترة غير محددة و لا ينتهي عمله الا بحدوث امر معين لا بد له من ان يستعمل loop من نوع ما .. ما المقصود برسم frame واحد؟ كما تعلمون كل الالعاب فيها frame rate, و هو معدل الصور اللتي يتم رسمها في الثانية, و لسبب ما, كل صورة تسمى frame او اطار, اعتقد ان السبب في هذا يعود الى المصطلحات اللتي كانت تستخدم في الطرق التقليدية في تقديم عروض السينما في الماضي, و الله أعلم. المهم, انه في بعض الأحيان تلاحظ ان اللعبة بطيئة و الصور متقطعة .. و السبب في هذا ان الـ frame rate قليل, و السبب في ذلك هو ان المدة اللتي تستغرقها اللعبة من أجل اكمال دورة واحدة من الـ game loop طويلة نسبيا, و السبب في هذا هو ان اللعبة تقوم بالعديد من العمليات الحسابية اللتي تأخذ وقتا طويلا للتنفيذ, و قد يكون السبب في هذا هو ان اللعبة مبرمجة بطريقة سيئة, او ان بطاقة العرض video card قديمة و عملية الرسم مكلفة (تاخذ وقتا طويلا نسبيا), او غيرها من الأسباب. اعتقد ان الـ frame rate النموذجي هو 60 صورة في الثانية .. مثال تبسيطي جدا جدا:
#include <iostream>#include <windows.h>#include <conio.h>using namespace std;void drawPlayer( int );int main(){ int input = 0; int playerPosition = 5; //This is the Game Loop (in this example) while( true ) { //delay, to slow down the frame rate Sleep( 30 ); //get input if( _kbhit() ) input = _getch(); else input = 0; //handle input if( input == 'q' ) break; //quit else if( input == 'a' ) //move left { playerPosition--; //detect collision with world boundary!! if( playerPosition < 0 ) { //don't let player go outside!! playerPosition = 0; } } else if( input == 'd' ) //move right { playerPosition++; //detect collision with world boundary!! if( playerPosition > 12 ) { playerPosition = 12; //don't let player go outside!! } } //draw one frame drawPlayer( playerPosition ); } return 0;}void drawPlayer( int position ){ //put the cursor at the beginning of the screen .. in borland, this would be: //gotoxy(0,0) COORD zero = { 0,0 }; SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), zero ); for( int i = 0; i <= 12; i++ ) { if( position == i ) cout << char(1); //ascii `face` character else cout << ' '; }}
displacement = speed * timeDelta;
currentTime = getTime();previousTime = currentTime;while( true ) //game loop{ currentTime = getTime(); //update current time timeDelta = currentTime - previousTime; //calculate time delta for this frame previousTime = currentTime; //update "previous time" to be now .. . . . .}