julian alvarez / Mbed 2 deprecated METRIX_2

Dependencies:   mbed

Fork of METRIX_revision by julian alvarez

You are viewing an older revision! See the latest version

2 Entrega tetris

JUEGO TETRIS EN UNA MATRIZ LED 8x8

/media/uploads/jiuk/inicio.png


Este espacio virtual tiene como fin explicar de manera fácil, rápida y sencilla el funcionamiento, conexión y programación de un juego llamado tetris en una matriz led 8x8 programada con una tarjeta de desarrollo.


OBJETIVOS:

  • Conocer el funcionamiento básico y programación de un núcleo de desarrollo, en este caso el NUCLEO-F446RE.
  • Aplicar conocimientos previamente aprendidos de la programación en c.
  • Desarrollar el modelo de tetris basándose en arreglos y matrices que permitan la visualización dinámica del juego.

MATERIALES:

/media/uploads/jiuk/nucleo.png

  • Nucleo STM
    • Jumpers
    • Cacle de datos
  • Matriz LED 8x8
    • con integrado MAX 7219

INTEGRANTES:

  • Cristhian Santos
  • Julián Álvarez

PARA EMPEZAR

Un tetris es un juego de categoría “puzzle” en dos dimensiones cuyo fin es organizar ciertos polinomios diseñados de manera que puedan ser organizados sin que existan espacios entre uno y otro, esto con el fin de completar una fila para que esta sea eliminada y caigan los restos de polinomios que se encontraban en la parte superior para continuar con la misma dinámica, el objetivo es eliminar la mayor cantidad de líneas y evitar que se forme una torre que llegue a llenar el tamaño permitido de columnas, en dado caso se perderá el juego. Para nuestro caso desarrollaremos el juego en una matriz de led de 8x8 (es decir contara con 8 filas y 8 columnas) controlada por un integrado max7912 que facilita el manejo de la matriz, esta matriz será el espacio donde se desarrollara el juego, las piezas las enviaremos por comunicación serial entre la tarjeta y el computador asumiendo 3 valores que serán: número de pieza, grados que gira cada pieza y finalmente la columna en donde se desea que se desplace cada pieza, estos datos estarán en medio de caracteres “<” “>” que indicaran las diferentes características entre una pieza y otra, se debe tener en cuenta que solo se enviara una línea de caracteres que contendrá todos los datos de las piezas que se desean enviar y el programa debe ser capaz de enviar dichas piezas una por una.


CREACIÓN GRÁFICA DEL JUEGO:

/media/uploads/jiuk/creacion_grafica.png

Iniciamos presentando la matriz matriz8x8 controlada por el integrado7912, este integrado tiene como fin facilitar el manejo de las filas y columnas de la matriz ya que viene configurado para que con solo enviarle dos códigos hexadecimales este sea capaz de manejar filas y columnas de manera muy sencilla, adicionalmente cuenta con configuración adicional tal como brillo, test, cantidad de columnas a utilizar entre otras.


PIEZAS:

Para la creación de las piezas recurrimos a crear cada una de ellas dentro de una matriz más pequeña de 3x4 que nos facilitara mucho el manejo de ellas a la hora de desplazarlas por las filas, las columnas y realizarle giros a cada pieza, esto debido a que encontramos cierta repetitividad en la creación de cada una de ellas, es decir estaban formadas por 1 2 y máximo 3 líneas continuas por ejemplo para el cuadrado encontramos que las 2 primeras columnas en código binario serian ceros mientras que las siguientes serian dos unos para cada línea dando forma al cuadro de la siguiente forma:

0 0 0
0 0 0
1 1 0
1 1 0

Esto en codigo binario y dentro de nuestra matriz 3x4 representara un cuadro que iluminara 4 leds en nuestra interfaz (cada “1” significa un led prendido). El objetivo es crear un registro de desplazamiento entre cada pieza enviada a la tarjeta y que cree la ilusion visual de que la pieza va desplazandose columna por columna hasta llegar a la parte inferior de la amtriz de leds, adicionalmente debemos realizar el juego de matrices para que al ubicar una pieza una sobre otra o una al lado de otra se siga manteniendo la ilusion visual que de una dinamica entretenida y realista al juego (esto se explicara en la seccion del codigo de programación).

