Menu
CoddyTech

Crescere

Lezione 8 di 14 del corso Gioco Unity: Snake 3D di Coddy.

Mangiare fa diventare il serpente più lungo di un segmento. Il nuovo segmento va dove si trovava la punta della coda prima del passo: la coda avanza e il nuovo segmento occupa la cella lasciata libera dalla punta, così il serpente cresce dalla coda.

Quella cella non c’è più una volta che la coda si è spostata, quindi ricordala prima. Poi, quando la testa ha raggiunto il cibo, istanzia un segmento in quel punto e aggiungilo all’elenco, così dal passo successivo seguirà gli altri. Un segmento che viene creato ma non aggiunto non si muove. Un treno aggiunge un vagone in coda allo stesso modo:

Vector3 back = wagons[wagons.Count - 1].position;
// ... il treno prosegue ...
Transform wagon = Instantiate(wagonPrefab, back, Quaternion.identity);
wagons.Add(wagon);

Fai crescere il serpente prima di chiamare Eat(). Eat() sposta il cibo e, nella lezione successiva, il serpente cercherà una cella che non occupa, compresa quella del nuovo segmento.

challenge icon

Sfida

Medio

Ogni cibo aggiunge un segmento alla coda.

  1. In Snake, aggiungi public Transform segmentPrefab; (la scena lo collega).
  2. In Step(), prima che la coda si muova, conserva Vector3 tailEnd: la cella dell'ultimo segmento oppure quella della testa quando la coda è vuota.
  3. Quando mangi del cibo, aggiungi Instantiate(segmentPrefab, tailEnd, Quaternion.identity) a tail, poi chiama Eat().

Premi «Gioca» e mangiane alcuni: il serpente cresce di un cubo ogni volta. Poi premi «Verifica».

Provalo tu

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

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // secondi tra due passi
    public int edge = 7;         // le celle della griglia vanno da -edge a edge
    public bool alive = true;
    public List<Transform> tail = new List<Transform>();
    private float timer;
    private Vector3 direction = Vector3.right;       // la direzione in cui si è mossa la testa nell'ultimo passo
    private Vector3 nextDirection = Vector3.right;   // la svolta in attesa del prossimo passo

    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;
        }

        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))
        {
            GameManager.Instance.Eat();
        }
    }

    void Die()
    {
        alive = false;
    }
}

Tutte le lezioni di Gioco Unity: Snake 3D

Esercitati da solo: Playground Unity