Está en la página 1de 7

EXPLICACIÓN DE CODIGO

Lo primero que vamos a intentar es que se deslice la serpiente por la matriz. Para esto,
comenzamos colocando un punto en la matriz de 8X8, necesitamos incluir la
biblioteca LedControl.h
#include "LedControl.h"

Generamos un objeto denominado lc, que nos va a permitir controlar la matriz:

LedControl lc = LedControl(11, 13, 10, 1);

Nuestro siguiente paso, es dibujar un punto en la matriz, encendemos el LED de la fila 1,


columna 1, lo que corresponde con las coordenadas [0,0]:
void setup() {
lc.shutdown(0, false);
lc.setIntensity(0, 8);
lc.clearDisplay(0); // limpiar la matriz
}

void loop() {
lc.setLed(0, 0, 0, true);
}

En la función setup(), habilitamos la matriz con shutdown(), seguidamente indicamos el nivel


de intensidad con setIntensity() y limpiamos la matriz con clearDisplay().

En la función loop(), indicamos que encienda un LED con la función setLed(), donde los valores
son el nº de dispositivos, la fila, la columna y si está encendido el LED (true) o apagado (false).

Si subimos el programa, ya nos enciende un punto, vamos a intentar que se mueva en la


vertical, para esto vamos a necesitar añadir dos array con las posibles posiciones de los LED
tanto para el eje x como para el eje y. Los añadimos justo debajo de LedControl lc =
LedControl(11, 13, 10, 1):
int serpiente_X[36];
int serpiente_Y[36];

En la función loop(), borramos la línea «lc.setLed(0, 1, 2, true)» que nos encendía el LED de la
fila 1 y ponemos lo siguiente:
lc.clearDisplay(0);
if (serpiente_Y[0] == 0) {
serpiente_Y[0] = 7;
} else {
serpiente_Y[0]--;
}
for (int i = 0; i < 1; i++) {
lc.setLed(0, serpiente_Y[i], serpiente_X[i], true);
}
delay(300);
Como ya sabemos la función loop() es la que se repite continuamente, primero, volvemos a limpiar
la pantalla borrándolo todo. En el primer if, mantenemos los valores entre 0 y 7, esta acción
comprueba si y es igual a 0, en ese caso lo pasa a 7, si es diferente a 0, le va restando uno. Así, y
siempre tendrá un valor entre 0 y 7.

Lo siguente, es encender el LED correspondiente, lo hacemos con el bucle for, si nos fijamos irá
encendiendo el LED de las coordenadas [0,7], [0,6], [0,5], [0,4], [0,3], [0,2], [0,1] y [0,0].

y por último, colocamos un delay(), para que la velocidad de cambio no sea muy rápida. El código
completo que llevamos desarrollado hasta ahora, es:
#include "LedControl.h"

LedControl lc = LedControl(11, 13, 10, 1);

int serpiente_X[36]; // son 36 las posibles posiciones en pantalla para el eje x


int serpiente_Y[36]; // son 36 las posibles posiciones en pantalla para el eje y

void setup() {
lc.shutdown(0, false);
lc.setIntensity(0, 8);
lc.clearDisplay(0); // limpiar la matriz
}

void loop() {
lc.clearDisplay(0);

if (serpiente_Y[0] == 0) {
serpiente_Y[0] = 7;
} else {
serpiente_Y[0]--;
}

for (int i = 0; i < 1; i++) {


lc.setLed(0, serpiente_Y[i], serpiente_X[i], true); // (nº dispositivo, fila, columna, valor)
}

delay(300);
}

Ahora vamos a intentar que funcione el joystick para poder mover el punto hacia la derecha o
izquierda. Necesitamos añadir las siguientes variables debajo de la línea «LedControl lc =
LedControl(11, 13, 10, 1);»:

int joy_Pin1 = A0;


int joy_Pin2 = A1;
int eje_x = 0;
int eje_y = 0;

String direccion = "arriba";

En la primera, joy_Pin1 indicamos en qué pin vamos a realizar la lectura del eje x del joystick;
joy_Pin2, es para el eje y. Las variables eje_x y eje_y, son para guardar la lectura y hacer nuestras
comprobaciones de hacia dónde está desplazando el jugador la palanca del joystick. Y direccion, es
la varible que guarda hacia dónde se mueve la serpiente.

En la función loop(), añadimos justo debajo de «lc.clearDisplay(0);»:


eje_x = analogRead(joy_Pin1);
eje_y = analogRead(joy_Pin2);

Estas dos nuevas líneas leerán los valores del joystick, del eje x e y. Lo siguiente que tenemos que
hacer, es comprobar hacia dónde se mueve la palanca:

