آه، لعبة Flappy Bird – تلك التجربة التي جعلتنا ندمن النقر على الشاشات، ندفع الطائر الصغير بين الأنابيب، ثم يتهاوى وجهه على الأرض بصوت “بونك”! إذا كنت تحلم بدخول عالم تطوير الألعاب، فإن إعادة بناء هذه اللعبة البسيطة ستمنحك أساسًا متينًا لفهم مبادئ Unity وكيفية تعامل المحرك مع الرسوميات والحركات والفيزياء.
سنخوض في هذا الدليل مجموعة من الخطوات العملية، تبدأ من تثبيت الأدوات اللازمة، مرورًا بإدارة الموارد وإنشاء الرسوم وتحريكها، وصولًا إلى برمجة المنطق الأساسي للعبة. كل خطوة صممت بعناية لتناسب المبتدئين وتساعدك على التعلم من خلال التطبيق المباشر.
الخطوة الأولى: تثبيت الأدوات اللازمة
قبل أن نبدأ في كتابة أي سطر برمجي، تحتاج إلى أدوات العمل الأساسية. محرر Unity هو بيئة التطوير التي سنستخدمها لبناء عالم لعبتنا، بينما Unity Hub يسهل عليك إدارة إصدارات Unity وفتح المشاريع وتنظيمها.
يتميز Unity Hub بواجهة بسيطة تتيح لك تنزيل أكثر من نسخة من Unity، فتح المشاريع السابقة، وإنشاء مشاريع جديدة بسهولة. احرص على تثبيت الإصدار الأخير من Unity LTS لضمان استقرار الأداء ودعم أحدث الميزات.
الخطوة الثانية: إنشاء مشروع ثنائي الأبعاد
في Unity Hub: اختر “جديد” (New)، ثم حدد قالب 2D. هذه الخطوة تضمن أن إعدادات الكاميرا والمساحة ثنائية الأبعاد جاهزة منذ البداية. عند تسمية المشروع، اختر اسمًا يعبر عن محتواه مثل FlappyBirdTutorial
لتسهل عليك تمييزه لاحقًا.
بعد الضغط على Create، سيُفتح محرر Unity مع نافذة المشروع، حيث سترى نوافذ Hierarchy (لعرض العناصر في المشهد)، وScene (لتحرير المشهد) وGame (لمعاينة اللعب)، وInspector (لعرض خصائص العناصر)، وProject (لإدارة الملفات والموارد).

الخطوة الثالثة: إعداد مجلد Sprites
للحفاظ على تنظيم ملفات المشروع، أنشئ في نافذة Project مجلدًا جديدًا باسم Sprites. هذا المجلد سيحتوي على جميع ملفات الصور التي سنستخدمها: طائر اللعبة، أنابيب العقبات، الخلفيات، وأزرار واجهة المستخدم.
التنظيم الجيد للمجلدات يوفر عليك البحث لاحقًا ويجعل عملية التصدير أو التعديل أسهل. يمكنك لاحقًا إنشاء مجلدات فرعية مثل Bird, Pipes, UI داخل Sprites.

الخطوة الرابعة: استيراد الموارد (Assets)
قم بتنزيل صور الطائر والأنابيب وواجهات المستخدم من مصادر مجانية أو صمّمها بنفسك. في نافذة Project، اضغط بزر الفأرة الأيمن داخل مجلد Sprites واختر Import New Asset…. بعد اختيار الملفات، انتقل إلى نافذة Inspector لكل ملف وضبط الإعدادات:
- Sprite Mode = Multiple: يسمح بتقسيم ملف الصورة إلى عدة عناصر.
- Filter Mode = Point: للحفاظ على بكسليّة الرسوم وعدم تلطيفها.
- Compression = None: لتفادي فقدان الجودة.
اضغط Apply لتأكيد التغييرات.

الخطوة الخامسة: تقسيم ملف Sprites إلى عناصر
لاستخدام أجزاء الصورة بمفردها (الطائر، أجزاء الأنبوب)، نفتح Sprite Editor. اختر الصورة في Project ثم اضغط Sprite Editor. اسحب مستطيلات حول كل عنصر لإنشاء شرائح مستقلة. بعد الانتهاء، اضغط Apply. يمكنك بعدها رؤية كل شريحة كعنصر منفصل داخل Sprites.
هذه العملية تُسهل عليك لاحقًا سحب الأجزاء إلى المشهد بشكل مباشر دون الحاجة لقص الصور خارج Unity.

الخطوة السادسة: ضبط المشهد (Scene)
في نافذة Game، اضبط نسبتَيْ العرض والارتفاع على 9:16 ليحاكي تصميم الهواتف الذكية. ثم اسحب صورة الخلفية (Background) من Project إلى Hierarchy.
اختر Main Camera واضبط قيمة Order in Layer إلى –1 لضمان ظهور الخلفية خلف جميع العناصر الأخرى. بهذه البساطة، يصبح المشهد جاهزًا لاستقبال الأشياء المتحركة فوقه.
الخطوة السابعة: إضافة اللاعب (Player)
من Sprites، اسحب إطار الطائر إلى Hierarchy وسمّه Player. أضف إليه مكونيّ Rigidbody 2D لضبط الفيزياء، وCapsule Collider 2D للكشف عن التصادم. تأكد من جعل اتجاه الكبسولة أفقيًا وضبط حجمها لتغطي جسم الطائر بدقة.
بهذه الإضافات، يصبح الطائر خاضعًا لقوانين الفيزياء؛ يستطيع السقوط بفعل الجاذبية ويتفاعل مع التصادمات.

