صنعت منذ مدة مكتبة اسمها g4c لبرمجة الالعاب. هذا درس سريع فيها. تحتاج إلى Visual C++ لتجرب ويمكنك تحميل المكتبة نفسها هنا:
سوف نصنع اليوم لعبة happy bird..البعض يحب الطيور الغاضبة لكننا نسمع دائما نصائح على غرار "كن ايجابيا"، "تفاءل" لذلك لن نقلد هؤلاء :)
تجهيز البرنامج
أولاً، خذ نسخة من الdirectory المسمى g4c empty project وسمها بإسم مشروعك. هذه هي الطريقة الرسمية لعمل مشروع جديد.
ثانياً، افتح المشروع (اسمه ينتهي بـ .sln) في الفجوال سي++.
ثالثاً: اذهب إلى مربع solution explorer في يسار الشاشة، أو اختر view -> solution explorer، افتح جزء source files، واختر empty.cpp
سوف تجد دالة main فارغة..سوف تكون هذه برنامجنا بعد قليل.
الرسومات
ارسم طائراً وتفاحة وضعهما في ملفين بإسم bird.bmp و apple.bmp وخزنهما في مكان سهل الوصول اليه مثل c:\img
لاحظ ان الملف يجب ان يكون من نوع BMP وليس أي نوع آخر.لو كانت مواهبك الفنية ضعيفة يمكنك الحصول على الصور من الكود الكاملة الخاصة بهذا المثال.
وضع الشخصيات على الشاشة
يوجد في g4c مفهوم الsprites (الأشكال الطيفية)؛ وهي صور يمكن تحريكها على الشاشة تمثل شخصيات الالعاب (طائرة، كرة، ثائر، ...). يوجد لديك 30 sprite في البرنامج ارقامهم من 0 إلى 29. لتحميل صورة في احدهم تستخدم الدالة load_sprite.
هذه الدالة تأخذ (1) اسم الملف الذي يحتوي الصورة (2) رقم الsprite المطلوب تحميل الصورة فيه.
void main()
{
load_sprite("c:/img/bird.bmp", 0);
load_sprite("c:/img/apple.bmp", 1);
}
لكننا لم نرسم هذه الأطياف بعد! لنفعل ذلك نستخدم الدالة put_sprite، وهي تأخذ رقم الشكل الطيفي وقيم x,y الخاصة بالنقطة التي سيوضع فيها. (x من اليسار، y من الأعلى).
void main()
{
//write your program ;)
load_sprite("c:/img/bird.bmp", 0);
load_sprite("c:/img/apple.bmp", 1);
int x = rand() % 640;
int y = rand() % 480;
put_sprite(0, x, y);
put_sprite(1, 150, 150);
}
هنا اخترنا قيمة عشوائية من صفر إلى 633 للمتغير x (عن طريق عملية mod)، ومثلها للy من 0 إلى 479 (لأن الشاشة دائما 640×480). ثم نادينا put_sprite لنضع الطيف رقم صفر (الطائر) في المكان العشوائي، بينما التفاحة دائما في المكان 150، 150.
تحريك الطائر
لكي نحرك الطائر سنصنع حلقة متكررة كالآتي:
استمر في الآتي:
اقرأ المفتاح
لو المفتاح المضغوط يمين، حرك الطائر لليمين
لو المفتاح المضغوط يسار، حرك الطائر لليسار
لكي نقرأ المفتاح نستخدم الدالة inkey، وهي تعيد -1 لو لم يكن هناك مفتاح مضغوطا لحظة ندائها، أو تعيد كود لو كان زر مضغوط. ما هي الأكواد؟ هي ثوابت في الويندوز (رقم لكل مفتاح) تجدها هنا
حسناً إذاً...
void main()
{
load_sprite("c:/img/bird.bmp", 0);
load_sprite("c:/img/apple.bmp", 1);
int x = rand() % 640;
int y = rand() % 480;
put_sprite(0, x, y);
put_sprite(1, 150, 150);
while(true)
{
int k = inkey();
switch(k)
{
case VK_UP:
y -= 3;
break;
case VK_DOWN:
y += 3;
break;
case VK_LEFT:
x -= 3;
break;
case VK_RIGHT:
x += 3;
break;
}
put_sprite(0, x, y);
}
}
الثوابت VK_... هي الأكواد التي حدثتك عنها. لاحظ ان تغيير قيم الx, y لا تكفي! يجب أن آمر البرنامج ان يعيد رسم الطيف في المكان x,y بواسطة الدالة put_sprite
الآن لو قمنا بتشغيل البرنامج يمكننا تحريك الطائر بالأسهم.
التصادم
كيف نعرف ان الطائر وصل للتفاحة؟ هناك دالة في الg4c اسمها register_sprite_proc، هذه تأخذ اسم دالة اخرى (يجب ان تكون موجودة) وتقوم باستدعاها اوتوماتيكيا في حالة تصادم طيفين مع بعضهما.
يعني لو قلت مثلا
register_sprite_proc(myFunc);
فسوف يقوم الg4c - وليس انت - باستدعاء myFunc في حالة أي تلامس لاشكال sprite أثناء تنفيذ البرنامج. لابد لهذه الدالة ان يكون لها مواصفات محددة:
- Can have any name
- Return value always of type int
- Parameters always of types (int, int, void *)
القيمة من نوع * void يمكن تجاهلها، أما الparameters من نوع int, int فهي ارقام الsprites المتصادمة. يعني لو اثناء تشغيل البرنامج تلامس الاطياف 3، 22 فسوف يتم استدعاء هذه الدالة بحيث يكون اول اثنان من الparameters هما [3، 22] أو [22، 3].
لكننا في لعبتنا لن نحتاج لفحص هذه القيم لأنه في حالة تلامس اطياف فليس لدينا اصلا سوى الطائر والتفاحة!
ها هي الكود الجديدة، لاحظ الاجزاء باللون الأحمر!
int myFunc(int s1, int s2, void *)
{
// حنكتب هنا ايه اللي المفروض يحصل لما الطائر يوصل للتفاحة
return 0;
}
void main()
{
//write your program ;)
load_sprite("c:/img/bird.bmp", 0);
load_sprite("c:/img/apple.bmp", 1);
register_sprite_proc(myFunc);
int x = rand() % 640;
int y = rand() % 480;
put_sprite(0, x, y);
put_sprite(1, 150, 150);
while(true)
{
int k = inkey();
switch(k)
{
case VK_UP:
y -= 3;
break;
case VK_DOWN:
y += 3;
break;
case VK_LEFT:
x -= 3;
break;
case VK_RIGHT:
x += 3;
break;
}
put_sprite(0, x, y);
}
}
ماذا سيحدث في الدالة myFunc؟ نريد ان نخبر المستخدم انه فاز في اللعبة. لكي نعرض رسالة على الشاشة لابد من استخدام دالة text_out، وهي تأخذ string + مكان x, y الذي سيظهر فيه الكلام. نعدل الدالة myFucn ونترك باقي البرنامج كما هو
int myFunc(int s1, int s2, void *)
{
text_out("You won!!", 5, 5);
return 0;
}
ربما تريد أيضاً قراءة دليل الملتمس إلى استخدام الماوس.

