Menu
CoddyTech

Không nằm trên thân rắn

Bài học 9 trên 14 trong khóa học Game Unity: rắn 3D của Coddy.

MoveFood() chọn bất kỳ ô nào, kể cả ô mà con rắn đang chiếm. Thức ăn nằm dưới thân rắn không thể bị ăn cho đến khi rắn di chuyển khỏi đó, và rắn càng dài thì việc này càng xảy ra thường xuyên.

Một cách khắc phục là chọn lại cho đến khi ô đó trống. Cách này hiệu quả khi bàn chơi còn trống, nhưng bàn chơi càng đầy thì càng phải thử nhiều lần, và nếu không còn ô trống thì quá trình sẽ không bao giờ kết thúc. Cách khắc phục ổn định là tạo danh sách các ô trống trước rồi chọn một ô trong số đó: mọi ô trống đều có khả năng được chọn như nhau, và chỉ cần chọn một lần. Rạp chiếu phim cũng xếp chỗ cho khách đến muộn theo cách tương tự:

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) trả về một chỉ số từ 0 đến chỉ số cuối cùng, vì giá trị tối đa không được tính. Để tạo danh sách, bàn chơi hỏi con rắn xem nó có chiếm một ô hay không: một phương thức trong Snake kiểm tra đầu và từng đoạn thân rắn.

challenge icon

Thử thách

Trung bình

Thức ăn không bao giờ xuất hiện trên rắn.

  1. Trong Snake, viết public bool Occupies(Vector3 cell): trả về true nếu ô đó là ô của đầu hoặc bất kỳ đoạn đuôi nào.
  2. Trong MoveFood() của GameManager, lặp x và z từ -snake.edge đến snake.edge, thêm mỗi ô mà !snake.Occupies(cell) trả về true vào List<Vector3> free, rồi đặt thức ăn tại free[Random.Range(0, free.Count)].

Nhấn Chơi và làm rắn dài ra: thức ăn luôn xuất hiện trên một ô trống. Sau đó nhấn Kiểm tra.

Tự làm thử

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 iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Game Unity: rắn 3D

Tự luyện tập: Playground Unity