Pas sur le serpent
Leçon 9 sur 14 du cours Jeu Unity : Snake 3D de Coddy.
MoveFood() choisit n’importe quelle case, y compris celles occupées par le serpent. La nourriture sous le serpent ne peut pas être mangée tant que le serpent ne s’en est pas éloigné, et plus le serpent est long, plus cela se produit souvent.
Une solution consiste à choisir à nouveau jusqu’à ce que la case soit libre. Cela fonctionne sur un plateau vide, mais il faut de plus en plus d’essais à mesure que le plateau se remplit, et s’il ne reste aucune case libre, la boucle ne se termine jamais. La solution fiable consiste d’abord à créer une liste des cases libres, puis à en choisir une : chaque case libre a la même probabilité d’être choisie, et un seul tirage suffit toujours. Un cinéma place un spectateur arrivé en retard de la même façon :
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) renvoie un indice de 0 jusqu’au dernier, car la valeur maximale est exclue. Pour créer la liste, le plateau demande au serpent s’il occupe une case : une méthode de Snake vérifie la tête et chaque segment.
Défi
Moyen- Dans
Snake, écrispublic bool Occupies(Vector3 cell): vrai lorsquecellest la case de la tête ou celle d’un segment de la queue. - Dans
GameManager, ajouteusing System.Collections.Generic;et réécrisMoveFood(): parcours x et z sur toutes les cases du plateau, ajoute chaque case que le serpent n’occupe pas à uneList<Vector3> free, puis place la nourriture sur une case aléatoire de cette liste.
Appuie sur Play, puis sur Check. Les vérifications remplissent la majeure partie du plateau avec le serpent et s’assurent que la nourriture trouve toujours les cases libres.
Essayez vous-même
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);
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.