Menu
CoddyTech

Menggigit Diri Sendiri

Pelajaran 10 dari 14 dalam kursus Game Unity: Snake 3D di Coddy.

Ular mati saat kepalanya menabrak ekornya sendiri, sama seperti saat menabrak dinding. Pemeriksaan dilakukan di tempat yang sama: pada next, sel di depan, sebelum kepala bergerak, sehingga kepala tetap di tempatnya saat permainan berakhir.

Satu segmen aman. Pada langkah ini, segmen terakhir juga bergerak ke atas, keluar dari selnya, jadi kepala yang mengikuti ujung ekornya ke sel itu tidak akan pernah menyentuhnya. Ular yang terdiri dari empat kubus bisa mengitari persegi berukuran 2 kali 2 selamanya dengan cara ini. Pemeriksaan tidak menyertakan segmen terakhir dengan berhenti satu langkah sebelum akhir:

// setiap item kecuali yang terakhir
for (int i = 0; i < items.Count - 1; i++)
{
    Debug.Log(items[i].name);
}

Dengan dinding dan ekor yang sama-sama mematikan, permainan bisa berakhir dengan kekalahan, dan bab berikutnya menambahkan skor serta cara untuk bermain lagi.

challenge icon

Tantangan

Sedang

Di dalam Step(), setelah pemeriksaan dinding: jika next adalah sel salah satu segmen ekor selain segmen terakhir, panggil Die() lalu kembalikan, agar kepala tidak bergerak.

Tekan Play, panjangkan ular dan gigit ekormu, lalu tekan Check.

Coba sendiri

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

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // detik antara dua langkah
    public int edge = 7;         // sel papan membentang dari -edge hingga edge
    public bool alive = true;
    public List<Transform> tail = new List<Transform>();
    public Transform segmentPrefab;
    private float timer;
    private Vector3 direction = Vector3.right;       // arah gerak kepala pada langkah terakhirnya
    private Vector3 nextDirection = Vector3.right;   // belokan yang menunggu langkah berikutnya

    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;
    }
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Game Unity: Snake 3D