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
MittelDas Futter landet nie auf der Schlange.
- Schreibe in
Snakepublic bool Occupies(Vector3 cell): true für das Feld des Kopfes oder eines beliebigen Schwanzsegments. - Durchlaufe in
GameManagersMoveFood()x und z von-snake.edgebissnake.edge, füge jede Zelle, für die!snake.Occupies(cell)gilt, zu einerList<Vector3> freehinzu und platziere das Futter auffree[Random.Range(0, free.Count)].
Drücke auf „Spielen“ und lass die Schlange länger werden: Das Futter landet immer auf einem leeren Feld. Drücke anschließend auf „Prüfen“.
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.
Alle Lektionen in Unity-Spiel: 3D-Snake
Übe selbstständig: Unity-Playground