Nie na wężu
Lekcja 9 z 14 w kursie Gra w Unity: Wąż 3D w Coddy.
MoveFood() wybiera dowolne pole, w tym pola zajmowane przez węża. Jedzenia pod wężem nie można zjeść, dopóki wąż się z niego nie przesunie, a im dłuższy jest wąż, tym częściej się to zdarza.
Jednym z rozwiązań jest ponawianie losowania, aż pole będzie wolne. Działa to na pustej planszy, ale im bardziej plansza się zapełnia, tym więcej prób potrzeba, a gdy nie zostanie już żadne wolne pole, losowanie nigdy się nie kończy. Niezawodne rozwiązanie polega na wcześniejszym utworzeniu listy wolnych pól i wybraniu jednego z nich: każde wolne pole ma takie samo prawdopodobieństwo, a jedno losowanie zawsze wystarczy. W kinie spóźnionemu widzowi przydziela się miejsce w ten sam sposób:
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) zwraca indeks od 0 do ostatniego indeksu, ponieważ górna granica nie jest uwzględniana. Aby utworzyć listę, plansza pyta węża, czy zajmuje dane pole: robi to metoda klasy Snake, która sprawdza głowę i każdy segment.
Wyzwanie
Średni- W
Snakenapiszpublic bool Occupies(Vector3 cell): zwraca true, gdycelljest polem głowy lub polem segmentu ogona. - W
GameManagerdodajusing System.Collections.Generic;i przepiszMoveFood(): wykonaj pętle po x i z dla każdego pola planszy, dodaj każde pole, którego wąż nie zajmuje, doList<Vector3> freei umieść jedzenie na losowym polu z tej listy.
Naciśnij Play, a następnie Check. Testy zapełniają wężem większość planszy i sprawdzają, czy jedzenie nadal znajduje wolne pola.
Spróbuj swoich sił
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);
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.