if (eje_y >= 0 && eje_y < 480) {


direccion = "arriba";
}
if (eje_y > 520 && eje_y <= 1023) {
direccion = "abajo";
}
if (eje_x >= 0 && eje_x < 480) {
direccion = "izquierda";
}
if (eje_x > 520 && eje_x <= 1023) {
direccion = "derecha";
}

Arduino nos dará lecturas entre 0 y 1023, sabiendo que la mitad es 512, podemos averiguar si se está
moviendo la palanca hacia la izquierda, la derecha, hacia arriba o hacia abajo. Una vez que tenemos
la dirección, vamos a ver qué LEDs son los que se encienden:

if (direccion == "arriba") {
if (serpiente_Y[0] == 0) {
serpiente_Y[0] = 7;
} else {
serpiente_Y[0]--;
}
} else if (direccion == "abajo") {
if (serpiente_Y[0] == 7) {
serpiente_Y[0] = 0;
} else {
serpiente_Y[0]++;
}
} else if (direccion == "izquierda") {
if (serpiente_X[0] == 0) {
serpiente_X[0] = 7;
} else {
serpiente_X[0]--;
}
} else if (direccion == "derecha") {
if (serpiente_X[0] == 7) {
serpiente_X[0] = 0;
} else {
serpiente_X[0]++;
}
}

Con el código anterior, lo único que hacemos es comprobar hacia qué dirección nos estamos
moviendo, y asegurarnos de que no desaparece por los bordes, es decir, que la serpiente aparecerá
por el otro lado.

En el juego real la serpiente no puede volver sobre sus pasos, ¿cómo lo evitamos? Por ejemplo,
nos estamos desplazando hacia arriba y queremos evitar que se pueda mover hacia abajo. El
código actual dice:
if (eje_y > 520 && eje_y <= 1023) {
direccion = "abajo";
}

A ese fragmento de código, le añadimos una pequeña comprobación para evitar el movimiento
hacia abajo, con un if. El código queda entonces así:
if (eje_y > 520 && eje_y <=1023) {
if (direccion != "arriba") direccion = "abajo";
}

Hacemos esta misma operación para las otras tres direcciones.

Recordad que la serpiente conforme va alimentándose crece, por lo que necesitamos una variable
para la longitud de la serpiente y que colocaremos justo antes de comenzar la función setup():

int longitudSerpiente = 1;

También debemos cambiar en la función loop() este trozo de código:

for (int i = 0; i < 1; i++) {


lc.setLed(0, serpiente_Y[i], serpiente_X[i], true); // (nº dispositivo, fila, columna, valor)
}

Por este otro:

for (int i = 0; i < longitudSerpiente; i++) {


lc.setLed(0, serpiente_Y[i], serpiente_X[i], true); // (nº dispositivo, fila, columna, valor)
}

1 lo cambiamos por la variable longitudSerpiente para que nos encienda los LEDs necesarios en
la matriz. Además, también necesitamos que todos los nuevos LEDs se muevan detrás del
primer LED. Si probáis a subir el código comprobaréis que solamente se mueve el primer LED.
Para conseguir ese efecto, añadimos:
for (int i = longitudSerpiente - 1; i > 0; i--) {
serpiente_X[i] = serpiente_X[i - 1];
serpiente_Y[i] = serpiente_Y[i - 1];
}

Con esto vamos a conseguir que la cola vaya creciendo y se desplace detrás de la cabeza de la
serpiente. Se trata de un for que prepara los LEDs que se deben encender según la longitud de la
serpiente. La función loop() queda ahora de la siguente forma:

void loop() {
lc.clearDisplay(0);

eje_x = analogRead(joy_Pin1);
eje_y = analogRead(joy_Pin2);
// en que dirección nos movemos?
if (eje_y >= 0 && eje_y <480) {
if (direccion != "abajo") direccion = "arriba";
}
if (eje_y > 520 && eje_y <=1023) {
if (direccion != "arriba") direccion = "abajo";
}
if (eje_x >= 0 && eje_x <480) {
if (direccion != "derecha") direccion = "izquierda";
}
if (eje_x > 520 && eje_x <=1023) {
if (direccion != "izquierda") direccion = "derecha";
}

for (int i = longitudSerpiente - 1; i > 0; i--) {


serpiente_X[i] = serpiente_X[i - 1];
serpiente_Y[i] = serpiente_Y[i - 1];
}

if (direccion == "arriba") {
if (serpiente_Y[0] == 0) {
serpiente_Y[0] = 7;
} else {
serpiente_Y[0]--;
}
} else if (direccion == "abajo") {
if (serpiente_Y[0] == 7) {
serpiente_Y[0] = 0;
} else {
serpiente_Y[0]++;
}
} else if (direccion == "izquierda") {
if (serpiente_X[0] == 0) {
serpiente_X[0] = 7;
} else {
serpiente_X[0]--;
}
} else if (direccion == "derecha") {
if (serpiente_X[0] == 7) {
serpiente_X[0] = 0;
} else {
serpiente_X[0]++;
}
}

for (int i = 0; i < longitudSerpiente; i++) {


lc.setLed(0, serpiente_Y[i], serpiente_X[i], true); // (nº dispositivo, fila, columna, valor)
}

delay(300);
}