/media/uploads/jiuk/piezas.png


FUNCIONAMIENTO DEL PROGRAMA:

El juego esta diseñado para que el usuario por medio del programa CoolTerm le envie a la tarjeta de desarrollo por codigo ASCII el valor de las teclas de dirrección (arriba,abajo,izquierda y derecha), estas son re cibidas por una funcion que según la tecla oprimida realizara diferentes acciones de la siguiente forma:

  • Arriba: Gira 90 grados la pieza.
  • Abajo: Desciende mas rápido cada pieza.
  • Derecha e izquierda: Mueve la pieza de derecha a izquierda según el caso.

    /media/uploads/jiuk/grados.png


EXPLICACIÓN DEL CODIGO:

El codigo es desarrollado OnLine por medio de la plataforma MBed y se basa en programación C, a continuación se especifica el funcionamiento del codigo con el que se desarrollo el proyecto.

  • Encabezados .h: Se creo un encabezado .h (moggo.h) en el se creo el arreglo de 6 casillas que contiene la informacion de cada pieza como se explico en el apartado “piezas”, este contiene todas las posibles combinaciones que dan forma a las diferentes piezas que se utilizaran durante el juego.

#ifndef MOGGO_H
#define MOGGO_H

#include "mbed.h"

#define ALL_TYPE 1

 uint8_t FIG_ALL[7]={0b10000000,0b11000000,0b11100000,0b01000000,0b01100000,0,0b00100000};
#endif
}


  • Incluir librerias, definir pines de salida y definir velocidad:
    Se incluyeron las librerias mbed.h que contiene la informacion de cada tarjeta de desarrollo y la librería moggo.h que como se explico anteriormente contiene la información de cada pieza, tambien se definen los pines con los que se va a realizar la conexión entre la tarjeta y la amtriz de led con su integrado MAX, se habilita la comunicación serial por puerto USB en la 8va linea del codigo y se define una variable llamada vel que se encargara de realizar los Delays dentro del programa.

SPI deviceM(PB_15, PB_14, PB_13);
DigitalOut ssel (PB_12);  
Serial command(USBTX,USBRX);      
Serial com_tar(PC_10,PC_11);        

#define  VEL 30   


La conexión entre la tarjeta y el Max se realiza de la siguiente forma:
/media/uploads/jiuk/max.jpg

  • Función sendSPI():
    Se encarga de enviar la información codificada en hexadecimal de los leds que deben prender entre filas y columnas, se bloquea y desbloquea en cada envío de datos para evitar ruidos durante la transmisión de datos

void sendSPI(uint8_t d1, uint8_t d2)
{
    deviceM.unlock();
    ssel=0;
    deviceM.write(d1); 
    deviceM.write(d2);
    ssel=1;
    deviceM.lock();
}


  • Función test();
    Se encarga de realizar la configuración básica del integrado MAX, el primer comando ingresa al tipo de configuración que se desea cambiar y el segundo es el valor de configuración para cada aspecto (para mayor información busque el datashet del integrado).

void test()                 
{
    sendSPI(0x09,0);        //no decodificacion
    sendSPI(0x0A,0x00);     //intensidad
    sendSPI(0x0B,0x07);     //usa 7 leds                     
    sendSPI(0x0C,1);        //no apaga
    sendSPI(0x0F,0);        //operacion normal     
}


  • Función cop_mat();
    Esta función se encarga de copiar los datos de las figuras que llegan y determinar el rango de copiado de acuerdo a los valores del límite de impresión.

void cop_mat(uint8_t a,uint8_t b,uint8_t c,uint8_t* fig,uint8_t columna)
{       
        if(((mat_act[cont-2]& (*(fig+c)>>columna-1))==0)&&((mat_act[cont-1]& (*(fig+b)>>columna-1))==0)&&((mat_act[cont]& (*(fig+a)>>columna-1))==0)){
                    mat_tmp[0]= *(fig+5)>>columna-1;             
                    mat_tmp[1]= *(fig+a)>>columna-1;           
                    mat_tmp[2]= *(fig+b)>>columna-1;
                    mat_tmp[3]= *(fig+c)>>columna-1;
            }
}


  • Función borrar():
    Se encarga de enviar en código binario ceros a toda la matriz, es decir apagara todos los leds que se encontraran prendidos antes de la función.

