Menu
CoddyTech

Muérdete a ti mismo

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

La serpiente muere cuando su cabeza choca contra su propia cola, igual que cuando choca contra una pared. La comprobación se realiza en el mismo lugar: en next, la celda de delante, antes de que la cabeza se mueva, así que la cabeza se queda donde está cuando termina el juego.

Un segmento es seguro. En este paso, el último segmento también se mueve hacia arriba, saliendo de su celda, así que una cabeza que sigue el extremo de su cola hasta esa celda nunca lo toca. Una serpiente de cuatro cubos puede dar vueltas eternamente alrededor de un cuadrado de 2 por 2 de esta manera. La comprobación deja fuera el último segmento al detenerse una posición antes del final:

// todos los elementos excepto el último
for (int i = 0; i < items.Count - 1; i++)
{
    Debug.Log(items[i].name);
}

Con las paredes y la cola como peligros mortales, se puede perder la partida, y el siguiente capítulo añade la puntuación y una forma de volver a jugar.

challenge icon

Desafío

Intermedio

En Step(), después de comprobar la pared: si next es la celda de cualquier segmento de la cola excepto el último, llama a Die() y devuelve el control, para que la cabeza no se mueva.

Pulsa Play, haz crecer la serpiente y muérdete la cola; 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 casillas del tablero van de -edge a edge
    public bool alive = true;
    public List<Transform> tail = new List<Transform>();
    public Transform segmentPrefab;
    private float timer;
    private Vector3 direction = Vector3.right;       // la dirección en la 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;
        }

        Vector3 tailEnd = tail.Count > 0 ? tail[tail.Count - 1].position : transform.position;
        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))
        {
            tail.Add(Instantiate(segmentPrefab, tailEnd, Quaternion.identity));
            GameManager.Instance.Eat();
        }
    }

    public bool Occupies(Vector3 cell)
    {
        if (transform.position == cell) return true;
        foreach (Transform segment in tail)
        {
            if (segment.position == cell) return true;
        }
        return false;
    }

    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