Menu
CoddyTech

Crecer

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

Al comer, la serpiente crece un segmento. El nuevo segmento aparece donde estaba el extremo de la cola antes del movimiento: la cola avanza y el nuevo segmento ocupa la celda que ha dejado libre el extremo, así que la serpiente crece por detrás.

Esa celda desaparece cuando la cola se ha movido, así que recuérdala primero. Después, cuando la cabeza haya llegado a la comida, instancia un segmento allí y añádelo a la lista para que empiece a seguirla en el siguiente movimiento. Un segmento que se crea pero no se añade nunca se mueve. Un tren añade un vagón por detrás de la misma manera:

Vector3 back = wagons[wagons.Count - 1].position;
// ... el tren sigue avanzando ...
Transform wagon = Instantiate(wagonPrefab, back, Quaternion.identity);
wagons.Add(wagon);

Haz crecer la serpiente antes de llamar a Eat(). Eat() mueve la comida y, en la siguiente lección, haremos que busque una celda que la serpiente no ocupe, incluido el nuevo segmento.

challenge icon

Desafío

Intermedio

La escena establece segmentPrefab de Snake como un cubo, igual que la cola.

  1. Añade public Transform segmentPrefab;.
  2. En Step(), antes de que se mueva la cola, guarda la celda del último segmento de la cola en Vector3 tailEnd (la celda de la cabeza cuando la cola está vacía).
  3. Cuando la cabeza esté sobre la comida, instancia segmentPrefab en tailEnd y añádelo a tail; después llama a Eat().

Pulsa Play y come unos cuantos, después pulsa Check.

Pruébalo tú mismo

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // segundos entre dos pasos
    public int edge = 7;         // las celdas del tablero van de -edge a edge
    public bool alive = true;
    public List<Transform> tail = new List<Transform>();
    private float timer;
    private Vector3 direction = Vector3.right;       // la dirección en que se movió la cabeza en su último paso
    private Vector3 nextDirection = Vector3.right;   // el giro pendiente para el siguiente paso

    void Update()
    {
        if (!alive) return;

        Keyboard keyboard = Keyboard.current;
        if (keyboard != null)
        {
            if (keyboard.upArrowKey.wasPressedThisFrame || keyboard.wKey.wasPressedThisFrame) Turn(Vector3.forward);
            if (keyboard.downArrowKey.wasPressedThisFrame || keyboard.sKey.wasPressedThisFrame) Turn(Vector3.back);
            if (keyboard.leftArrowKey.wasPressedThisFrame || keyboard.aKey.wasPressedThisFrame) Turn(Vector3.left);
            if (keyboard.rightArrowKey.wasPressedThisFrame || keyboard.dKey.wasPressedThisFrame) Turn(Vector3.right);
        }

        timer += Time.deltaTime;
        if (timer >= tick)
        {
            timer -= tick;
            Step();
        }
    }

    void Turn(Vector3 newDirection)
    {
        if (newDirection != -direction)
        {
            nextDirection = newDirection;
        }
    }

    void Step()
    {
        direction = nextDirection;
        Vector3 next = transform.position + direction;
        if (Mathf.Abs(next.x) > edge || Mathf.Abs(next.z) > edge)
        {
            Die();
            return;
        }

        for (int i = tail.Count - 1; i > 0; i--)
        {
            tail[i].position = tail[i - 1].position;
        }
        if (tail.Count > 0)
        {
            tail[0].position = transform.position;
        }
        transform.position = next;

        if (GameManager.Instance.IsFood(next))
        {
            GameManager.Instance.Eat();
        }
    }

    void Die()
    {
        alive = false;
    }
}
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