[XNA] Implementando un clon de Tetris con XNA

El Tetris es un must-do para cualquier programador que se precie… pues con esto he podido poner un check en la lista de “cosas que hacer para ser un buen programador”. Un juego, por sencillo que sea -como es el caso del tetris- contiene mucha lógica, y si no se estructura bien la complejidad puede crecer de forma exponencial… llegando a complicar de tal forma la codificación que resulte imposible continuar con el desarrollo del juego. El caso es que si te animas a implementar este pequeño juego, te darás cuenta de la importancia de diseñar antes de picar código -algo a lo que estamos relativamente acostumbrado cuando programamos aplicaciones de gestión-. En este caso he usado una herramienta de diseño increiblemente avanzada… EL EXCEL. Pues sí… el excel ¿qué pasa…? Lo cierto es que me ha ido perfecto para “debugar mentalmente” algunas situaciones, así como tener controlada la forma y tamaño de cada uno de los tipos de piezas disponibles en un tetris que se precie. Como demuestra la captura de pantalla:

El resultado de unas horillas de codificación es el siguiente:

[View:http://www.youtube.com/watch?v=m_JezzoomWw:550:0]

Dicho esto… vamos a ver un poco el algoritmo de implementación (a grandes rasgos):

 1 Crear pieza aleatoria               
 2 Leer nueva posición               
 3 Comprobar si la nueva posición está libre               
     3.1 Si NO está libre copiar a Matriz              
     3.2 Si está libre, lo movemos a la posición solicitada              
4 Comprobar si hay línea en la matriz               
    4.1 Si hay línea, desplazar todo una línea hacia abajo a partir de esta, sobreescribiendo              

¿Fácil verdad?  Toda la lógica se encuentra en las clases Tablero y Ficha, que muestro en este diagrama de Visual Studio:

Los objetos importantes son MatrizGlobal, que es una matriz de dos dimensiones donde se van almacenando todas las piezas que no están bajo el control del jugador, y sobre la cual detectaremos colisiones con la ficha que sí mueve el usuario, si ha llegado al tope (game over), si hay línea, etc.

public Color?[,] MatrizGlobal;

Por defecto todos los valores de la matriz serán null, y a medida que el usuario vaya soltando piezas sobre el “suelo” de la matriz, estas piezas pasarán a formar parte de la matriz en forma de Color (para posteriormente ser capaces de pintar cada pieza con la textura que toca).

La clase update de Tablero ejecuta el algoritmo que he mostrado antes:

public void Update(GameTime gameTime)
{
  
if (tipoMovimiento != Ficha.TipoMovimiento.gameOver)
   {

      // Lógica de la ficha
     
tipoMovimiento = this.Ficha.Update(gameTime, ref MatrizGlobal);

      // Comprobar si hay lnea
     
if (tipoMovimiento == Ficha.TipoMovimiento.colisionVertical)
      {
        
this.ComprobarLineas();
        
this.Ficha = new Ficha();
      }
   }
  
else
  
{
     
// Si pulsa espacio, limpiamos tablero y reiniciamos
     
if (Keyboard.GetState().IsKeyDown(Keys.Space))
      {
        
this.ResetGame();
      }
   }
}

En la clase Ficha tenemos como método más “complicado” el que calcula si se puede mover la pieza a la nueva posición solicitada (la pieza siempre cae hacia abajo, más si el jugador la está haciendo rotar o mover hacia derecha o izquierda). Sería esta la implementación del método:

int anchoBloque = this.ancho[this.rotacionActual];
int altoBloque = this.alto[this.rotacionActual];

int anchoTablero = MatrizGlobal.GetLength(0);
int altoTablero = MatrizGlobal.GetLength(1);

// Comprobamos posicin de la pieza con el tablero
for (int y = 0; y < altoBloque; y++)
{
  
for (int x = 0; x < anchoBloque; x++)
   {
     
if (this.Espacio[rotaciontmp, x, y] == true)
      {
        
if(nuevaPosicionY + y == altoTablero)
           
return TipoMovimiento.colisionVertical;
        
if(nuevaPosicionX + x >= anchoTablero)
           
return TipoMovimiento.fueraLimites;
        
if (MatrizGlobal[nuevaPosicionX + x, nuevaPosicionY + y] != null)
           
return TipoMovimiento.colisionLateral;

         if (this.PosicionY + y + 1 < altoTablero && MatrizGlobal[nuevaPosicionX + x, this.PosicionY + y + 1] != null)
           
return TipoMovimiento.colisionVertical;
      }
   }
}

return TipoMovimiento.correcto;

¿Lo próximo? Creo que va a ser divertido implementar una IA que juegue sola al tetris… (y digo sola porqué ningún humano es capaz de vencer una máquina jugando al tetris…)

16 comentarios en “[XNA] Implementando un clon de Tetris con XNA”

  1. Hola chicos, gracias por los comentarios 🙂

    Txiki, es interesante programar el tetris por uno mismo, por eso no he colgado el código. Sinó menudo “must-do” 😛

    Un saludo,

    JB

  2. Buen post, ciertamente es un must-do, como el “conecta 4”.
    La verdad es que estos jueguecillos por simples que parezcan en un principio, te hacen pensar y te obligan a organizarte.

  3. Muy bueno Jesús me ha gustado la parte del diseño en excel XD, la verdad es que es un must-do que también tengo pendiente XD.

    Saludos

  4. Im-presionante… 🙂

    Yo tengo a medias una versión de Plock (uno de esos jueguecitos flash que hay en el facebook) hecho en XNA para Surface…

    Es mi primera toma de contacto con XNA, algun dia de esos voy a poner mis experiencias al respecto!! xDDDD

    Saludos!

  5. Muy bueno el juego jesús, ahora tengo que hacer un tetris para movil con j2me para un proyecto de clase, y cuando lo termine quiero hacerlo tambien con XNA. Un saludo!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *