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.
Défi
MoyenDans 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;
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.