Crescere
Lezione 8 di 14 del corso Gioco in 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
MedioLa scena imposta segmentPrefab di Snake su un cubo come quelli della coda.
- Aggiungi
public Transform segmentPrefab;. - In
Step(), prima che la coda si muova, conserva la cella dell'ultimo segmento della coda inVector3 tailEnd(la cella della testa quando la coda è vuota). - Quando la testa è sul cibo, istanzia
segmentPrefabsutailEnde aggiungilo atail, poi chiamaEat().
Premi Play e mangiane alcuni, poi premi Check.
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;
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.