Menu
CoddyTech

No en la serpiente

Lección 9 de 14 del curso Juego de Unity: Snake 3D de Coddy.

MoveFood() elige cualquier celda, incluidas las celdas que ocupa la serpiente. La comida debajo de la serpiente no se puede comer hasta que la serpiente se aparte de ella, y cuanto más larga sea la serpiente, más a menudo ocurre.

Una solución es volver a elegir hasta que la celda esté libre. Funciona en un tablero vacío, pero hacen falta cada vez más intentos a medida que se llena el tablero y, cuando ya no quedan celdas libres, nunca termina. La solución estable primero crea una lista de las celdas libres y elige una: todas las celdas libres tienen la misma probabilidad de ser elegidas y siempre basta con una elección. En un cine se asigna un asiento a un invitado que llega tarde de la misma manera:

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) devuelve un índice de 0 al último, ya que el valor máximo queda excluido. Para crear la lista, el tablero le pregunta a la serpiente si ocupa una celda: un método de Snake que comprueba la cabeza y cada segmento.

challenge icon

Desafío

Intermedio
  1. En Snake, escribe public bool Occupies(Vector3 cell): verdadero cuando cell es la celda de la cabeza o la de un segmento de la cola.
  2. En GameManager, añade using System.Collections.Generic; y reescribe MoveFood(): recorre x y z por cada celda del tablero, añade cada celda que la serpiente no ocupe a una List<Vector3> free y coloca la comida en una celda aleatoria de esa lista.

Pulsa Play y después pulsa Check. Las comprobaciones llenan la mayor parte del tablero con la serpiente y se aseguran de que la comida siga encontrando las celdas libres.

Pruébalo tú mismo

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 iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Juego de Unity: Snake 3D