void borrar()          
{
    int i;
    for(i=0;i<=8;i++)
    {
        sendSPI(i,0);
        mat_act[i]=0;   
    }
};


  • Función buscar_fil():
    Esta función realiza un escaneo de la matriz impresa en pantalla (por decirlo de una forma simple) Cuando encuentra algún dato escrito realiza una comparación para determinar hasta donde puede bajar la nueva figura, el proceso se repite cada vez que baja una nueva figura.

void buscar_fil(){
    for (uint8_t i=0;i<9;i++){                     
        if((mat_act[i]& mat_tmp[3])==0){
        fila=i;
        }
        if((mat_act[i]& mat_tmp[3])!=0){
        fila=i-1;                            
        i=9;
        }
        if((mat_act[i]& mat_tmp[2])!=0){            
        fila=i;                                  
        i=9;
        }
        if((mat_act[i]& mat_tmp[1])!=0){
        fila=i+1;                                  
        i=9;
        }
    }
    if(fila>8)
        fila=8;
    if(fila<=0){
        wait_ms(VEL);
        borrar();
        fila=8;
    }
    command.printf("\n buscar fila \n %d",fila);
    command.printf("\n ******************************* \n ");
};


  • Función guardar_mat():
    Guarda las figuras que entran en la matriz, para esto identifica el sector en el que cae la figura y actualiza en la matriz esta información.

void guardar_mat(){
        mat_act[fila-3]=mat_tmp1[0];
        mat_act[fila-2]=mat_tmp1[1];
        mat_act[fila-1]=mat_tmp1[2];
        mat_act[fila  ]=mat_tmp1[3];
        };


  • Función dibujar():
    Para esta función utilizamos 3 matrices dos de ella nos sirven para sobrescribir la tercera, y finalmente esta tercera es la que nos mostrara las figuras cayendo, siempre está realizando una suma binaria de esta forma garantiza no sobrescribir datos innecesariamente afectando el proceso del programa.

void dibujar(char type_fig,char grados,char columna)
{    
    switch (type_fig){                                
        case 1: if(columna>7)
                columna=7;
                cop_mat(5,1,1,FIG_ALL,columna); break;  //1: cuadro;
        
        case 2: if(grados==1 || grados==3)              
                cop_mat(0,0,0,FIG_ALL,columna);
                if(grados==2 || grados==4)
                cop_mat(5,5,2,FIG_ALL,columna);         //2: I;    
                break;
                  
        case 3: if(grados==1)
                cop_mat(0,0,1,FIG_ALL,columna);         //3: L; 
                if(grados==2)
                cop_mat(5,2,0,FIG_ALL,columna);
                if(grados==3)
                cop_mat(1,3,3,FIG_ALL,columna);
                if(grados==4)
                cop_mat(5,6,2,FIG_ALL,columna);
                break;
        
        case 4: if(grados==1)
                cop_mat(5,3,2,FIG_ALL,columna);         //4: T;
                if(grados==2)
                cop_mat(0,1,0,FIG_ALL,columna);
                if(grados==3)
                cop_mat(5,2,3,FIG_ALL,columna);
                if(grados==4)
                cop_mat(3,1,3,FIG_ALL,columna);
                break;
        
        case 5: if(grados==1 || grados==3)
                cop_mat(5,4,1,FIG_ALL,columna);         //5: S; 
                if(grados==2 || grados==4)
                cop_mat(0,1,3,FIG_ALL,columna);
                break; 
    }  
}


  • Función fichas():
    Se encarga de generar números aleatorios entre 0 y 5 que representan cada tipo de figura, es decir genera una pieza diferente una vez cae la pieza anterior.

void fichas(){
    ficha= rand() % 5+1; 
    //grados= rand() % 4+1;
    ncolumna=4; 
    }

All wikipages