الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

كيف أتحكم بسرعة لعبتي .

بدأه Abdullah.Alshammeri في 29 مايو 2008 · 19 رد · 3,086 مشاهدة · في قسم برمجة الألعاب و الرسوميات العام
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم .

لا أخفيكم أن الوقت .. ودقته .. هي أكثر ما يزعجني في برمجة الألعاب ..

سأذكر عدة نقاط واطلب منكم التعليق .. كمناقشة يعني .

- اذا كانت لعبتي سريعة .. فأول ما سأقوم به هو التالي

while(...)
{

  int firstTime  = TimeGetTime(); 
.
.
int lastTime += TimeGetTime() - firstTime;

if(lastTime > 100 ) // كل 100 جزء من الثانية .. أريد التحديث
updatePosition


DrawSomethingHere();

}

هل هذا عملي ؟؟؟ .

هذه الطريقة .. أعتقد مفيدة لو كانت لعبتك سريعة وتريد ابطائها .. لكن العكس لا .,

2- لماذا بعض الألعاب .. وخاص القديمة .. تجعل FPS دائما 60 فريم لكل ثانية .

3- ما فائدة QueryPerformanceFrequency .. وغيرها من الدوال .. يوقولن انها اكثر دقة .. ولم الاحظ اي فرق .. كيف تعمل مثل هذه الدالة .

أتمنى أجد مقال أو رد يفصل ال Timer تفصيل ممل :) ... بانتظاركم ,,

وجدت هذا الرابط .. اريد أن أقرأه لاحقا ,, وحتى لا يضيع :

http://www.geisswerks.com/ryan/FAQS/timing.html

تم تعديل هذه المشاركة بواسطة الشمري في 29 مايو 2008 في 14:46

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#2

المفهوم من ذلك في الاساس هو تثبيت معدل الرسم علي الشاشة في جميع الاجهزة التي تعمل عليها اللعبة

اقتباس
2- لماذا بعض الألعاب .. وخاص القديمة .. تجعل FPS دائما 60 فريم لكل ثانية .

السبب بسيط هو ان هذا المعدل كان يُستخدم في افلام السينما و يعطي صورة جيدة للمشاهد ، ايضاً هناك نظرة اخري هندسية الكترونية و هو معدل انعاش الصورة الراسي او التزمان الرأسي Vertical Synchoronization المرسل من محطة التليفزيون يقوم بسمح الصورة افقيا بمعدل 60 مرة في الثانية و هو تردد قياسي .

اقتباس
3- ما فائدة QueryPerformanceFrequency .. وغيرها من الدوال .. يوقولن انها اكثر دقة .. ولم الاحظ اي فرق .. كيف تعمل مثل هذه الدالة

تقوم هذه الدالة بحساب الوقت بدقة اكثر لانها تٌرجع قيمة Large Integer اي اكثر من ثانية علي عكس timeGetTime بالميلي ثانية و يقولوا ايضاً انها تثبت الوقت بدقة اكثر لكني لم اجربها حقاً .

هذا ما استخدمه (( الكود عفي عليه التراب حقاً لم المسه منذ سنين ))

DWORD				start_clock_count = 0;	 // used for timing

DWORD Get_Clock(void)
{
// this function returns the current tick count

// return time
return(GetTickCount());

} // end Get_Clock

///////////////////////////////////////////////////////////

DWORD Start_Clock(void)
{
// this function starts the clock, that is, saves the current
// count, use in conjunction with Wait_Clock()

return(start_clock_count = Get_Clock());

} // end Start_Clock

////////////////////////////////////////////////////////////

DWORD Wait_Clock(DWORD count)
{
// this function is used to wait for a specific number of clicks
// since the call to Start_Clock

while((Get_Clock() - start_clock_count) < count);
return(Get_Clock());

} // end Wait_Clock

BEng , Electronics and communications.

Embedded systems engineer.

Graphics Programmer

عالم الكومبيوتر هو من لديه المعرفة في علوم الكومبيوتر ، الرياضيات ، هندسة الالكترونيات -احمد صالح

#3

السلام عليكم

