Menu
CoddyTech

عضّ نفسك

الدرس 10 من 14 في دورة لعبة Unity: الثعبان ثلاثي الأبعاد على Coddy.

يموت الثعبان عندما يصطدم رأسه بذيله، كما يحدث عند اصطدامه بجدار. يُجرى الاختبار في الموضع نفسه: على next، الخلية التي أمامه، قبل أن يتحرك الرأس، ليبقى الرأس في مكانه عند انتهاء اللعبة.

جزء واحد آمن. في هذه الخطوة، يتحرك الجزء الأخير إلى الأعلى أيضًا، خارج خليته، لذا فإن الرأس الذي يتبع نهاية ذيله إلى تلك الخلية لا يلمسه أبدًا. يمكن لثعبان مكوّن من أربعة مكعبات أن يدور حول مربع أبعاده 2 في 2 إلى الأبد بهذه الطريقة. يستثني الاختبار الجزء الأخير بالتوقف قبل النهاية بجزء واحد:

// كل عنصر باستثناء الأخير
for (int i = 0; i < items.Count - 1; i++)
{
    Debug.Log(items[i].name);
}

مع كون الجدران والذيل كليهما قاتلين، يمكن خسارة اللعبة، ويضيف الفصل التالي النتيجة وطريقة للعب مرة أخرى.

challenge icon

التحدي

متوسط

قضم الذيل ينهي اللعبة.

  1. في Step()، بعد اختبار الجدار، كرّر المرور على الذيل باستخدام i < tail.Count - 1، مع استثناء المقطع الأخير.
  2. إذا كان tail[i].position == next، فاستدعِ Die() ثم أعد، لكي لا يتحرك الرأس.

اضغط «العب»، وأطِل الثعبان ثم استدر باتجاه ذيلك: سيتوقف. ثم اضغط «تحقق».

جرّب بنفسك

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // الثواني بين خطوتين
    public int edge = 7;         // تمتد خلايا اللوحة من -edge إلى edge
    public bool alive = true;
    public List<Transform> tail = new List<Transform>();
    public Transform segmentPrefab;
    private float timer;
    private Vector3 direction = Vector3.right;       // الاتجاه الذي تحرك فيه الرأس في خطوته الأخيرة
    private Vector3 nextDirection = Vector3.right;   // الانعطاف المنتظر للخطوة التالية

    void Update()
    {
        if (!alive) return;

        Keyboard keyboard = Keyboard.current;
        if (keyboard != null)
        {
            if (keyboard.upArrowKey.wasPressedThisFrame || keyboard.wKey.wasPressedThisFrame) Turn(Vector3.forward);
            if (keyboard.downArrowKey.wasPressedThisFrame || keyboard.sKey.wasPressedThisFrame) Turn(Vector3.back);
            if (keyboard.leftArrowKey.wasPressedThisFrame || keyboard.aKey.wasPressedThisFrame) Turn(Vector3.left);
            if (keyboard.rightArrowKey.wasPressedThisFrame || keyboard.dKey.wasPressedThisFrame) Turn(Vector3.right);
        }

        timer += Time.deltaTime;
        if (timer >= tick)
        {
            timer -= tick;
            Step();
        }
    }

    void Turn(Vector3 newDirection)
    {
        if (newDirection != -direction)
        {
            nextDirection = newDirection;
        }
    }

    void Step()
    {
        direction = nextDirection;
        Vector3 next = transform.position + direction;
        if (Mathf.Abs(next.x) > edge || Mathf.Abs(next.z) > edge)
        {
            Die();
            return;
        }

        Vector3 tailEnd = tail.Count > 0 ? tail[tail.Count - 1].position : transform.position;
        for (int i = tail.Count - 1; i > 0; i--)
        {
            tail[i].position = tail[i - 1].position;
        }
        if (tail.Count > 0)
        {
            tail[0].position = transform.position;
        }
        transform.position = next;

        if (GameManager.Instance.IsFood(next))
        {
            tail.Add(Instantiate(segmentPrefab, tailEnd, Quaternion.identity));
            GameManager.Instance.Eat();
        }
    }

    public bool Occupies(Vector3 cell)
    {
        if (transform.position == cell) return true;
        foreach (Transform segment in tail)
        {
            if (segment.position == cell) return true;
        }
        return false;
    }

    void Die()
    {
        alive = false;
    }
}

جميع دروس لعبة Unity: الثعبان ثلاثي الأبعاد

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