Menu
CoddyTech

التبديل بين الحالات

جزء من قسم إنشاء ألعاب حقيقية في رحلة Unity على Coddy. الدرس 15 من 60.

تنفّذ كل حالة من حالات اللعبة عملاً مختلفًا في كل إطار. يضع switch على حقل الحالة هذا العمل في حالة واحدة لكل حالة، وينفّذ كل إطار حالة واحدة بالضبط. يجري تغيير الحالة عبر طريقة واحدة، لذا تتوافق الشاشة دائمًا مع الحالة. تتضمن معركة الزعيم هذه مقدمةً ومعركةً وشاشة فوز:

public enum Phase { Intro, Fight, Won }

public class BossFight : MonoBehaviour
{
    public GameObject introPanel;
    public GameObject fightPanel;
    public GameObject winPanel;
    public int bossHp = 10;
    private Phase phase;
    private float timer = 3f;

    void Start()
    {
        Enter(Phase.Intro);
    }

    void Update()
    {
        switch (phase)
        {
            case Phase.Intro:
                timer -= Time.deltaTime;
                if (timer <= 0f) Enter(Phase.Fight);
                break;
            case Phase.Fight:
                if (bossHp <= 0) Enter(Phase.Won);
                break;
            case Phase.Won:
                break;
        }
    }

    void Enter(Phase next)
    {
        phase = next;
        introPanel.SetActive(next == Phase.Intro);
        fightPanel.SetActive(next == Phase.Fight);
        winPanel.SetActive(next == Phase.Won);
    }
}

تنتهي كل حالة بـ break، لأن C# يرفض ترجمة حالة تستمر في التنفيذ وصولًا إلى الحالة التالية. عندما ينفد مؤقّت المقدمة، يغيّر Enter(Phase.Fight) المرحلة، لكن حالة Fight لا تعمل إلا في الإطار التالي، لأن هذا الإطار قد اختار حالته بالفعل. أما مع كتل if منفصلة ومتتابعة، فقد يبدأ الإطار المعركة وينفّذ شيفرة القتال في الإطار نفسه.

Enter هو المكان الوحيد الذي يغيّر phase. تكون next == Phase.Fight مساويةً لـ true للوحة القتال فقط، لذا يُظهر استدعاء واحد تلك اللوحة ويخفي اللوحتين الأخريين. يوضع العمل المرتبط بالدخول إلى حالة، مثل إعادة ضبط المؤقّت، في Enter أيضًا، ويُنفّذ مرة واحدة بدلًا من كل إطار.

challenge icon

التحدي

سهل

أنشئ سباق النقرات لمدة 5 ثوانٍ.

  1. في SetState، اعرض لوحة الحالة الجديدة فقط. عند الدخول إلى Playing، عيّن taps = 0 وtimeLeft = roundTime وTaps: 0؛ وعند الدخول إلى GameOver، اعرض Taps: 3 في resultText.
  2. في Update()، استخدم switch (state): ينقل Space الحالة من Ready إلى Playing ومن GameOver إلى Ready؛ وفي Playing، يحصي كل ضغطة على Space في taps وtapsText حتى ينتهي الوقت.

اضغط «العب» وتنافس مرتين. ثم اضغط «تحقق».

جرّب بنفسك

using UnityEngine;
using TMPro;

public enum GameState { Ready, Playing, GameOver }

public class GameManager : MonoBehaviour
{
    public GameObject readyPanel;
    public GameObject playPanel;
    public GameObject gameOverPanel;
    public TMP_Text tapsText;
    public TMP_Text resultText;
    public float roundTime = 5f;
    public GameState state;
    private int taps;
    private float timeLeft;

    void Start()
    {
        SetState(GameState.Ready);
    }

    void Update()
    {
        // بدّل حسب state:
        // Ready: يبدأ Space جولة
        // Playing: تُحتسب ضغطة عند الضغط على Space؛ وعندما ينتهي الوقت، تنتهي اللعبة
        // GameOver: يعيد Space الحالة إلى Ready
    }

    void SetState(GameState next)
    {
        state = next;
        // أظهر لوحة الحالة الجديدة فقط
        // تبدأ جولة جديدة بـ 0 ضغطات وتستمر roundTime ثانية؛ وفي النهاية، يعرض resultText عدد الضغطات
    }
}

جميع دروس إنشاء ألعاب حقيقية

تدرّب بنفسك: Playground لـ Unity