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.
Sfida
MedioOgni cibo aggiunge un segmento alla coda.
- In
Snake, aggiungipublic Transform segmentPrefab;(la scena lo collega). - In
Step(), prima che la coda si muova, conservaVector3 tailEnd: la cella dell'ultimo segmento oppure quella della testa quando la coda è vuota. - Quando mangi del cibo, aggiungi
Instantiate(segmentPrefab, tailEnd, Quaternion.identity)atail, poi chiamaEat().
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