Menu
CoddyTech

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.

challenge icon

Wyzwanie

Średni

Jedzenie nigdy nie pojawia się na wężu.

  1. W Snake napisz public bool Occupies(Vector3 cell): zwraca true dla pola zajmowanego przez głowę lub dowolny segment ogona.
  2. W MoveFood() klasy GameManager wykonaj pętlę po x i z od -snake.edge do snake.edge, dodaj każde pole, dla którego !snake.Occupies(cell), do List<Vector3> free, a następnie umieść jedzenie na free[Random.Range(0, free.Count)].

Naciśnij „Graj” i wydłuż węża: jedzenie zawsze pojawia się na pustym polu. Następnie naciśnij „Sprawdź”.

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);
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Gra w Unity: Wąż 3D

Poćwicz samodzielnie: Edytor online Unity