يمكنك اخى مبدئيا زيارة هذا الرابط للاستاذ وسام

http://www.agdn-online.com/papers/mmio.htm

وبالتحديد في الجزئية المسماة: المكالمة الثالثة

أرجو أن تعطيك هذه نظرة أوسع لموضوع ال timing

أرفقت أيضا في المرفقات كلاس تستخدم في امثلة كورس ال GameInstitute

وهى رائعة حيث بها امكانية ان تحدد أقصي FPS تريده

وارفقت ايضا احدى امثلة الكورس كاملا لكنه بال DX

أرجو ان يفيدك هذا

للامانة الامثلة منقولة من كورس ال Game Institute

والسلام عليكم

Timer_Class_for_Games.rar

Complete_Sample_using_DX.rar

Ahmed Ezz

Software Engineer

ezzelden.ahmed@yahoo.com

http://ahmedezz.110mb.com/

انما عمرك بأعمالك ، فكم تريد أن تعيش؟

#4

لقد وجدت أن أحداً قد طرح سؤالك يا أخ الشمري في الشبكة العربية لمطوري الألعاب. للأسف لم أستطع نسخ الإجابة لأنها طويلة

لكن هذا رابط الموضوع:

http://www.agdn-online.com/communities.asp...mp;threadid=391

وفيه ذكر أيضاً للمقالة اللي أعطانا إياها aeamg2005 مع أمثلة كود عملية وشرح مفصل للدالة query performence frequency

-------

زوريل

وزير العلوم الأعلى لقوات فيجا المتحالفة

ومخطط الهجمات التكنولوجية

قاعدة جمجمة القمر

#5

بارك الله فيكم جميعا ..

أعيد الرد الذي كتبته في المتنتدى الاخر ,,

المعلومات دسمة .. واحتاج لبعض الوقت للقراءة والتطبيق .. ولي رجعة أخرى ان شاء الله .

الان أشعر بأنه قد زالت كثير من علامات الاستفهام ...

جزيتم خيرا ..

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#6

اخي شمري هناك نقاط لم تذكر (عليه امتحان غداً) ...:

هو انك في تصميم اللعبة قد تستخدم Frame Based Modelling او Time Based Modelling و للحصول علي الدقة تستخدم الطريقة الثانية هي الادق فانت تستخدم الزمن في الاساس فإن كنت مثلاً تريد ان السيارة تسير 50 بكسل في الثانتين فإبستخدام هذه الطريقة تستطيع تثبيت هذا المعدل مع اختلاف المعالجات او الاجهزه التي تعمل عليها فمثلاً لو وضعت حمل عليها من المعالج ستجد ان مهما كان الحمل ستسير 50 بكسل في الثانية و لكن ستجد بطىء او عدم نعومة في الاداء و هذا ما يحدث في الالعاب الان ، اما الطريقة الثانية و هي تثبيت عدد الفريمات في الثانية ستختلف علي قدرة المعالج او الجهاز الذي تعمل عليه .

BEng , Electronics and communications.

Embedded systems engineer.

Graphics Programmer

عالم الكومبيوتر هو من لديه المعرفة في علوم الكومبيوتر ، الرياضيات ، هندسة الالكترونيات -احمد صالح

#7

ليس لدي الكثير من الوقت, ولكن سأذكر مسألة مهمة واجهتها شخصياً, فيما يخص الـ time based والـ frame based, كنت سابقاً أستخدم الـ time based ولكن وجدت إنها تعقد مسائل التوقيت كثيراً, وينتج عنها الكثير من العمليات الإضافية على أعداد حقيقية, تصور مثلاً قائمة البداية للعبة, حيث يدخل كل عنصر من القائمة من اليسار بعد 100 ميلي ثانية من العنصر الذي سبقه, يجب ان يمتلك كل عنصر وكل تأثير مؤقتاً يرتبط مباشرة بمقدار فرق الزمن بين الإطار الحالي والإطار السابق (time delta), وعندما تدخل في تفاصيل اللعبة او المحاكاة ستتعقد المسألة أكثر, حيث إن كل شئ يجب أن يصمم بطريقة بحيث يعتمد على قيمة فرق الزمن التي تكون متغيرة ومجهولة.