الخطوة الثامنة: تحريك الطائر بأنيميشن
في Project: Create → Animation، سمّها Flap. اسحب الأنيميشن إلى Player ليضاف Animator. اضغط Ctrl+6 لفتح نافذة Animation، ثم اسحب ثلاث إطارات من Sprites إلى لوحة الأنيميشن. حرّك مفاتيح الإطارات لتحصل على حركة جناح سلسة: المفتاح الأول في البداية، الثاني عند 0:05، والثالث عند 0:10.
التزامن الدقيق بين الإطارات يعطي انطباعًا طبيعيًا لطيران الطائر ويعزز تجربة اللعب.

الخطوة التاسعة: إعداد المنصة الأرضية (Platform)
اسحب صورة المنصة إلى Hierarchy وسمِّها Platform. في Inspector اختر Draw Mode = Tiled لتكرار الصورة أفقياً بشكل سلس، وOrder in Layer = 1 حتى تظهر فوق الخلفية. أضف Box Collider 2D وفعل Auto Tiling لجعل التصادم مع أرضية ثابتة.
الآن المنصة جاهزة لتقف عليها العوائق والطائر دون اختراقها.

الخطوة العاشرة: برمجة تحليق الطائر
أنشئ C# Script باسم Player.cs واصقه مع الكود:
using UnityEngine;
public class Player : MonoBehaviour
{
public float velocity = 2.4f;
private Rigidbody2D rb;
void Start() => rb = GetComponent<Rigidbody2D>();
void Update()
{
if (Input.GetMouseButtonDown(0))
rb.velocity = Vector2.up * velocity;
}
}
اسحب السكربت إلى Player. مع هذا الكود، يصبح اللاعب قادرًا على القفز عند النقر أو اللمس.
الخطوة الحادية عشرة: إنشاء العوائق (Pipes)
اسحب إطارَي الأنبوب إلى المشهد وأضف لكل منهما Box Collider 2D. اجعلهما Child داخل Empty Game Object جديد سمّه ObstaclePipes. هذا التنظيم يسهل تحريكهما معًا وإدراجهما كمجموعة.
الخطوة الثانية عشرة: تحريك العوائق
أنشئ Script باسم Obstacle.cs:
using UnityEngine;
public class Obstacle : MonoBehaviour
{
public float speed = 2f;
void Update() => transform.position += Vector3.left * speed * Time.deltaTime;
}
اربطه بـObstaclePipes. يتحرك الأنابيب إلى اليسار بسرعة ثابتة، مما يخلق تحديًا للاعب.
الخطوة الثالثة عشرة: مكرّر إنشاء العوائق
أنشئ Empty Game Object باسم ObstacleSpawner وضعه على يمين الشاشة. ثم Script باسم Spawner.cs:
using UnityEngine;
public class Spawner : MonoBehaviour
{
public float queueTime = 1.5f, height = 2f;
private float timer = 0f;
public GameObject obstaclePrefab;
void Update()
{
timer += Time.deltaTime;
if (timer > queueTime)
{
var go = Instantiate(obstaclePrefab, transform.position + new Vector3(0, Random.Range(-height, height), 0), Quaternion.identity);
Destroy(go, 10f);
timer = 0f;
}
}
}
اربط obstaclePrefab
بالـPrefab الذي أنشأته من ObstaclePipes. بهذه الخطوات، تظهر الأنابيب بشكل دوري وبارتفاعات عشوائية.
الخطوة الرابعة عشرة: واجهة المستخدم وزر إعادة التشغيل
إنشاء Canvas من UI → Canvas، ثم Image وسمِّها RestartButton. اربطها بصورة زر التشغيل من Sprites، واضغط Set Native Size ثم ضع Scale = 0.85. سيظهر زر إعادة التشغيل عند فشل اللاعب.
الخطوة الخامسة عشرة: مدير اللعبة (GameManager)
أنشئ Empty Game Object باسم GameManager Script GameManager.cs:
using UnityEngine;
using UnityEngine.UI;
using UnityEditor.SceneManagement;
public class GameManager : MonoBehaviour
{
public GameObject startButton;
public Player player;
public Text countdownText;
private float timer = 5f;
void Start()
{
countdownText.gameObject.SetActive(false);
Time.timeScale = 0f;
}
void Update()
{
if (player.isDead)
{
countdownText.gameObject.SetActive(true);
timer -= Time.unscaledDeltaTime;
countdownText.text = "إعادة التشغيل خلال " + Mathf.Ceil(timer);
if (timer <= 0f) RestartGame();
}
}
public void StartGame()
{
startButton.SetActive(false);
Time.timeScale = 1f;
}
public void GameOver() => Time.timeScale = 0f;
public void RestartGame() => EditorSceneManager.LoadScene(0);
}
اربط startButton وزر التشغيل وPlayer وText بالحقول المناسبة.
الخطوة السادسة عشرة: كشف التصادم وحالة الموت
في Player.cs أضف:
public GameManager gameManager;
public bool isDead = false;
private void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.CompareTag("Ground") || col.gameObject.CompareTag("Obstacle"))
{
isDead = true;
gameManager.GameOver();
}
}
وتأكد من وسم المنصة والأنابيب بالـTag الصحيح.

الختام
احفظ المشاهد والسكربتات، ثم استمتع بلعبتك!