Juego de pingpong y tetris.
tetris juego
Es un juego de puzzles, en el cual toca ir apilando diferentes figuras y a medida que se llena una fila esta se elimina para ir avanzando en el juego, si se deja acumular las fichas hasta el limite se pierde el juego.
Para el manejo de las figuras se utiliza un joystick o analogo; si el joystick se mueve a la derecha la figura se moverá a la derecha, si se mueve hacia la izquiera la figura se moverá a la izquierda y si el joystick se mueve hacia arriba la figura cambiará de posición.
Aquí se muestran las figuras y sus diferentes posiciones

Para enviar la informacion a la tarjeta utilizada, que fue una STM32F411- NUCLEO se hace una función la cual se encarga enviar los datos de entrada.
void sendSPI(uint8_t d1, uint8_t d2)
{
deviceM.unlock();
ssel=0;
deviceM.write(d1);
deviceM.write(d2);
ssel=1;
deviceM.lock();
}
Para que la figura se desplace hacia abajo se utiliza la siguiente función dentro del codigo.
void imp_mat(uint8_t *temp) // Hace el desplazamiento hacia abajo de la figura
{
sendSPI(cont-3,mat_act[cont-3]);
sendSPI(cont-2,(*(temp+0) | mat_act[cont-2]));
sendSPI(cont-1,(*(temp+1) | mat_act[cont-1]));
sendSPI(cont,(*(temp+2) | mat_act[cont]));
}
La función que se encarga de almacenar la figura en una matriz temporal y dar el movimiento de un lado a otro atraves de las columnas.
void cop_fi (uint8_t* tfig) //Almacena la figura en la matriz temporal
{
for(i=0;i<8;i++)
{
mat_tmp[i]=*(tfig+i)>>dat[1]-1;
}
for(i=0;i<8;i++)
{
mat_tmp1[i]= mat_tmp[i];
}
}
Para guardar la matriz temporal creada se hace una funcion donde esa matriz temporal se guarda dentro de una matriz actual.
void guardar_mat(uint8_t *temp) //guarda la matriz
{
mat_act[fila-3]=(*(temp+0))| mat_act[fila-3];
mat_act[fila-2]=(*(temp+1))| mat_act[fila-2];
mat_act[fila-1]=(*(temp+2))| mat_act[fila-1];
};
En esta función se configura se lee el voltaje y me transforma la señal digital en una analoga.
void analogo() //Lee voltaje de entrada y lo multiplica por 3300 para tener un voltaje de 3.3
{
mx=vrx.read();
msx=mx*3300;
my=vry.read();
msy=my*3300;
printf("Datosx = %f",msx);
}
La programación de los giros y los movimientos por medio del joystick se encuentra en esta función la cual está estructurada por medio de un switch que selecciona los casos y dependiendo de los movimientos del joystick se mueve atraves de las columnas de derecha a izquierda o biseversa y tambien cambia de posicion.
void move_fig() //mueve la figura por medio del analogo o joystick
{
analogo();
int mfig;
if(msx>1800){
mfig=1;}
if(msy<300){ //mover figura a la derecha
mfig=2;}
if(msy>3000){ //mover figura a la izquierda
mfig=3;}
switch(mfig)
{
case 0:
break;
case 1:
grad++;
if(grad<5){
switch (grad)
{
case 1:
mat_tmp[0]=mat_tmp1[4];
mat_tmp[1]=mat_tmp1[5];
mat_tmp[2]=mat_tmp1[6];
break;
case 2:
mat_tmp[0]=mat_tmp1[0];
mat_tmp[1]=mat_tmp1[2];
mat_tmp[2]=mat_tmp1[1];
break;
case 3:
mat_tmp[0]=mat_tmp1[6];
mat_tmp[1]=mat_tmp1[5];
mat_tmp[2]=mat_tmp1[4];
break;
case 4:
mat_tmp[0]=mat_tmp1[0];
mat_tmp[1]=mat_tmp1[1];
mat_tmp[2]=mat_tmp1[2];
break;
}
}
if(grad>4){
grad=0;
}
break;
case 2:
int temp1 = mat_tmp[i]&(0x01);
if(temp1==0)
{
for(i=0;i<3;i++)
{
mat_tmp[i]=mat_tmp[i]>>1; //mover derecha
}
for(i=0;i<7;i++){
mat_tmp1[i]=mat_tmp1[i]>>1;
}
}
break;
case 3:
int temp2 = mat_tmp[i]&(0x80);
if(temp2==0)
{
for(i=0;i<7;i++){
mat_tmp1[i]=mat_tmp1[i]<<1;
}
for(i=0;i<3;i++)
{
mat_tmp[i]=mat_tmp[i]<<1; //mover izquierda
}
}
break;
}
}
En esta función se almacena la matriz temporal para que no siga bajando y ademas evalua el espacio disponible para que la figura baje o se detenga.
void act_matrix(uint8_t* temp) //Evalua figura guardada y su espacio
{
for (i=0;i<9;i++){
save=*(temp+2)& mat_act[i];
if (save==0 )
{
fila=i+1;
}
if (save!=0)
{
fila=i;
i=9;
}
}
}
#include "mbed.h"
#include "algo.h"
#define MAXDAT 3
Ticker camb;
AnalogIn vrx(A0);
AnalogIn vry(A1);
SPI deviceM(PB_15, PB_14, PB_13);
DigitalOut ssel (PB_12);
Serial pc(USBTX,USBRX);
uint8_t mat_act[11]={0,0,0,0,0,0,0,0,0,0,0}; //Matriz para mostrar en pantalla.
uint8_t mat_tmp[8]={0,0,0,0,0,0,0,0};
uint8_t mat_tmp1[8]={0,0,0,0,0,0,0,0}; //Matriz temporal de las fichas.
uint8_t dat[MAXDAT]={0,0,0};
uint8_t fila=0,save=0,i=0,cont=0,mcol=0,num=0,grad=0;
float mx;
float msx;
float my;
float msy;
void sendSPI(uint8_t d1, uint8_t d2)
{
deviceM.unlock();
ssel=0;
deviceM.write(d1);
deviceM.write(d2);
ssel=1;
deviceM.lock();
}
void test() //Test
{
sendSPI(0x09,0); //No decodificacion
sendSPI(0x0B,0x07); //Usa 7 leds
sendSPI(0x0C,1); //No se apaga
sendSPI(0x0A,0x0);
for (int i=0;i<2;i++){
sendSPI(0x0F,1);
wait (0.1);
sendSPI(0x0f,0);
wait (0.1); }
}
void borrar() //borrar toda la matriz;
{
int i;
for(i=0;i<=8;i++)
{
sendSPI(0x0+i,0x00);
}
}
void imp_mat(uint8_t *temp) // Hace el desplazamiento hacia abajo de la figura
{
sendSPI(cont-3,mat_act[cont-3]);
sendSPI(cont-2,(*(temp+0) | mat_act[cont-2]));
sendSPI(cont-1,(*(temp+1) | mat_act[cont-1]));
sendSPI(cont,(*(temp+2) | mat_act[cont]));
}
uint32_t read_command() //ingresa "<",">" y define el tamaño del vector "dat"
{
char intc=pc.getc();
while(intc != '<')
intc=pc.getc();
for (int i =0;i<MAXDAT;i++)
dat[i]=pc.getc();
intc=pc.getc();
if(intc != '>'){
return 0;
}
return 1;
}
void cop_fi (uint8_t* tfig) //Almacena la figura en la matriz temporal
{
for(i=0;i<8;i++)
{
mat_tmp[i]=*(tfig+i)>>dat[1]-1;
}
for(i=0;i<8;i++)
{
mat_tmp1[i]= mat_tmp[i];
}
}
void ingred_d() //Selecciona el tipo de figura
{
uint8_t tf=dat[0];
switch(tf)
{
case tipo_c: // Cuadrado
cop_fi(FIG_C);
break;
case tipo_s: // S
cop_fi(FIG_S);
break;
case tipo_t: // T
cop_fi(FIG_T);
break;
case tipo_i: // I
cop_fi(FIG_I);
break;
case tipo_l: // L
cop_fi(FIG_L);
break;
}
}
void analogo() //Lee voltaje de entrada y lo multiplica por 3300 para tener un voltaje de 3.3
{
mx=vrx.read();
msx=mx*3300;
my=vry.read();
msy=my*3300;
printf("Datosx = %f",msx);
}
void move_fig() //mueve la figura por medio del analogo o joystick
{
analogo();
int mfig;
if(msx>1800){
mfig=1;}
if(msy<300){ //mover figura a la derecha
mfig=2;}
if(msy>3000){ //mover figura a la izquierda
mfig=3;}
switch(mfig)
{
case 0:
break;
case 1:
grad++;
if(grad<5){
switch (grad)
{
case 1:
mat_tmp[0]=mat_tmp1[4];
mat_tmp[1]=mat_tmp1[5];
mat_tmp[2]=mat_tmp1[6];
break;
case 2:
mat_tmp[0]=mat_tmp1[0];
mat_tmp[1]=mat_tmp1[2];
mat_tmp[2]=mat_tmp1[1];
break;
case 3:
mat_tmp[0]=mat_tmp1[6];
mat_tmp[1]=mat_tmp1[5];
mat_tmp[2]=mat_tmp1[4];
break;
case 4:
mat_tmp[0]=mat_tmp1[0];
mat_tmp[1]=mat_tmp1[1];
mat_tmp[2]=mat_tmp1[2];
break;
}
}
if(grad>4){
grad=0;
}
break;
case 2:
int temp1 = mat_tmp[i]&(0x01);
if(temp1==0)
{
for(i=0;i<3;i++)
{
mat_tmp[i]=mat_tmp[i]>>1; //mover derecha
}
for(i=0;i<7;i++){
mat_tmp1[i]=mat_tmp1[i]>>1;
}
}
break;
case 3:
int temp2 = mat_tmp[i]&(0x80);
if(temp2==0)
{
for(i=0;i<7;i++){
mat_tmp1[i]=mat_tmp1[i]<<1;
}
for(i=0;i<3;i++)
{
mat_tmp[i]=mat_tmp[i]<<1; //mover izquierda
}
}
break;
}
}
void act_matrix(uint8_t* temp) //Evalua figura guardada y su espacio
{
for (i=0;i<9;i++){
save=*(temp+2)& mat_act[i];
if (save==0 )
{
fila=i+1;
}
if (save!=0)
{
fila=i;
i=9;
}
}
}
void guardar_mat(uint8_t *temp) //guarda la matriz
{
mat_act[fila-3]=(*(temp+0))| mat_act[fila-3];
mat_act[fila-2]=(*(temp+1))| mat_act[fila-2];
mat_act[fila-1]=(*(temp+2))| mat_act[fila-1];
};
int main() // menú en el cual se guardan todas las funciones realizadas
{
camb.attach(&move_fig,5);
test();
borrar();
while(1){
while(read_command()==0);
ingred_d();
act_matrix(mat_tmp);
for (cont=0;cont<fila;cont++)
{
analogo();
move_fig();
act_matrix(mat_tmp);
imp_mat(mat_tmp);
wait_ms(500);
}
guardar_mat(mat_tmp);
elim_lin();
}
}
juego pin pon
Este juego es ejecutado por un solo jugador, graficamente en la matriz se observa una barra la cual representa una raqueta y un punto movil que representa la pelota tanto la barra como la pelota tienen desplazamientos independientes, el movimiento de la barra es conrolado por un joystick en el eje X, el lanzamiento inicial de la pelota es controlado por el joystick en el eje Y, la direccion de lanzamiento de la pelota dependera a que lado de la matriz este ubicada la barra, una vez lazanda la pelota esta usara los limites de la matriz como pared para cambiar de direccion y su desplazamiento se hara en diagonales ascendentes y descendentes, cuando la pelota regresa a la poscion inicial es decir en donde se encuentra la barra la reconocera como pared y rebotara, continuando asi con un ciclo, en el momento en que la pelota no encuentre la barra al volver, se borrara la matriz representando asi un game over, a continuacion se coloca el codigo completo que contiene las fucniones mencionadas, en donde se encontrara de forma detalla la explicacion de cada linea como comentario.
#include "mbed.h"//biblioteca por defecto
AnalogIn vrx(A0);//puertos de entrada para lectura del joystick
AnalogIn vry(A1);//puertos de entrada para lectura del joystick
SPI deviceM(PB_15, PB_14, PB_13);//puertos usados para conectar la matriz
DigitalOut ssel (PB_12);//puertos usados para conectar la matriz
Serial pc(USBTX,USBRX);//conexion por puerto USB
int i/*variable contadora*/,j=1;//variable puntero
double a=0.05;// variable que representa la velocidad del juego
int dir=0; //movimiento de la pelota: 0=derecha,1=izquierda
int up=0; //movimiento de la pelota: 0=arriba,1=abajo
uint8_t FIG_P[8]={0x38,0x10,0x0,0x0,0x0,0x0,0x0,0x0};//arreglo de 8 posiciones que contiene la barra y la pelota, cada bit representa los 8 leds de cada columna, ya el dexplazamiento de bit a bit representa los leds de las filas
float mx;//variable donde se guarda los voltajes leidos
float msx;//variable donde se escalan los voltajes leidos
float my;//variable donde se guarda los voltajes leidos
float msy;//variable donde se escalan los voltajes leidos
uint8_t lim_der=3,lim_izq=2;//variables que representan los limites de dexplazamiento para la barra
void mostrar();
void borrar();
void barra();
void barra_ini();
void sendSPI(uint8_t d1, uint8_t d2)
{
deviceM.unlock();
ssel=0;
deviceM.write(d1);
deviceM.write(d2);
ssel=1;
deviceM.lock();
}
void test() //Test
{
sendSPI(0x09,0); //No decodificacion
sendSPI(0x0B,0x07); //Usa 8 leds
sendSPI(0x0C,1); //No se apaga
sendSPI(0x0A,0x0);
for (i=0;i<2;i++)
{
sendSPI(0x0F,1);
wait (0.1);
sendSPI(0x0f,0);
wait (0.1);
}
}
void analogo()//lee los voltajes generados por el joystick, los escala, e imprime dicho valor
{
mx=vrx.read();//lectura del volytaje en el eje x
msx=mx*3300;//multiplica por este 3300 con el fin escalar el valor leido
my=vry.read();//lectura del voltaje en el eje y
msy=my*3300;//multiplica por este 3300 con el fin escalar el valor leido
printf("movimiento_x = %f",msx);//imprimir en pantalla los valores leidos
printf("movimiento_y = %f",msy);//imprimir en pantalla los valores leidos
}
void barra()//desplaza la barra de lado a lado segun los movimientos en el joystick
{
if(msx<300)//condicion segun la lectura del voltaje
{
int temp1 = FIG_P[0]&(0x80);//se crea una variable temporal con el fin de alojar alli el resultado la operacion logica AND, con el fin de identificar si el bit mas significativo es 1 y asi limitar el dezplazamiento de la barra
if(temp1==0)//condicion segun el resultado de la operacion
{
FIG_P[0]=FIG_P[0]<<1; //dezplazamiento hacia la izquierda en la matriz
}
}
else if(msx>3000)//condicion segun la lectura del voltaje
{
int temp1 = FIG_P[0]&(0x01);//se crea una variable temporal con el fin de alojar alli el resultado la operacion logica AND, con el fin de identificar si el bit menos significativo es 1 y asi limitar el dezplazamiento de la barra
if(temp1==0)//condicion segun el resultado de la operacion
{
FIG_P[0]=FIG_P[0]>>1; //dezplazamiento hacia la derecha en la matriz
}
}
}
void barra_ini()//inicialmente se muestra la barra y la pelota, para que se dezplacen al tiempo antes de iniciar el juego
{
if(msx<300)//condicion segun la lectura del voltaje
{
int temp1 = FIG_P[0]&(0x80);//se crea una variable temporal con el fin de alojar alli el resultado la operacion logica AND, con el fin de identificar si el bit mas significativo es 1 y asi limitar el dezplazamiento de la barra
if(temp1==0)//condicion segun el resultado de la operacion
{
FIG_P[0]=FIG_P[0]<<1;
FIG_P[1]=FIG_P[1]<<1;//desplaza hacia la izquierda al tiempo de la barra y la pelota antes de comenzar el juego
}
}
else if(msx>3000)//condicion segun la lectura del voltaje
{
int temp1 = FIG_P[0]&(0x01);//se crea una variable temporal con el fin de alojar alli el resultado la operacion logica AND, con el fin de identificar si el bit menos significativo es 1 y asi limitar el dezplazamiento de la barra
if(temp1==0)//condicion segun el resultado de la operacion
{
FIG_P[0]=FIG_P[0]>>1;
FIG_P[1]=FIG_P[1]>>1; //desplaza hacia la derecha al tiempo de la barra y la pelota antes de comenzar el juego
}
}
}
void move_fig()//mueve la palota por toda la matriz, y limita sus desplazamientos con cambios de direccion simulando un rebote contra paredes
{
barra();//llamado a la funcion barra para poder dezplazar mientras la pelota se mueve
if(dir==0) //condicional para el valor de la variable que controla el desplazamiento hacia los lados de la pelota
{
if (up==0)//condicional para el valor de la variable que controla el desplazamiento hacia arriba y abajo de la pelota
{
FIG_P[j+1] = FIG_P[j]>>1;//desplazamiento diagonal derecha ascendente de la pelota
FIG_P[j] = 0x00;//elimina el paso de la pelota, de lo contrario dejaria los leds encendidos a medida que se desplaza
}
else//condicional para el valor de la variable que controla el desplazamiento hacia arriba y abajo de la pelota
{
FIG_P[j+1] = FIG_P[j+2]>>1;//desplazamiento diagonal derecha descendente de la pelota
FIG_P[j+2] = 0x00;//elimina el paso de la pelota, de lo contrario dejaria los leds encendidos a medida que se desplaza
}
}
else //condicional para el valor de la variable que controla el desplazamiento hacia los lados de la pelota
{
if(up==0)//condicional para el valor de la variable que controla el desplazamiento hacia arriba y abajo de la pelota
{
FIG_P[j+1] = FIG_P[j]<<1;//desplazamiento diagonal izquierda ascendente de la pelota
FIG_P[j] = 0x00;//elimina el paso de la pelota, de lo contrario dejaria los leds encendidos a medida que se desplaza
}
else//condicional para el valor de la variable que controla el desplazamiento hacia arriba y abajo de la pelota
{
FIG_P[j+1] = FIG_P[j+2]<<1;//desplazamiento diagonal izquierda descendente de la pelota
FIG_P[j+2] = 0x00;//elimina el paso de la pelota, de lo contrario dejaria los leds encendidos a medida que se desplaza
}
}
if(FIG_P[j+1]==0x80)//condiciona a que la pelota llegue al extremo izquierdo de la matriz, justo en el bit mas significativo
{
dir=0;// cambia de direccion hacia la derecha
}
else if(FIG_P[j+1]==0x01)//condiciona a que la pelota llegue al extremo derecho de la matriz, justo en el bit menos significativo
{
dir=1;// cambia de direccion hacia la izquierda
}
mostrar();//hace un llamado a la funcion mostrar con el fin de estar refrescando los datos a imprimir
wait(0.08);// tiempo de espera para poder visualizar los dezplazamientos
if(j+1==7)//condiciona a que la pelota llegue hasta la extremo superior de la matriz
{
up=1;//cambia la direccion de la pelota hacia abajo
}
else if(j==0)//condiciona a que la pelota llegue hasta la extremo inferior de la matriz
{
int temp2=FIG_P[j+1]&FIG_P[0];//se crea una variable temporal, para alojar alli el resultado de la operacion logica AND, con el fin de identificar si este aloja un 1 o un 0, de esta forma se sabe si la pelota alcanzo a ser golpeada por la barra
if(temp2==0)//condiconal si la variable temproal es igual a 0
{
FIG_P[j] = 0x00;
FIG_P[j+1] = 0x00;//al no ser devuelta la pelota por la barra, tanto como la pelota como la barra son borradas simulando un game over
}
up=0;// la pelota al ser golpeada por la barra subira de nuevo
}
mostrar();//hace un llamado a la funcion mostrar con el fin de estar refrescando los datos a imprimir
wait(0.08);// tiempo de espera para poder visualizar que la pelota no alcanzo a ser tocada por la barra
}
void mostrar()//imprime en la matriz la barra y la pelota contenidas en el arreglo
{
for(i=0; i<8; i++)//contador para recorrer posciones
{
sendSPI(i+1, FIG_P[i]);//avanza de 1 en 1 para recorrer todas las posiciones del arreglo e irlas mostrando
}
}
void borrar() //borra toda la matriz;
{
for(i=0;i<=8;i++)//contador para recorrer posiciones
{
sendSPI(0x0+i,0x00);//recorre bit por bit colocando solo 0
}
}
void inicio()//antes de comenzar el juego se hace una letura de voltaje en y del joystick, con el fin de lanzar la pelota e iniciar, ahora bien segun el desplazamiento que se haga de la barra con el joystick, la pelota tomara un direccion diferente de lanzamiento
{
analogo(); //se hace una llamada a la funcion analogo para hace las respectivas lecturas de voltaje
while(msy>300)//concional para el voltaje en y
{
analogo();//llamado a funcion analogo para leer voltajes
barra_ini();//llamado a funcion barra_ini para que haga los desplazamientos laterales junto a la pelota
mostrar();//llamado a funcion mostrar imprime el arreglo que contiene la barra y la pelota
if(msx<300)//condiciona segun voltaje en x
{
dir=1;//lanza la pelota inicialmente hacia la izquierda
}
else if (msx>3000)//condiciona segun voltaje en x
{
dir=0;//lanza la pelota inicialmente hacia la derecha
}
}
}
int main()//funcion principal
{
//orden de ejecucion de funciones
test();
borrar();
inicio();
while(1)//ciclo principal del juego
{
mostrar();
analogo();
move_fig();
if(up==0)
{
j++; //la va sumando de a 1 a la variable puntero con el fin de que la pelota ascienda
}
else{
j--;//la va restando de a 1 a la variable puntero con el fin de que la pelota descienda
}
}
}
Como se puede ver los codigos de los juegos estan por aparte, en este codigo siguiente se muestran los dos juegos con un interfaz de selección y una breve explicación en varias lineas.
#include "mbed.h"//biblioteca por defecto
#include "algo.h"//biblioteca creada que contiene las figuras del juego de tetris
#define MAXDAT 3
Ticker anal;
AnalogIn vrx(A0);//puertos de entrada para lectura del joystick
AnalogIn vry(A1);//puertos de entrada para lectura del joystick
SPI deviceM(PB_15, PB_14, PB_13);//puertos usados para conectar la matriz
DigitalOut ssel (PB_12);//puertos usados para conectar la matriz
Serial pc(USBTX,USBRX);//conexion por puerto USB
int j=1,op;//variable puntero
double a=0.4;// variable que representa la velocidad del juego
int dir=0; //movimiento de la pelota: 0=derecha,1=izquierda
int up=0; //movimiento de la pelota: 0=arriba,1=abajo
uint8_t FIG_J[6]={0x22,0x22,0xe2,0xa2,0xe7,0x0};//arreglo que contiene las iniciales T y P (iniciales de tetris y pin pon)
uint8_t FIG_U[8]={0xe7,0xa5,0xa7,0xa1,0xe7,0x0,0x0,0x0};//arreglo de 8 posiciones que contiene las iniciales de game over
uint8_t FIG_P[8]={0x38,0x10,0x0,0x0,0x0,0x0,0x0,0x0};//arreglo de 8 posiciones que contiene la barra y la pelota, cada bit representa los 8 leds de cada columna, ya el dexplazamiento de bit a bit representa los leds de las filas
float mx;//variable donde se guarda los voltajes leidos
float msx;//variable donde se escalan los voltajes leidos
float my;//variable donde se guarda los voltajes leidos
float msy;//variable donde se escalan los voltajes leidos
void inicio();
void mostrar();
void mostrarg();
void mostrarj();
void borrar();
void barra();
void barra_ini();
void inicio();
uint8_t mat_act[11]={0,0,0,0,0,0,0,0,0,0,0}; //Matriz para mostrar en pantalla.
uint8_t mat_tmp[8]={0,0,0,0,0,0,0,0};
uint8_t mat_tmp1[8]={0,0,0,0,0,0,0,0}; //Matriz temporal de las fichas.
uint8_t dat[MAXDAT]={0,0,0};
uint8_t fila=0,save=0,i=0,cont=0,mcol=0,num=0,grad=0;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//FUNCIONES EN COMUN
void sendSPI(uint8_t d1, uint8_t d2)//envia datos a la tarjeta, cierra y abre puertos
{
deviceM.unlock();
ssel=0;
deviceM.write(d1);
deviceM.write(d2);
ssel=1;
deviceM.lock();
}
void test() //Test
{
sendSPI(0x09,0); //No decodificacion
sendSPI(0x0B,0x07); //Usa 8 leds
sendSPI(0x0C,1); //No se apaga
sendSPI(0x0A,0x0);
for (int i=0;i<2;i++)
{
sendSPI(0x0F,1);
wait (0.1);
sendSPI(0x0f,0);
wait (0.1);
}
}
void borrar() //borra toda la matriz;
{
for(int i=0;i<=8;i++)//contador para recorrer posiciones
{
sendSPI(0x0+i,0x00);//recorre bit por bit colocando solo 0
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//FUNCIONES PIN PON
void analogo()//lee los voltajes generados por el joystick, los escala, e imprime dicho valor
{
mx=vrx.read();//lectura del volytaje en el eje x
msx=mx*3300;//multiplica por este 3300 con el fin escalar el valor leido
my=vry.read();//lectura del voltaje en el eje y
msy=my*3300;//multiplica por este 3300 con el fin escalar el valor leido
printf("movimiento_x = %f",msx);//imprimir en pantalla los valores leidos
printf("movimiento_y = %f",msy);//imprimir en pantalla los valores leidos
}
void barra()//desplaza la barra de lado a lado segun los movimientos en el joystick
{
if(msx<300)//condicion segun la lectura del voltaje
{
int temp1 = FIG_P[0]&(0x80);//se crea una variable temporal con el fin de alojar alli el resultado la operacion logica AND, con el fin de identificar si el bit mas significativo es 1 y asi limitar el dezplazamiento de la barra
if(temp1==0)//condicion segun el resultado de la operacion
{
FIG_P[0]=FIG_P[0]<<1; //dezplazamiento hacia la izquierda en la matriz
}
}
else if(msx>3000)//condicion segun la lectura del voltaje
{
int temp1 = FIG_P[0]&(0x01);//se crea una variable temporal con el fin de alojar alli el resultado la operacion logica AND, con el fin de identificar si el bit menos significativo es 1 y asi limitar el dezplazamiento de la barra
if(temp1==0)//condicion segun el resultado de la operacion
{
FIG_P[0]=FIG_P[0]>>1; //dezplazamiento hacia la derecha en la matriz
}
}
}
void barra_ini()//inicialmente se muestra la barra y la pelota, para que se dezplacen al tiempo antes de iniciar el juego
{
if(msx<300)//condicion segun la lectura del voltaje
{
int temp1 = FIG_P[0]&(0x80);//se crea una variable temporal con el fin de alojar alli el resultado la operacion logica AND, con el fin de identificar si el bit mas significativo es 1 y asi limitar el dezplazamiento de la barra
if(temp1==0)//condicion segun el resultado de la operacion
{
FIG_P[0]=FIG_P[0]<<1;
FIG_P[1]=FIG_P[1]<<1;//desplaza hacia la izquierda al tiempo de la barra y la pelota antes de comenzar el juego
}
}
else if(msx>3000)//condicion segun la lectura del voltaje
{
int temp1 = FIG_P[0]&(0x01);//se crea una variable temporal con el fin de alojar alli el resultado la operacion logica AND, con el fin de identificar si el bit menos significativo es 1 y asi limitar el dezplazamiento de la barra
if(temp1==0)//condicion segun el resultado de la operacion
{
FIG_P[0]=FIG_P[0]>>1;
FIG_P[1]=FIG_P[1]>>1; //desplaza hacia la derecha al tiempo de la barra y la pelota antes de comenzar el juego
}
}
}
void move_fig()//mueve la palota por toda la matriz, y limita sus desplazamientos con cambios de direccion simulando un rebote contra paredes
{
barra();//llamado a la funcion barra para poder dezplazar mientras la pelota se mueve
if(dir==0) //condicional para el valor de la variable que controla el desplazamiento hacia los lados de la pelota
{
if (up==0)//condicional para el valor de la variable que controla el desplazamiento hacia arriba y abajo de la pelota
{
FIG_P[j+1] = FIG_P[j]>>1;//desplazamiento diagonal derecha ascendente de la pelota
FIG_P[j] = 0x00;//elimina el paso de la pelota, de lo contrario dejaria los leds encendidos a medida que se desplaza
}
else//condicional para el valor de la variable que controla el desplazamiento hacia arriba y abajo de la pelota
{
FIG_P[j+1] = FIG_P[j+2]>>1;//desplazamiento diagonal derecha descendente de la pelota
FIG_P[j+2] = 0x00;//elimina el paso de la pelota, de lo contrario dejaria los leds encendidos a medida que se desplaza
}
}
else //condicional para el valor de la variable que controla el desplazamiento hacia los lados de la pelota
{
if(up==0)//condicional para el valor de la variable que controla el desplazamiento hacia arriba y abajo de la pelota
{
FIG_P[j+1] = FIG_P[j]<<1;//desplazamiento diagonal izquierda ascendente de la pelota
FIG_P[j] = 0x00;//elimina el paso de la pelota, de lo contrario dejaria los leds encendidos a medida que se desplaza
}
else//condicional para el valor de la variable que controla el desplazamiento hacia arriba y abajo de la pelota
{
FIG_P[j+1] = FIG_P[j+2]<<1;//desplazamiento diagonal izquierda descendente de la pelota
FIG_P[j+2] = 0x00;//elimina el paso de la pelota, de lo contrario dejaria los leds encendidos a medida que se desplaza
}
}
if(FIG_P[j+1]==0x80)//condiciona a que la pelota llegue al extremo izquierdo de la matriz, justo en el bit mas significativo
{
dir=0;// cambia de direccion hacia la derecha
}
else if(FIG_P[j+1]==0x01)//condiciona a que la pelota llegue al extremo derecho de la matriz, justo en el bit menos significativo
{
dir=1;// cambia de direccion hacia la izquierda
}
mostrar();//hace un llamado a la funcion mostrar con el fin de estar refrescando los datos a imprimir
wait(a);// tiempo de espera para poder visualizar los dezplazamientos
if(j+1==7)//condiciona a que la pelota llegue hasta la extremo superior de la matriz
{
up=1;//cambia la direccion de la pelota hacia abajo
}
else if(j==0)//condiciona a que la pelota llegue hasta la extremo inferior de la matriz
{
int temp2=FIG_P[j+1]&FIG_P[0];//se crea una variable temporal, para alojar alli el resultado de la operacion logica AND, con el fin de identificar si este aloja un 1 o un 0, de esta forma se sabe si la pelota alcanzo a ser golpeada por la barra
if(temp2==0)//condiconal si la variable temproal es igual a 0
{
FIG_P[j] = 0x00;
FIG_P[j+1] = 0x00;//al no ser devuelta la pelota por la barra, tanto como la pelota como la barra son borradas simulando un game over
mostrarg();//imprime en la matriz las letras G,O (iniciales de game over) indicando que el juego termino
wait(3);//tiempo en el que duran las letras en pantalla
borrar();//borra contenido actual en la matriz
}
up=0;// la pelota al ser golpeada por la barra subira de nuevo
a=a/1.5;//reduce a la mitad el tiempo de espera, cada vez que la barra devuelve la pelota, aumenta la velocidad de dezplazamiento, es decir la velocidad del juego aumenta
}
}
void mostrar()//imprime en la matriz la barra y la pelota contenidas en el arreglo
{
for(int i=0; i<8; i++)//contador para recorrer posiciones
{
sendSPI(i+1, FIG_P[i]);//avanza de 1 en 1 para recorrer todas las posiciones del arreglo e irlas mostrando
}
}
void mostrarg()//imprime en la matriz la barra y la pelota contenidas en el arreglo
{
for(int i=0; i<8; i++)//contador para recorrer posciones
{
sendSPI(i+1, FIG_U[i]);//avanza de 1 en 1 para recorrer todas las posiciones del arreglo e irlas mostrando
}
}
void mostrarj()//imprime en la matriz la barra y la pelota contenidas en el arreglo
{
for(int i=0; i<6; i++)//contador para recorrer posciones
{
sendSPI(i+1, FIG_J[i]);//avanza de 1 en 1 para recorrer todas las posiciones del arreglo e irlas mostrando
}
}
void inicio()//antes de comenzar el juego se hace una letura de voltaje en y del joystick, con el fin de lanzar la pelota e iniciar, ahora bien segun el desplazamiento que se haga de la barra con el joystick, la pelota tomara un direccion diferente de lanzamiento
{
analogo(); //se hace una llamada a la funcion analogo para hace las respectivas lecturas de voltaje
while(msy>300)//concional para el voltaje en y
{
analogo();//llamado a funcion analogo para leer voltajes
barra_ini();//llamado a funcion barra_ini para que haga los desplazamientos laterales junto a la pelota
mostrar();//llamado a funcion mostrar imprime el arreglo que contiene la barra y la pelota
if(msx<300)//condiciona segun voltaje en x
{
dir=1;//lanza la pelota inicialmente hacia la izquierda
}
else if (msx>3000)//condiciona segun voltaje en x
{
dir=0;//lanza la pelota inicialmente hacia la derecha
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//FUNCIONES MATRIZ
void imp_mat(uint8_t *temp)// Hace el desplazamiento hacia abajo de la figura
{
sendSPI(cont-3,mat_act[cont-3]);
sendSPI(cont-2,(*(temp+0) | mat_act[cont-2]));
sendSPI(cont-1,(*(temp+1) | mat_act[cont-1]));
sendSPI(cont,(*(temp+2) | mat_act[cont]));
}
uint32_t read_command() //ingresa "<",">" y define el tamaño del vector "dat"
{
char intc=pc.getc();
while(intc != '<')
intc=pc.getc();
for (int i =0;i<MAXDAT;i++)
dat[i]=pc.getc();
intc=pc.getc();
if(intc != '>'){
return 0;
}
return 1;
}
void cop_fi (uint8_t* tfig) //Almacena la figura en la matriz temporal
{
for(i=0;i<8;i++)
{
mat_tmp[i]=*(tfig+i)>>dat[1]-1;
}
for(i=0;i<8;i++)
{
mat_tmp1[i]= mat_tmp[i];
}
}
void d_ale()
{
num=rand()%5+1;
mcol=4;
}
void ingred_d() //Tipo de figuras
{
uint8_t tf=dat[0];
switch(tf)
{
case tipo_c: // Cuadrado
cop_fi(FIG_C);
break;
case tipo_s: //S
cop_fi(FIG_S);
break;
case tipo_t: //T
cop_fi(FIG_T);
break;
case tipo_i: //I
cop_fi(FIG_I);
break;
case tipo_l: //L
cop_fi(FIG_L);
break;
}
}
void analogoo()
{
mx=vrx.read();
msx=mx*3300;
my=vry.read();
msy=my*3300;
printf("Datosx = %f",msx);
}
void mover_fig()//mueve la figura por medio de botones
{
analogoo();
int mfig;
if(msx>1800){
mfig=1;}
if(msy<300){//mover figura a la derecha
mfig=2;}
if(msy>3000){//mover figura a la izquierda
mfig=3;}
switch(mfig)
{
case 1:
grad++;
if(grad<5){
switch (grad)
{
case 1:
mat_tmp[0]=mat_tmp1[4];
mat_tmp[1]=mat_tmp1[5];
mat_tmp[2]=mat_tmp1[6];
break;
case 2:
mat_tmp[0]=mat_tmp1[0];
mat_tmp[1]=mat_tmp1[2];
mat_tmp[2]=mat_tmp1[1];
break;
case 3:
mat_tmp[0]=mat_tmp1[6];
mat_tmp[1]=mat_tmp1[5];
mat_tmp[2]=mat_tmp1[4];
break;
case 4:
mat_tmp[0]=mat_tmp1[0];
mat_tmp[1]=mat_tmp1[1];
mat_tmp[2]=mat_tmp1[2];
break;
}
}
if(grad>4){
grad=0;
}
break;
case 2:
int temp1 = mat_tmp[i]&(0x01);
if(temp1==0)
{
for(i=0;i<3;i++)
{
mat_tmp[i]=mat_tmp[i]>>1; //mover derecha
}
for(i=0;i<7;i++){
mat_tmp1[i]=mat_tmp1[i]>>1;
}
}
break;
case 3:
int temp2 = mat_tmp[i]&(0x80);
if(temp2==0)
{
for(i=0;i<7;i++){
mat_tmp1[i]=mat_tmp1[i]<<1;
}
for(i=0;i<3;i++)
{
mat_tmp[i]=mat_tmp[i]<<1; //mover izquierda
}
}
break;
}
}
void act_matrix(uint8_t* temp)//Evalua figura guardada y su espacio
{
for (i=0;i<9;i++){
save=*(temp+2)& mat_act[i];
if (save==0 )
{
fila=i+1;
}
if (save!=0)
{
fila=i;
i=9;
}
}
}
void guardar_mat(uint8_t *temp)//guarda la matriz
{
mat_act[fila-3]=(*(temp+0))| mat_act[fila-3];
mat_act[fila-2]=(*(temp+1))| mat_act[fila-2];
mat_act[fila-1]=(*(temp+2))| mat_act[fila-1];
};
void elim_lin()
{
for(i=0;i<9;i++){
if(mat_act[i]==255){
for(uint8_t a=i;a>=1;a--){
sendSPI(a,mat_act[a-1]);
mat_act[a]=mat_act[a-1];
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//FUNCION PRINCIPAL
int main()
{
//orden de funciones
test();
borrar();
mostrarj();
while(1)//ciclo que determina segun lectura de la funcion analogo que caso del swtich tomar, es decir que juego elegir
{
analogo();//se llama funcion para leer voltaje
if(msx<1500)//condicional que lleva al usuario al primer caso, en este caso juego de pin pon
{
op=1;//contiene las funciones del juego de pin pon
}
if(msx>2000)//condicional que lleva al usuario al primer caso, en este caso juego de tetris
{
op=2;//contiene las funciones del juego de pin pon
}
switch(op)//switch que hace seleccion de juego
{
case 1: //contenido del juego de pin pon
borrar();
wait(0.2);
inicio();
while(1)//ciclo principal del juego
{
mostrar();
analogo();
move_fig();
if(up==0)
{
j++; //la va sumando de a 1 a la variable puntero con el fin de que la pelota ascienda
}
else
{
j--;//la va restando de a 1 a la variable puntero con el fin de que la pelota descienda
}
}
case 2://contenido del juego de tetris
borrar();
anal.attach(&mover_fig,500);
while(1)
{
while(read_command()==0);
ingred_d();
act_matrix(mat_tmp);
for (cont=0;cont<fila;cont++)
{
analogoo();
mover_fig();
act_matrix(mat_tmp);
imp_mat(mat_tmp);
wait_ms(500);
}
guardar_mat(mat_tmp);
elim_lin();
}
}
}
}
Please log in to post comments.