هنالك ايضاً مسألة مهمة جداً تتعلق بالفيزياء والتصادم, حيث إن هؤلاء يستخدمون وحدات خاصة تقوم بعمليات التكامل تسمى بالـ integrator, إذا تم إستخدام الـ integrator في بيئة ذات زمن تحديث متغير, ستكون هنالك نسبة خطأ عشوائية وكبيرة, كما تفضل الأستاذ وسام حيث وصف كيف يمكن للسيارة أن تدخل في جدار إذا كانت تمشي بسرعة كبيرة, لذلك فإذا كانت اللعبة تستخدم هكذا عمليات حسابية يجب أن تقوم بتحديث جزء الفيزياء على الأقل بإستخدام زمن ثابت.

أما الـ frame based, فمشكلته تنحصر في إعتماده على سرعة العتاد الذي يتم إستخدامه (قد لا يتمكن كومبيوتر معين من رسم وتحديث 60 إطار في الثانية), ولكنه أسهل للإستخدام من الناحية البرمجية عموماً, وجزء الفيزياء لن يواجه أخطاء ومشاكل في الحسابات كما في الزمن المتغير.

إذاً ما هو الحل؟ الإثنان يمتلكان عيوب ومزايا... هنالك عدة حلول ممكن التوصل لها, مثلاً جعل اللعبة تستخدم عدة اساليب للتوقيت في نفس اللحظة, كيف ذلك؟

لنقل إن لدينا لعبة نحتاج أن ننفذ أجزاءها بالإسلوب التالي:

- رسم المشاهد: بأقصى سرعة ممكنة

- تحديث المشاهد: من الأفضل إستخدام عدد أطر ثابت للتحديث كل ثانية, مثلاً 30 مرة في الثانية

- العمليات الفيزيائية: يجب إستخدام عدد أطر ثابت للتحديث كل ثانية, مثلاً 10 مرات في الثانية أو أكثر طبعاً

أعتقد إن القصد واضح الآن, كل ما تحتاجه حلقة تنفيذ تقوم بمتابعة كل جزء وتنفيذه حينما يحين الوقت لذلك, هنالك مشاكل طبعاً ولكني أعتقد إن هذه الطريقة مستخدمة في عدد كبير من الألعاب.

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

أعتقد إن هذه الفكرة ستكون معقدة للتطبيق, ولكني افكر في محاولة تطبيقها في مشروعي القادم...

هذه المقالة تتحدث عن فكرة مشابهه: Canonical Game Loop

#8

السلام عليكم ,

اعتذر عن التأخر ,,

قرأت كل ردودكم .. وفهمت حاجات كثيرة غائبة عني .. ولي بعض الاسئلة التي لم تنتهي .

- يوجد اسلوب غريب .. أراه في بعض الامثلة .. سأشرح لكم ما فهمته ..وأتمنى تصحيح معلوماتي ,

long start = timeGetTime();
.
.
long delta = timeGetTime() - start; 

x  += delta * 0.001f;

حيث x هو احداثي لنقطة معينة مثلا ..

لو فرضنا الدلتا = 1 ... عندها ستزداد قيمة x بمقدار 0.001 .

وكلما زادت الدلتا .. زادت قيمة x أكثر .

وتصبح الدلتا كبيرة .. فقط اذا كانت معالجة اللعبة بطيئة .. بحيث يكون الفارق بين start و ال end time كبير

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

أما اذا كانت المعالجة سريعة .. ستقل قيمة الدلتا .. وستكون الخطوة x أقل .. ونقلل بالتالي من سرعة المعالجة

في الغالب أرى مثل هذه الطريقة عندما نريد أن نقوم بتدوير مجسم أو كاميرا ..

هل الاستنتاج صحيح .. وهل مثل هذه الطريقة سليمة .

- النقطة الثانية وهي سبب كتابتي لهذا الموضوع أصلا .. وهي النقطة التي أثارها الاخ SandHawk ..

أنا أعمل حاليا على لعبة كلاسيكية .. وهي تعتمد على وجود دبابات تتحرك .. كل دبابة لها سرعة معينة .

عملت كل شيء .. الا انني اصبت باحباط لعجزي عن ادارة اللعبة من ناحية التوقيت .

هل اجعل لكل دبابة مؤقت خاص ,

هل أقول .. كل دبابة تتحرك 1 بكسل لكل 10 أجزاء من الثانية ,

ما سأكتبه شيء شبيه بالتالي :

Tank tank[100] .. 

if(tank[0].timer >= 10 milliSecond )
{
	tank[0].x += 1;
}

if(tank[1].timer >= 20 milliSecond )
{
   tank[1].x +=1;
}

الدبابة الاولى اسرع من الثانية .. لذلك احدثها كل 10 أجزاء من الثانية ..بعكس الاخرى .

- النقطة الاخيرة وهي التي أثارها الاخ أحمد ,, عن Time based و Frame based ..

لو أردت تثبيت معدل الفريمات للعبتي بواقع 60 فريم لكل ثانية :

while( Game->run() )
{
		  long start = GetTickCount();
	.
	.
	.
		  SwapBuffers (hDC);

		  while(GetTickCount() - start < 10);
}

لكن عندما حسبت FPS .. لا يظهر لي 60 فريم ,, السطر الاخير من الكود موجود بالملف المرفق الذي اضافه احد الاخوان في هذا الموضوع ..

انظروا :

	while (!bQuit)
	{
		/* check for messages */
		if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
		{
			/* handle or dispatch messages */
			if (msg.message == WM_QUIT)
			{
				bQuit = TRUE;
			}
			else
			{
				TranslateMessage (&msg);
				DispatchMessage (&msg);
			}
		}
		else
		{
			/* OpenGL animation code goes here */
			long   start = GetTickCount();
			static unsigned int newTime =0;
			static unsigned int oldTime =0;
			static unsigned int frame=0;
			static unsigned int FPS=0;
			newTime = GetTickCount();
			frame++;

			if((newTime - oldTime)>1000)//1000 ms
			{
				FPS=frame;
				oldTime=newTime;
		 		frame=0;
			}
			char *ch = new char[10];
			itoa(FPS,ch,10);
	 		SetWindowText(hWnd,ch);

			glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
			glClear (GL_COLOR_BUFFER_BIT);
			glPushMatrix ();
			glRotatef (theta, 0.0f, 0.0f, 1.0f);
			glBegin (GL_TRIANGLES);
			glColor3f (1.0f, 0.0f, 0.0f);   glVertex2f (0.0f, 1.0f);
			glColor3f (0.0f, 1.0f, 0.0f);   glVertex2f (0.87f, -0.5f);
			glColor3f (0.0f, 0.0f, 1.0f);   glVertex2f (-0.87f, -0.5f);
			glEnd ();
			glPopMatrix ();

			SwapBuffers (hDC);

			theta += 1.0f;

			while((GetTickCount() - start) < 60 );



		}
	}

وماذا لو انخفض معدل الفريمات الى اقل من 60 فريم .. كيف سأعود الى الوضع الطبيعي .. لايوجد حل على ما اظن .

الخلاصة .. هي كيف لي بادارة لعبة دبابات .. من ناحيةالتوقيت .. حيث لكل دبابة سرعة معينة في الحالتين ( Time Based - Frame Based )

تم تعديل هذه المشاركة بواسطة الشمري في 20 يونيو 2008 في 17:35

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#9

وعليكم السلام ورحمة الله,

بالنسبة للنقطة الأولى, فذلك بالضبط هو الهدف.

النقطة الثانية:

لقد واجهت هذه المشكلة بنفسي, كلما اتقدم في اللعبة كلما تتعقد الحسابات أكثر فأكثر, حاولت تطوير مجموعة اكواد استخدمها لتسهيل الأمور ولكن لم تنفع كثيراً, خاصة مع دخول جزء الـ finite state machine التي عاجلاً ام آجلاً ستلجأ لها لإدارة أجزاء وعناصر اللعبة, ولكن تعلمت الكثير من هذه التجارب واوصيك بمحاولة تطبيق طريقة الزمن المتغير لكي تدرك نقاط ضعفها وقوتها.

