Menu
CoddyTech

الكرة الأخيرة تُحتسب

الدرس 18 من 19 في دورة لعبة Unity: كاسر الطوب على Coddy.

عندما تكون هناك ثلاث كرات في اللعب، يجب ألا يؤدي فقدان كرة إلى خسارة حياة إلا إذا كانت الكرة الأخيرة. وحتى ذلك الحين، تُزال من القائمة وتُدمَّر. وينطبق الأمر نفسه على الكائنات الهلامية التي تنقسم:

public void SlimeDied(Slime slime)
{
    slimes.Remove(slime);
    Destroy(slime.gameObject);
    if (slimes.Count == 0) Debug.Log("Room cleared");
}

قد تُفقَد الكرة الأصلية بينما تواصل النسخ الطيران، لذا قد تكون الكرة الأولى في القائمة نسخة. ويستخدم الكود الذي يحتاج إلى «الكرة»، مثل الكود الخاص بإخلاء المستوى، balls[0]، وليس الحقل Ball من المشهد.

challenge icon

التحدي

صعب

لا يؤدي فقدان كرة إضافية إلى خسارة حياة.

  1. في بداية BallLost: إذا كان balls.Count > 1، نفّذ balls.Remove(lost);، ودمّر كائنها ثم أعد.
  2. عند اجتياز مستوى، استدعِ balls[0].ResetToPaddle() بدلًا من ball.ResetToPaddle().

اضغط «العب»، وقسّم الكرة ثم فوّت كرتين: ستبقى الأرواح كما هي حتى تسقط الكرة الأخيرة. ثم اضغط «تحقق».

جرّب بنفسك

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;

    public Brick brickPrefab;
    public Transform wall;
    public string[] levels;
    public float spacingX = 1.75f;
    public float spacingY = 0.75f;
    public float topY = 6f;

    public Ball ball;
    public int lives = 3;
    public TMP_Text scoreText;
    public TMP_Text livesText;
    public GameObject gameOverPanel;
    public GameObject[] powerUps;
    public float dropChance = 0.15f;

    int score;
    int level;
    int bricksLeft;
    List<Ball> balls = new List<Ball>();

    void Awake()
    {
        Instance = this;
    }

    void Start()
    {
        balls.Add(ball);
        BuildLevel(0);
        ShowHud();
    }

    void BuildLevel(int index)
    {
        level = index;
        string[] rows = levels[index].Split('/');
        for (int row = 0; row < rows.Length; row++)
        {
            string line = rows[row];
            float left = -(line.Length - 1) * spacingX / 2f;
            for (int col = 0; col < line.Length; col++)
            {
                char c = line[col];
                if (c == '.') continue;
                Vector3 pos = new Vector3(left + col * spacingX, topY - row * spacingY, 0f);
                Brick brick = Instantiate(brickPrefab, pos, Quaternion.identity, wall);
                brick.SetHits(c - '0');
                bricksLeft++;
            }
        }
    }

    public void BrickBroken(Brick brick)
    {
        score += brick.points;
        bricksLeft--;
        ShowHud();
        if (Random.value < dropChance)
        {
            GameObject prefab = powerUps[Random.Range(0, powerUps.Length)];
            Instantiate(prefab, brick.transform.position, Quaternion.identity);
        }
        if (bricksLeft == 0)
        {
            ball.ResetToPaddle();
            BuildLevel((level + 1) % levels.Length);
        }
    }

    public void BallLost(Ball lost)
    {
        lives--;
        ShowHud();
        if (lives == 0)
        {
            gameOverPanel.SetActive(true);
            lost.gameObject.SetActive(false);
        }
        else lost.ResetToPaddle();
    }

    public void SplitBall()
    {
        Ball source = balls[0];
        Ball left = Instantiate(source, source.transform.position, Quaternion.identity);
        left.Launch(new Vector3(-0.6f, 1f, 0f));
        balls.Add(left);
        Ball right = Instantiate(source, source.transform.position, Quaternion.identity);
        right.Launch(new Vector3(0.6f, 1f, 0f));
        balls.Add(right);
    }

    public void PlayAgain()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }

    void ShowHud()
    {
        scoreText.text = "Score: " + score;
        livesText.text = "Lives: " + lives;
    }
}

جميع دروس لعبة Unity: كاسر الطوب

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