Snake

Curso de Unity 3D

20.  
23.  
25.  
39.  

1. Botón derecho en el panel de jerarquía→ 2D Object → Sprite.

2. Cargamos el sprite de un cuadradito blanco en el componente anterior.

3. Utilizamos el propio cuadrado para hacer los límites del area por el que s emoverá la serpiente.

Snake 1

4. Movimiento de la serpiente.

private void Start(){
    StartCoroutine(MoveCoroutine());
}

private void Move(){
    Vector3 nextPos = Vector3.up;
    transform.position += nextPos;
}

IEnumerator MoveCoroutine(){
    while (true){
      yield return new WaitForSeconds(0.5f);
      Move();
    }
}

5. Ajustamos la magnitud del movimiento de la serpiente a su tamaño.

float step;
...
step = GetComponent<SpriteRenderer>().bounds.size.x;
...
transform.position += nextPos * step;

6. Movemos la serpiente en función de las instrucciones del usuario:

enum Controls
{
    up,
    down,
    left,
    right
}

void Update(){
    if (Input.GetKeyDown(KeyCode.RightArrow)){
      controls = Controls.right;
    }
    ...

private void Move(){
    Vector3 nextPos = Vector3.zero;
    if (controls == Controls.left){
      nextPos = Vector3.left;
    }
    ...

7. Vamos a crear la cola de la serpiente. La cola de la serpiente será una lista de cuadrados que van siguiendo la posición de la cabeza. Para ello, almacenaremos la posición de la cabeza justo antes del movimiento en una variable llamada lastPos e iremos moviendo la cola a esa posición tras haber efectuado el movimiento de la cabeza.

public List<Transform> tail = new List<Transform>();
Vector3 lastPos;

private void Move(){
    lastPos = transform.position;// Posición de la cabeza antes de mover
    ...
    MoveTail();
}

void MoveTail(){
    for (int i = 0; i < tail.Count; i++){
      Vector3 temp = tail[i].position;
      tail[i].position = lastPos;
      lastPos = temp;
    }
}

Para probar este código:

  1. Duplicaremos varias veces la cabeza de la serpiente.
  2. Le eliminaremos el script a las cabezas duplicadas.
  3. Asignaremos estas cabezas duplicadas sin script a la propiedad tail de la cabeza.

8. La serpiente come y crece.

  1. Para que haya colisión entre dos objetos, al menos uno de los dos debe tener RigidBody. Normalmalmente, dicho RigidBody se añade al elemento que se mueve. Como hemos visto anteriormente, es recomendable que un GameObject en movimiento tenga RigidBody, ya que esto hace que el cálculo su correspondiente BoxCollider sea mucho más ligero. Por tanto, añadimos un RigidBody a la serpiente. Puesto que la serpiente no se verá afectada por las fuerzas externas (como la gravedad) usaremos un RigidBody con un Body Type Kinematic.
  2. Duplicamos el sprite de la cabeza de la serpiente.
  3. Le quitamos el script asociado.
  4. Le asociamos el Tag food.
  5. Lo guardamos como Prefab. Lo llamaremos food.
  6. Añadiremos la siguiente función al código de la serpiente para comprobar que se produce la colisión:
private void OnTriggerEnter2D(Collider2D collision){
    if (collision.gameObject.tag == "Food"){
      print("colision");
    }
  }
}

7. Ahora en lugar de la traza, un trozo de cola a la serpiente. Para ello, cambiaremos el valor de una variable booleana que gestiona cuando se ha producido la colisión con la comida.

...
if (collision.gameObject.tag == "Food"){
    growingPending = true;
}
...
void MoveTail(){
    ...
    if (growingPending) CreateTail();
}

void CreateTail(){
    GameObject newTail = Instantiate(tailPrefab, lastPos, Quaternion.identity);
    newTail.name = "Tail_" + tail.Count;
    tail.Add(newTail.transform);
    growingPending = false;
}

La variable lastPos almacena la posición del trozo de cola que se movió anteriormente. Cuando el bucle ha terminado de mover toda la cola, esa es la posición en la que queremos crear la nueva pieza de cola.

Al principio del juego, cuando sólo tenemos la cabeza de la serpiente, si hubiesemos añadido la cola en el momento de colisionar con la comida, este nuevo trozo de cola se habría creado encima de la cabeza, colisionando con ella. Por eso, debemos haber terminado de mover toda la cola para crear la nueva instancia.

8. Cada vez que la serpiente colisione contra la comida, la comida debe ser destruída y otra comida debe ser instanciada en otro lugar.

9. Cuando el jugador colisione contra los límites de la pantalla o contra su cola, debemos ir a la pantalla de GameOver.

Debemos reducir el BoxCollider del prefab de la cola, para que esta no colisione con la cabeza en el momento de su instanciación o cuando pasamos al lado. Lo mismo tendríamos que hacer con la comida, para no colisionar con ella cuando pasemos por al lado.

Snake 2
← Videojuego PONG con Unity 3D
Cambiar el punto de pivote →

Aviso Legal | Política de privacidad