اما طريقة التطبيق, فأعتقد إن طريقتك يمكن ان تعمل ولكنها ستكون مزعجة اكثر حيث لديك بارمترين متغيرين بدل الواحد (بارمتر سرعة الدبابة بالبكسل وبارمتر الزمن), يمكنك التخلص من احد البارمترين بإستخدام الـ time delta, ما هو الـ time delta من وجهة نظر الزمن؟ إذا كانت الثانية الواحدة = 1000 ميلي ثانية فإن الـ time delta تشير إلى جزء من الثانية, أي أقل من 1000, لذلك فيمكن إستخدامها للحصول على قيمة حقيقية تتراوح بين 1.0f و 0.0f وذلك عن طريق قسمتها على 1000.

أي:

long start = timeGetTime();
.
.
long delta = timeGetTime() - start; 

// حساب قيمة الدلتا الحقيقية إستناداً إلى قيمة الدلتا الصحيحة
float deltaf = (float)delta / 1000.0f; // or float deltaf = (float)delta * 0.001f;

والآن يمكن إستخدام قيمة الدلتا الحقيقية لحساب كم بكسل بالضبط ستتحرك الدبابة كل إطار للحصول على السرعة المطلوبة:

// لنفرض إن الدبابة الأولى يجب ان تسير 50 بكسل في الثانية
// والدبابة الثانية بضعف السرعة وذلك 100 بكسل في الثانية
// ولدينا قيمة الـ deltaf
Tank tank[100];

tank[0].x += 50 * deltaf;
tank[1].x += 100 * deltaf;

وذلك هو بالضبط الإسلوب الغريب الذي ذكرت إنك رأيته في الأمثلة :)

وهو الإسلوب الذي استخدمه شخصياً حتى الآن.

تم تعديل هذه المشاركة بواسطة SandHawk في 20 يونيو 2008 في 18:20

#10

جزاك الله خير أخوي ..

بقي شيء واحد :) .. تثبيت FPS على 60 فريم لكل ثانية .. لم يعمل معي بالشكل الصحيح .. لا اعرف هل المشكلة من حسابي له او شيء اخر .

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#11

الثانية الواحدة = 1000 ميلي ثانية, إن كنت تنوي الحصول على 60 إطار في الثانية, ذلك يعني إن الإطار الواحد يجب ان يستغرق:

LaTeX
:D

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

بالعودة لمثال الدبابات, ولكن بإستخدام النظام الجديد للتوقيت, لجعل دبابة تمشي بسرعة 100 بكسل في الثانية, تقسم السرعة (100) على عدد الأطر الثابت (60), المقدار الذي تحصل عليه هو ما يجب ان تحرك الدبابة بإستخدامه كل مرة, لن تحتاج إدخال الـ time delta في المعادلة..

ولكن إنتبه إلى شئ مهم هنا, عند قسمة 100 على 60 ستحصل على 1.666, كيف يمكنك ان تحرك شيئاً 1.6 بكسل؟ لا يمكن ذلك عملياً, إما 1 او 2, في هذه الحالة سيتم تقريب الناتج إلى 2, وهذا سيقدم نسبة خطأ قد تؤثر على اللعبة. (إن كانت مسافة الحركة 0.4 سيتم تقريبها إلى 0 ولن يتحرك شئ!)

سأعطي حل لهذه المشكلة ولكن يمكن ان تكون هنالك طريقة افضل لحلها, حلّي هو أن تكون إحداثيات الدبابة من نوع float بدل int, يمكن عن طريق ذلك إضافة 1.666 وعدم خسارة اي جزء, وعندما يأتي وقت الرسم, تقوم بتحويل الإحداثيات إلى int بطريقة casting إعتيادية, او في حالة OpenGL يمكن إستخدام الدوال التي تأخذ أعداد حقيقية بدل التي تأخذ أعداد صحيحة (مثلاً glVertex3f).

أين بقية المشاركين؟ كنت اتمنى مشاركتهم في هذا النقاش. :)

