Menu
CoddyTech

Gigit Dirimu 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

Menggigit ekor mengakhiri permainan.

  1. Di Step(), setelah pemeriksaan dinding, lakukan perulangan pada ekor dengan i < tail.Count - 1, tanpa menyertakan segmen terakhir.
  2. Jika tail[i].position == next, panggil Die() lalu return, sehingga kepala tidak bergerak.

Tekan tombol “Main”, besarkan ular dan belok ke arah ekormu: ular akan berhenti. Lalu tekan tombol “Periksa”.

Coba sendiri

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

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // detik di 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 terakhir
    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;
    }
}

Semua pelajaran di Game Unity: Snake 3D

Latihan sendiri: Playground Unity