Non sul serpente
Lezione 9 di 14 del corso Gioco Unity: Snake 3D di Coddy.
MoveFood() sceglie una qualsiasi cella, incluse quelle occupate dal serpente. Il cibo sotto il serpente non può essere mangiato finché il serpente non si sposta, e più il serpente è lungo, più spesso succede.
Una soluzione consiste nel riprovare finché la cella non è libera. Funziona su una griglia vuota, ma servono sempre più tentativi man mano che la griglia si riempie e, se non rimane nessuna cella libera, non finisce mai. La soluzione più affidabile consiste nel creare prima un elenco delle celle libere e sceglierne una: tutte le celle libere hanno la stessa probabilità di essere scelte e basta sempre un solo tentativo. Un cinema assegna un posto a un ospite in ritardo allo stesso modo:
List<int> free = new List<int>();
for (int seat = 1; seat <= 40; seat++)
{
if (!taken.Contains(seat)) free.Add(seat);
}
int pick = free[Random.Range(0, free.Count)];Random.Range(0, free.Count) restituisce un indice da 0 all'ultimo, poiché il valore massimo è escluso. Per creare l'elenco, la griglia chiede al serpente se occupa una cella: un metodo di Snake che controlla la testa e ogni segmento.
Sfida
MedioIl cibo non finisce mai sul serpente.
- In
Snake, scrivipublic bool Occupies(Vector3 cell): restituisce true per la cella della testa o per quella di qualsiasi segmento della coda. - In
GameManager, dentroMoveFood(), esegui un ciclo da-snake.edgeasnake.edgeper x e z, aggiungi ogni cella per cui!snake.Occupies(cell)a unaList<Vector3> freee posiziona il cibo sufree[Random.Range(0, free.Count)].
Premi «Gioca» e fai crescere il serpente: il cibo finirà sempre su una cella vuota. Poi premi «Verifica».
Provalo tu
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
public Snake snake;
public GameObject foodPrefab;
private Transform food;
private int score;
void Awake()
{
Instance = this;
}
void Start()
{
food = Instantiate(foodPrefab).transform;
MoveFood();
}
public bool IsFood(Vector3 cell)
{
return cell == food.position;
}
public void Eat()
{
score++;
MoveFood();
}
void MoveFood()
{
int x = Random.Range(-snake.edge, snake.edge + 1);
int z = Random.Range(-snake.edge, snake.edge + 1);
food.position = new Vector3(x, 0f, z);
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Gioco Unity: Snake 3D
Esercitati da solo: Playground Unity