En este tutorial crearemos un sencillo juego de memoria en lenguaje java.
Necesitamos
Tiempo: 20 minutos
Nivel: Intermedio
Comencemos
1) Creamos un proyecto en netbeans que llamaremos «Memoria«, el proyecto tendrá la siguiente estructura:
El proyecto consta de:
Un paquete llamado «ram» que contiene las clases JuegoFrm que es un JFrame y dos clases Tablero y Casilla.
En el paquete res se colocan las 8 imágenes que en este ejemplo son 8 banderas de diferentes países, más una imagen extra que sera el que se muestre cuando se oculten las banderas. Las imágenes son del formato JPG.
2) Clase Casilla. Este juego de memoria que no es más que una matriz de objetos, estará formado por objetos «Casillas» que se extenderán de JLabel. El código comentado es el siguiente:
01 package com.bolivia.ram; 02 import java.awt.Cursor; 03 import java.awt.Dimension; 04 import javax.swing.ImageIcon; 05 import javax.swing.JLabel; 06 /** 07 * @web https://www.jc-mouse.net/ 08 * @author Mouse 09 */ 10 public class Casilla extends JLabel{ 11 12 private int ancho=140; 13 private int alto=140; 14 private ImageIcon hide = new ImageIcon(getClass().getResource("/com/bolivia/ram/res/hide.jpg")); 15 private ImageIcon bandera; 16 private String sBandera=""; 17 private boolean congelado=false; 18 19 /** 20 * constructor de clase 21 * @param name String El nomnbre de instancia 22 */ 23 public Casilla( String name ){ 24 super(); 25 Dimension d = new Dimension(ancho,alto); 26 setName(name); 27 setSize( d ); 28 setPreferredSize( d ); 29 setText(""); 30 setIcon( hide ); 31 setVisible(true); 32 setOpaque(true); 33 setCursor(new Cursor( Cursor.HAND_CURSOR )); 34 } 35 36 /** 37 * Muestra la imagen de la bandera asignada a esta casilla 38 * @return no tiene 39 */ 40 public void showBandera(){ 41 setIcon( bandera ); 42 } 43 44 /** 45 * Oculta la bandera 46 * @return no tiene 47 */ 48 public void ocultarBandera(){ 49 if( !congelado ){ 50 setIcon( hide ); 51 } 52 } 53 54 /** 55 * Cuando una imagen es congelada, no se puede volver a ocultar hasta comenzar un nuevo juego 56 * @param value boolean 57 */ 58 public void congelarImagen(boolean value){ 59 this.congelado=value; 60 } 61 62 /** 63 * Metodo que retorna el valor boolean de una casilla si este esta o no congelado 64 * @return boolean 65 */ 66 public boolean isCongelado(){ 67 return this.congelado; 68 } 69 70 /** 71 * Asigna la bandera que contendra la casilla 72 * @param name nombre de la bandera 73 */ 74 public void setBandera( String name ){ 75 this.sBandera = name; 76 if( !name.equals("") ){ 77 bandera = new ImageIcon(getClass().getResource("/com/bolivia/ram/res/"+name+".jpg")); 78 } 79 } 80 81 /** 82 * Retorna el nombre de la bandera que tenga asignada la casilla, si no tiene ninguna 83 * retorna una cadena vacia 84 * @return String 85 */ 86 public String getNameBandera(){ 87 return sBandera; 88 } 89 90 }
3) Clase Tablero. La clase base del juego la llamamos «Tablero«, esta clase se extiende de un JPanel y aquí es donde se colocan las «Casillas» creadas en el paso (2) que formaran nuestro juego, para alinearlas se hace uso del layout «gridLayout«, en esta clase definimos también la clase «juegoMouseListener» que nos permite capturar los clic realizados sobre las casillas y también definimos la clase «Animacion» que se extiende de SwingWorker, esta clase nos permitirá trabajar en un hilo aparte para, ejecutar un retardo (SLEEP) de 1 segundo que simula una animación y ademas nos permitirá llevar la cuenta de los aciertos que tenga el jugador caso contrario ocultara las banderas.
01 package com.bolivia.ram; 02 import java.awt.Component; 03 import java.awt.Dimension; 04 import java.awt.event.MouseEvent; 05 import java.awt.event.MouseListener; 06 import javax.swing.BorderFactory; 07 import javax.swing.JOptionPane; 08 import javax.swing.JPanel; 09 import javax.swing.SwingWorker; 10 /** 11 * @web https://www.jc-mouse.net/ 12 * @author Mouse 13 */ 14 public class Tablero extends JPanel{ 15 //array con los nombres de las banderas 8 en total para 16 pares 16 private String[] band = {"angola","bolivia","eritrea","haiti","india","malawi","palau","portugal"}; 17 18 private int fila =4; 19 private int col = 4; 20 private int ancho_casilla=140; 21 22 public boolean play = false; 23 24 int c=0; 25 Casilla c1; 26 Casilla c2; 27 int aciertos=0; 28 29 /** Constructor de clase */ 30 public Tablero(){ 31 super(); 32 //propiedades 33 setBorder( BorderFactory.createEmptyBorder(0, 0, 0, 0)); 34 setLayout( new java.awt.GridLayout(fila, col) ); 35 Dimension d= new Dimension( (ancho_casilla*col),(ancho_casilla*fila) ); 36 setSize(d); 37 setPreferredSize(d); 38 //crea instancias de casillas para crear el tablero 39 int count=0; 40 for(int i=1;i<=(fila*col);i++){ 41 Casilla p = new Casilla( String.valueOf(i) ); 42 p.setBandera( band[count] ); 43 count++; 44 count = (count>=band.length)? 0:count++; 45 p.showBandera(); 46 p.addMouseListener( new juegoMouseListener() ); 47 this.add( p ); 48 } 49 setVisible(true); 50 } 51 52 /** 53 * Inicia juegos 54 * - llena las casillas con pares de banderas 55 * @return no tiene 56 */ 57 public void comenzarJuego(){ 58 aciertos=0; 59 play=true; 60 Component[] componentes = this.getComponents(); 61 //limpia banderas 62 for( int i=0; i< componentes.length ;i++){ 63 ((Casilla)componentes[i]).congelarImagen(false); 64 ((Casilla)componentes[i]).ocultarBandera(); 65 ((Casilla)componentes[i]).setBandera( "" ); 66 } 67 //coloca nuevo orden aleatorio de banderas 68 for( int i=0; i< componentes.length ;i++){ 69 int n = (int) (Math.random()*(band.length)); 70 if( !existe(band[n]) ){//comprueba que bandera no este asignada mas de 2 veces 71 ((Casilla)componentes[i]).setBandera( band[n] ); 72 }else{ 73 i--; 74 } 75 } 76 77 } 78 79 80 /** 81 * Metodo que comprueba que una casilla existe 82 * @param int num nombre del objeto 83 * @return Casilla si existe 84 * NULL si no existe 85 */ 86 private boolean existe( String bandera ){ 87 int count=0; 88 Component[] componentes = this.getComponents(); 89 for( int i=0; i<componentes.length;i++ ) { 90 if( componentes[i] instanceof Casilla ) { 91 if( ((Casilla)componentes[i]).getNameBandera().equals( bandera ) ) { 92 count++; 93 } 94 } 95 } 96 return (count==2)? true:false; 97 } 98 99 /** 100 * Clase que implemenenta un MouseListener para la captura de eventos del mouse 101 */ 102 class juegoMouseListener implements MouseListener{ 103 104 @Override 105 public void mouseClicked(MouseEvent e) { 106 107 if( play ){ 108 c++;//lleva la cuenta de los click realizados en las casillas 109 if( c==1 ){ //primer click 110 c1=((Casilla) e.getSource()); //obtiene objeto 111 if( !c1.isCongelado() ){ 112 c1.showBandera(); 113 System.out.println("Primera Bandera: " + c1.getNameBandera() ); 114 }else{//no toma en cuenta 115 c=0; 116 } 117 }else if( c==2 && !c1.getName().equals( ((Casilla) e.getSource()).getName() ) ){//segundo click 118 c2=((Casilla) e.getSource()); 119 if( !c2.isCongelado() ){ 120 c2.showBandera(); 121 System.out.println("Segunda Bandera: " + c2.getNameBandera() ); 122 //compara imagenes 123 Animacion ani = new Animacion( c1, c2 ); 124 ani.execute(); 125 } 126 c=0;//contador de click a 0 127 }else{ //mas de 2 clic consecutivos no toma en cuenta 128 c=0; 129 } 130 }else{ 131 System.out.println("Para jugar: FILE -> JUGAR"); 132 } 133 134 135 } 136 137 @Override 138 public void mousePressed(MouseEvent e) {} 139 140 @Override 141 public void mouseReleased(MouseEvent e){} 142 143 @Override 144 public void mouseEntered(MouseEvent e) {} 145 146 @Override 147 public void mouseExited(MouseEvent e) {} 148 149 } 150 151 /** 152 * 153 */ 154 class Animacion extends SwingWorker<Void, Void>{ 155 private Casilla casilla1; 156 private Casilla casilla2; 157 158 public Animacion(Casilla value1, Casilla value2){ 159 this.casilla1= value1; 160 this.casilla2= value2; 161 } 162 163 @Override 164 protected Void doInBackground() throws Exception { 165 System.out.println("doInBackground: procesando imagenes..."); 166 //espera 1 segundo 167 Thread.sleep( 1000 ); 168 if( casilla1.getNameBandera().equals( casilla2.getNameBandera() ) ){//son iguales 169 casilla1.congelarImagen(true); 170 casilla2.congelarImagen(true); 171 System.out.println("doInBackground: imagenes son iguales"); 172 aciertos++; 173 if( aciertos == 8 ){//win 174 System.out.println("doInBackground: Usted es un ganador!"); 175 JOptionPane.showMessageDialog(null,"Usted es un ganador!"); 176 } 177 } 178 else{//no son iguales 179 casilla1.ocultarBandera(); 180 casilla2.ocultarBandera(); 181 System.out.println("doInBackground: imagenes no son iguales"); 182 } 183 return null; 184 } 185 186 } 187 188 }
4) Para terminar debemos trabajar en la interfaz del juego.
Abrimos la clase JuegoFrm en modo diseño, le añadimos un JMenu y dos JMenuItem como se ve en la imagen siguiente. agregamos también un JPanel con dimensiones de (560,560), completamos cambiando los nombres con los que se ven en la imagen.
Abrimos el JFrame en modo código y declaramos una instancia a nuestra clase Tablero
private Tablero tabla = new Tablero();
En el constructor de la clase agregamos el tablero a nuestra interfaz de usuario.
this.jpContenedor.add( tabla );
this.jpContenedor.repaint();
finalmente los JMenuItem
01 private void cmdPlayActionPerformed(java.awt.event.ActionEvent evt) { 02 tabla.comenzarJuego(); 03 } 04 05 private void cmdExitActionPerformed(java.awt.event.ActionEvent evt) { 06 System.exit(0); 07 }
Ejecutamos y si no tenemos ningún problema comenzamos a jugar
Proyecto completo: Entrale compadre 🙂
fin 🙂
Java ha ido evolucionando a pasos agigantados en los últimos años gracias al pedido de su comunidad global de programado[...]
Nueva versión de un viejo proyecto swing «JCMousePanel» que nos permitía agregar imágenes en los contenedores JPanel. En[...]
Es recomendable tener actualizado la Maquina Virtual Java de nuestro equipo para poder disfrutar de las mejoras que trae[...]
Los JavaBeans son clases que encapsulan objetos en un solo objeto (beans). Son fáciles de crear y pueden contener muchos[...]
Hola 🙂 en esta post se deja a disposición de la comunidad de programadores que quiera aprender un poquito sobre Factura[...]
JavaFX un producto de Sun Microsystems/Oracle Corporation que salio a la luz para competir con tecnologías como Flash o[...]