تم تعديل هذه المشاركة بواسطة SandHawk في 22 يونيو 2008 في 22:44

#12

بدأت المشاكل تتلاشى شيئا فشيئا :P

* بالنسبة للكود الذي أرفقت هو الكود المنطقي .. وقد جربته فعلا ولكن ليس كما كتب تماما" لم أطرح " .... سأجرب مرة أخرى وأتمنى أن يتثبت FPS على 60 هذه المرة .

* مشكلة " اذا كان FPS أقل من المطلوب .. كيف نزيده " قد أثارها الاخ وسام . في موقعه .. كنت أريد أن أسأله وتعاجزت :)

وضعت رد في ذاك الموضوع

* أشعر أن لعبة الدبابات سترى النور قريبا بعد هذه المناقشات :) .

تم تعديل هذه المشاركة بواسطة الشمري في 23 يونيو 2008 في 10:31

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#13

تثبيت fps على 60 جنّني .

متأكد 100% .. أن حسابي لل FPS صحيح .. وسويت مثل ما قلت أخي سلوان .. لكن دائما يظهر لي ال FPS

بقيمة 33 .. سواء رسمت شيء على الشاشة . . أو لا .

هل يمكن أن تستنتج الخطأ :) ..

  {

		   double t1 = GetTickCount();

		   drawSomething(1);

		  const float FRAME_TIME = 1000.0f/60.0f;


		   int x = GetTickCount() - t1;

		   GetFPS(); 

		   if(x < FRAME_TIME)
				Sleep(FRAME_TIME - x);

		  // while( (GetTickCount() - t1) < (FRAME_TIME ) );

		}

ام ان الامر له علاقة بكرت الشاشة لدي .. قرأت عن vsyn .. وعلاقته بال FPS ... .. أم أن العلة في GetTickCount !!

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#14

من النظرة الأولى لاحظت إنك إستخدمت نوع double لإسترجاع الزمن اول مرة؟ اعتقد إن ذلك يجب ان يكون int.

ايضاً, من الكود الذي أدرجته فإنك لم تمرر اي قيمة لدالة GetFPS, كيف إذن تقوم بحسابه؟ هل يمكنك إدراج كود GetFPS هنا؟

اود كذلك ان اشير إلى نقطة مهمة جداً, زمن الـ Sleep (إذا كان موجب فقط) يجب أن يضاف لزمن الإطار عند القيام بحسابات GetFPS لانه عملياً جزء من الزمن المبذول لكل إطار, وإلا فإنك ستحصل على نتائج غير صحيح.

اما بالنسبة للـ vsync فهي لا تؤثر لأن عملها هو جعل الرسم يتزامن تماماً مع معدل إنعاش الشاشة, وذلك يبدأ من 60Hz فما فوق.

وانا متأكد إنه ليس لـ GetTickCount يد في الموضوع كذلك....

إذاً, انا اتهم دالة GetFPS... (لا ادري لماذا تذكرت المحقق كونان :P )

#15
اقتباس
اود كذلك ان اشير إلى نقطة مهمة جداً, زمن الـ Sleep (إذا كان موجب فقط) يجب أن يضاف لزمن الإطار عند القيام بحسابات GetFPS لانه عملياً جزء من الزمن المبذول لكل إطار, وإلا فإنك ستحصل على نتائج غير صحيح.

قمت بتطبيق ماقلت .. لا اعلم ان كنت قد فهمت المقصود من كلامك ,, والان صار 66 ( قيمة fps )

كنت أتوقف لمدة 16 جزء من الثانية . وهذه تمثل frame .. لذلك صرت اضيف فريمين كل loop ..

//***********************************************
		   static char titleBar[25] = {0};
		   static int FPS = 0;
		   static int frame = 0;
		   static int prevTime = 0.0;
   		   const int FRAME_TIME = 1000/60;
		   int startTime = timer.getTime();

		   drawSomething(10);



		   FPS++;
		   if( (startTime - prevTime)  > 1000)
			  {
				prevTime = startTime;
				wsprintf(titleBar, "%d FPS", int(FPS));
				SetWindowText(hWnd, titleBar);
				FPS = 0;
			   }

		//   int delta = (GetTickCount()- startTime);
		//   if( delta < FRAME_TIME)
		   {
				   Sleep(FRAME_TIME);
				   // while( (timer.getTime() - startTime) < (FRAME_TIME ) );

				   // ADD Another Frame, 16 ms(one frame)
				   FPS++;
		   }