En el siguiente paso haremos aparezcer el LED que simula la comida y que nuestra serpiente
debe zamparse. Necesitamos dos nuevas variables para posicionar la comida que situamos
justo antes de comenzar la función setup():
int comida_X;
int comida_Y;

Queremos que se posicione en unas coordenadas aleatorias, por lo que dentro de la función
setup() colocaremos al final:
comida_X = random(0, 8);
comida_Y = random(0, 8);

Estas dos últimas líneas nos generan unas coordenadas aleatorias para la fila y la columna
entre 0 y 7. Solo nos queda encender el LED que hará de comida, dentro de la función loop(),
entre el for que nos dibuja la serpiente y el delay(300), colocamos el código:
// dibujar la comida
if (serpiente_X[0] == comida_X && serpiente_Y[0] == comida_Y){
// si coincide la cabeza de la serpiente con la comida, es que se la ha comido y crece un LED
longitudSerpiente++;
// nueva posición
comida_X = random(0, 8);
comida_Y = random(0, 8);
}
lc.setLed(0, comida_Y, comida_X, true);
delay(50); // haremos que parpadee
lc.setLed(0, comida_Y, comida_X, false);

En el if, comprobamos si la cabeza de la serpiente coincide con la posición de la comida, en caso


afirmativo, significa que se lo ha comido, por lo que aumentamos la longitud de la serpiente y
generamos unas nuevas coordenadas para una nueva comida. Seguidamente, encendemos el LED y
añadimos un delay para proceder a apagar el LED, con esto conseguiremos que parpadee.

Podemos probar el código ahora y veremoss que en el momento que comemos, la longitud de la
serpiente aumenta.

El siguente paso, va a consistir en comprobar que la serpiente no choca consigo misma, para esto
colocamos el siguiente código dentro de la función loop(), antes del delay(300):

for (int i = 1; i < longitudSerpiente; i++) {


if (serpiente_X[0] == serpiente_X[i] && serpiente_Y[0] == serpiente_Y[i]) {
fin = true;
}
}

En estas líneas tenemos un bucle for para recorrer las coordenadas del cuerpo de la serpiente, y
dentro un if comparando las coordenadas x (serpiente_X[0]) e y (serpiente_Y[0]) de la posición de la
cabeza, con las coordenadas x (serpiente_X[i]) e y (serpiente_Y[i]) de los puntos del cuerpo. En el
for tenemos i = 1, la primera posición, es la de la cabeza de la serpiente. Cargamos el juego y
comprobamos si se termina cuando impacta la serpiente contra sí misma. El juego acaba con la
variable denominada fin que pasa a estado verdadero, y que al principio hemos declarado como
boleana y con valor false.

boolean fin = false;

Nos queda poner todo el contenido de la función loop() dentro de un if, de la siguiente forma:

void loop() {
lc.clearDisplay(0);
if(!fin){
...
...
}
}

De esta forma cuando termina la partida, la pantalla quedará limpia.

Nos falta indicar cómo comenzar una nueva partida. Para ello, presionaremos el botón del joystick.
Tenemos que indicar qué pin es el que está conectado al botón del joystick, justo debajo de la línea
LedControl lc = LedControl(11, 13, 10, 1);

const int boton_inicio = 2;

Al final del if de la función loop() que hemos creado en el paso anterior, añadimos:
}else{
Serial.println("game over");
if(digitalRead(boton_inicio)==0){
Serial.println("Nueva");
// Inicializar otra vez
// comida
comida_X = random(0, 8);
comida_Y = random(0, 8);
// posición inicial
eje_x = 0;
eje_y = 0;
// longitud
longitudSerpiente = 1;
// dirección
direccion = "arriba";

fin = false;
}

Con el if comprobamos si se presiona el botón del joystick, si es el caso, inicializamos la


posición del LED de la comida. Reinicializamos la posición de la serpiente donde la longitud de
ésta vuelve a ser 1 y la dirección, hacia arriba. Por último, indicamos la variable fin como false.

También podría gustarte