Menu
CoddyTech

Se mordre la queue

Leçon 10 sur 14 du cours Jeu Unity : Snake 3D de Coddy.

Le serpent meurt lorsque sa tête rencontre sa propre queue, comme lorsqu’elle rencontre un mur. Le test se fait au même endroit : sur next, la case devant lui, avant que la tête ne bouge, afin qu’elle reste où elle est lorsque la partie se termine.

Un segment est sans danger. À cette étape, le dernier segment avance lui aussi, quittant sa case ; ainsi, une tête qui suit l’extrémité de sa queue jusque dans cette case ne le touche jamais. Un serpent de quatre cubes peut ainsi tourner indéfiniment autour d’un carré de 2 sur 2. Le test exclut le dernier segment en s’arrêtant juste avant la fin :

// tous les éléments sauf le dernier
for (int i = 0; i < items.Count - 1; i++)
{
    Debug.Log(items[i].name);
}

Avec les murs et la queue tous deux mortels, il est possible de perdre la partie ; le chapitre suivant ajoute le score et un moyen de rejouer.

challenge icon

Défi

Moyen

Dans Step(), après le test du mur : si next est la cellule de n’importe quel segment de la queue sauf le dernier, appelle Die() et retourne, afin que la tête ne bouge pas.

Appuie sur Play, fais grandir le serpent et mords-toi la queue, puis appuie sur Check.

Essayez vous-même

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

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // secondes entre deux déplacements
    public int edge = 7;         // les cases du plateau vont de -edge à edge
    public bool alive = true;
    public List<Transform> tail = new List<Transform>();
    public Transform segmentPrefab;
    private float timer;
    private Vector3 direction = Vector3.right;       // la direction dans laquelle la tête s’est déplacée lors du dernier pas
    private Vector3 nextDirection = Vector3.right;   // le changement de direction en attente du prochain pas

    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 iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Jeu Unity : Snake 3D