//***********************************************

الكود كامل بالمرفقات .. استعملت دالة أكثر دقة من GetTickCount ومافيه فرق كبير ..

قمت بالغاء عملية فحص الوقت المنقضي .. اذا كان أكبر من FRAME_TIME أو لا .. السبب في ذلك .. ان قيمة delta "تشطح" أحيانا .. يعني أحيانا تعيد صفر .. واحيانا 15 ... مما يظهر FPS بقيم مختلفة .. احيانا 33 واحيانا 66 واحيانا 42 ..

بقي نقطة سأطرحها في موقع وسام .. لننتقل الى هناك :) ... بما أنك موجود أيضا هناك أيضا :) ..

Timer_test.zip

تم تعديل هذه المشاركة بواسطة الشمري في 27 يونيو 2008 في 18:05

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#16

هل من جديد اخوى الشمرى حول الاكواد واللعبة :)

انا الصراحة سأدخل السى بلس خصوصا لبرمجة الالعاب :) لانه لايوجد لها اعدادت مع المحركات وغيره من ذلك الذى تتطلبه اللغات الاخرى

لان معظم المحركات تتم البرمجة عليها :) ، ان شاء الله ابدءفى القريب العاجل بس لى استفسار بسيط واعتذر لانه خارج الموضوع

هل انت تستخدم السى بلس بلس 6 ولا 2005 واسف على الخروج من صلب الموضوع

#17

أنا استخدم VC 2005 و 2008 .. لاتوجد فروقات بينهم كما أرى ,, :)

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#18
اقتباس
أنا استخدم VC 2005 و 2008 .. لاتوجد فروقات بينهم كما أرى ,,

الصراحة انا اريد ان فى السى بلس خصوصا لبرمجة الالعاب فهل من كتاب لتعليم السى بلس 2005

لانى كنت سمعت كلام انها تختلف قليلا عن السى بلس 6 ؟؟

------------------------------------------

وانا اعتذر بشدة مرة اخرى عن خروجى عن صلب موضوعك

#19

لاتوجد اختلافات أخي .. :) ..

لا تكن متخوف من السي لهذه الدرجة .. اذا كنت مبرمج سابق بأي لغة .. فالامر أسهل مما تتخيّل ..

أي كتاب سينفع معك .. انت فقط ابدأ .. وستجدنا في قسم السي ننتظر أسئلتك :) ..

لايلزم اتقان السي بلس 100% حتى تبرمج العاب .. مثل حالتي يعني :) ..

تم تعديل هذه المشاركة بواسطة الشمري في 30 يونيو 2008 في 13:16

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#20
اقتباس
لاتوجد اختلافات أخي .. ..

لا تكن متخوف من السي لهذه الدرجة .. اذا كنت مبرمج سابق بأي لغة .. فالامر أسهل مما تتخيّل ..

أي كتاب سينفع معك .. انت فقط ابدأ .. وستجدنا في قسم السي ننتظر أسئلتك ..

لايلزم اتقان السي بلس 100% حتى تبرمج العاب .. مثل حالتي يعني ..

الصراحة طمنتنى جدا جدا :)

انا الان سأحاول ان اتعلم الاساسيات بالسى بلس وان اتعمق قليلا باللغة من ثم اذهب مباشرة الى الدايركت اكس ولكى اباشر العمل معكم

الصراحة لدى الكثير من الافكار وان شاء الله اطبقها بالقريب العاجل

--------------------------

على فكرة انت من لفت انتباهى للغة السى بلس ، انت من شجعنى لهذه اللغة

---------------

انا يا غالى ضفت ايميلك الذى انت وضعه بملفك الشخصى فهل انت قليل التواجد على المسنجر ؟

مواضيع مشابهة