Menu
CoddyTech

Grandir

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

En mangeant, le serpent gagne un segment. Le nouveau segment va à l’endroit où se trouvait l’extrémité de la queue avant le déplacement : la queue avance, et le nouveau segment occupe la case qu’elle vient de quitter ; le serpent grandit donc par l’arrière.

Cette case disparaît une fois la queue déplacée : mémorise-la donc d’abord. Ensuite, lorsque la tête a atteint la nourriture, instancie un segment à cet endroit et ajoute-le à la liste, afin qu’il suive le serpent dès le déplacement suivant. Un segment créé mais non ajouté ne bouge jamais. Un train ajoute un wagon à l’arrière de la même façon :

Vector3 back = wagons[wagons.Count - 1].position;
// ... le train continue d'avancer ...
Transform wagon = Instantiate(wagonPrefab, back, Quaternion.identity);
wagons.Add(wagon);

Fais grandir le serpent avant d’appeler Eat(). Eat() déplace la nourriture, et la prochaine leçon fera en sorte qu’elle cherche une case qui n’est pas occupée par le serpent, y compris le nouveau segment.

challenge icon

Défi

Moyen

Chaque aliment ajoute un segment à la queue.

  1. Dans Snake, ajoute public Transform segmentPrefab; (la scène le relie).
  2. Dans Step(), avant que la queue ne bouge, conserve Vector3 tailEnd : la case du dernier segment, ou celle de la tête lorsque la queue est vide.
  3. Lorsque le serpent mange, ajoute Instantiate(segmentPrefab, tailEnd, Quaternion.identity) à tail, puis appelle Eat().

Clique sur « Jouer » et mange quelques aliments : le serpent grandit d’un cube à chaque fois. Puis clique sur « Vérifier ».

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>();
    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;
        }

        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;
    }
}

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

Entraînez-vous par vous-même : Playground Unity