Nicht auf der Schlange
Lektion 9 von 14 im Kurs Unity-Spiel: 3D-Snake von Coddy.
MoveFood() wählt eine beliebige Zelle aus, auch Zellen, die von der Schlange bedeckt sind. Futter unter der Schlange kann erst gefressen werden, wenn die Schlange sich davon wegbewegt hat, und je länger die Schlange ist, desto häufiger kommt das vor.
Eine Lösung ist, so lange erneut eine Zelle auszuwählen, bis sie frei ist. Auf einem leeren Spielfeld funktioniert das, aber je voller das Spielfeld wird, desto mehr Versuche sind nötig, und wenn keine freie Zelle mehr übrig ist, endet es nie. Die zuverlässige Lösung erstellt zuerst eine Liste der freien Zellen und wählt eine davon aus: Jede freie Zelle ist gleich wahrscheinlich, und eine Auswahl genügt immer. Ein Kino weist einem verspäteten Gast auf dieselbe Weise einen Sitzplatz zu:
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) gibt einen Index von 0 bis zum letzten zurück, da der Höchstwert ausgeschlossen ist. Um die Liste zu erstellen, fragt das Spielfeld die Schlange, ob sie eine Zelle bedeckt: Dazu dient eine Methode in Snake, die den Kopf und jedes Segment überprüft.
Aufgabe
Mittel- Schreibe in
Snakepublic bool Occupies(Vector3 cell): true, wenncelldie Zelle des Kopfes oder die Zelle eines Schwanzsegments ist. - Füge in
GameManagerusing System.Collections.Generic;hinzu und schreibeMoveFood()um: Durchlaufe x und z für jede Zelle des Spielfelds, füge jede Zelle, die die Schlange nicht belegt, zu einerList<Vector3> freehinzu und platziere das Futter auf einer zufälligen Zelle dieser Liste.
Drücke Play und dann Check. Bei den Prüfungen wird der größte Teil des Spielfelds mit der Schlange gefüllt und sichergestellt, dass das Futter weiterhin die freien Zellen findet.
Probier es selbst
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);
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.