Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube
JC Mouse Bolivia
Index / Java / Juego de memoria para niños (Código Fuente)

Juego de memoria para niños (Código Fuente)

Autor jc mouse martes, octubre 20, 2015

En un post anterior, desarrollamos un swing para simular un efecto FLIP  y recibí algunos mensajes pidiéndome un ejemplo de como usarlo. Cuando creamos un swing personalizado estos tienen casi las mismas propiedades que el resto de swing conocidos, esto se debe a que la mayoría de los componentes descienden de JComponent. Claro esta que también tienen sus propios métodos, por tanto se usan como cualquier otro swing.

Para mostrar el uso de ese componente FLIP, desarrollamos un sencillo juego de memoria. Este tipo de juegos sirve para desarrollar la memoria de los niños y niñas de una forma divertida, que es jugando 🙂 si señor profesor de mi infancia perdida, también se aprende jugando 😉

Sin más preámbulo describiremos a continuación el proyecto en cuestión:

La estructura del juego de memoria es la siguiente:

game java

En el paquete org.bolivia.game se encuentra un JFrame (GameFrame) que es la interfaz del juego compuesto por un JPanel y un JButton.

Tenemos también a la clase JFlipButton que es nuestro componente con el efecto flip con unas pequeñas modificaciones del original.

En el paquete org.bolivia.game.resources se encuentran las imágenes que se usan en el proyecto. En este caso son 10 imágenes de 100×100 pixeles en formato JPG

Clase JFlipButton

package org.bolivia.game;
import java.awt.BasicStroke;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.GeneralPath;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.Timer;
/**
 * @web http://www.jc-mouse.net/
 * @author Mouse
 */
public class JFlipButton extends JComponent implements MouseListener {
    
    private Timer timer                     =       null;    
    private boolean inTransition            =       false;
    private int speed                       =       4;//velocidad de flip en milisegundos
    private int displacement                =       2;//desplazamiento en pixeles
    public boolean isFront                  =       true;
    private boolean inward                  =       true;//sentido del desplazamiento
    //iconos por defecto
    private Icon iconBack                   =       new ImageIcon(getClass().getResource("/org/bolivia/game/resources/moe.jpg"));
    private Icon iconFront                  =       new ImageIcon(getClass().getResource("/org/bolivia/game/resources/cover.jpg"));
    private Image image                     =       ((ImageIcon)iconFront).getImage();
    //variables de desplazamiento
    private int displacementHorizontal      =       0;    
    private float displacementLeft          =       0;       
    private float displacementRight         =       0;    
    //tamaño por defecto
    private Dimension dimension             =       new Dimension(100,100);
    //
    private String nameCharacter            =       "";
    private int index                       =       -1;
    
    
    /**Constructor de clase*/
    public JFlipButton(){
        super();
        setSize(dimension);
        setPreferredSize(dimension);        
        setVisible(true);        
        setCursor(new Cursor(Cursor.HAND_CURSOR));
        addMouseListener(JFlipButton.this);        
    }
    
    @Override
    public void paintComponent(Graphics g){         
        Graphics2D g2 =(Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);            
        g2.setStroke(new BasicStroke( 1f ));
        //coordenas de imagen
        GeneralPath p = new GeneralPath();
            p.moveTo(displacementHorizontal, displacementLeft);//esquina A
            p.lineTo(getWidth()-displacementHorizontal, displacementRight);//esquina B
            p.lineTo(getWidth()-displacementHorizontal, getHeight()-displacementRight);//esquina D
            p.lineTo( displacementHorizontal, getHeight()-displacementLeft  );//esquina C
            p.closePath();
        Shape shp = p;
        g2.setClip(shp);
        g2.drawImage(image, 0, 0,getWidth() - displacementHorizontal,getHeight(), null);        
        g2.setClip(null);
        g2.draw(shp);
        g.dispose(); 
    }

    /**
     * Metodo que realiza los cambios en las variables de desplazamiento
     * @return Void
     */
    public void flipAnimate(){
        inTransition = !inTransition;
        //declaramos un evento para modificar el desplazamiento vertical y horizontal
        ActionListener animation = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                
                if(inward){   
                    displacementHorizontal += displacement;   
                    displacementRight += (displacementRight>=getHeight()/2)?0:displacement/(getSize().getWidth()/getSize().getHeight()+1f);                                        
                }else{
                    displacementHorizontal -= displacement;                                        
                    displacementLeft -=displacement/(getSize().getWidth()/getSize().getHeight()+1f);                                        
                }
                //repinta graficos
                repaint();
                
                //si se llego al medio del componente -> cambia de sentido
                if(displacementHorizontal >= getWidth()/2){ 
                    inward = false;
                    displacementLeft = displacementRight;                    
                    displacementRight=0;                    
                    //
                    if( isFront ){//mostrar imagen de atras
                        isFront=false;
                        image=((ImageIcon)iconBack).getImage();                            
                    }else{//mostrar imagen de adelante
                        isFront =true;                        
                        image=((ImageIcon)iconFront).getImage();                        
                    }                    
                } 
                //volvio a su posicion inicial -> detener animacion
                if( inward == false && displacementHorizontal == 0 ){
                    inTransition=false;   
                    timer.stop();
                    displacementLeft=0;
                    displacementRight=0;
                    displacementHorizontal=0;
                    inward = true;                                 
                }
            }
        }; 
        //
        if( inTransition )
        {
            if(timer != null)timer.stop();
            timer = new Timer( speed, animation);
            timer.start(); //inicia animacion      
        }
    }
    
    public void cancel(){
        if(timer != null)timer.stop();
        inTransition=false;           
    }
    
    @Override
    public void mouseClicked(MouseEvent e) {
        flipAnimate();
    }

    @Override
    public void mousePressed(MouseEvent e) {/*...*/}

    @Override
    public void mouseReleased(MouseEvent e) {/*...*/}

    @Override
    public void mouseEntered(MouseEvent e) {/*...*/}

    @Override
    public void mouseExited(MouseEvent e) {/*...*/}

    public Icon getIconBack() {
        return iconBack;
    }

    public void setIconBack(Icon iconBack) {
        this.iconBack = iconBack;
    }

    public Icon getIconFront() {
        return iconFront;
    }

    public void setIconFront(Icon iconFront) {
        this.iconFront = iconFront;
    }

    public int getDisplacement() {
        return displacement;
    }

    public void setDisplacement(int displacement) {
        this.displacement = displacement;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public String getNameCharacter() {
        return nameCharacter;
    }

    public void setNameCharacter(String nameCharacter) {
        this.nameCharacter = nameCharacter;
        iconBack = new ImageIcon(getClass().getResource("/org/bolivia/game/resources/"+ this.nameCharacter +".jpg"));
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }
    
}

La lógica del juego se controlo desde la clase GameFrame

public class GameFrame extends javax.swing.JFrame {

    private List<String> characters = new LinkedList<String>();
    private Character character1 = new Character();
    private Character character2 = new Character();
    private int hits = 0;
    
    /**
     * Creates new form GameFrame
     */
    public GameFrame() {
        initComponents();       
        
        setTitle("Game Memory [http://www.jc-mouse.net/]");
        setLocationRelativeTo(null);
        
        //layout
        jPanel1.setLayout(new GridLayout(4, 4));
        
        //se añaden las figuras al panel
        for(int i=0;i<16;i++){
            jPanel1.add( new JFlipButton() );    
        }
        
        //se crea nuevo juego
        newGame();
        
        //se añade eventos para cada casilla
        for(int i=0;i<16;i++){
            
            final JFlipButton button = (JFlipButton) jPanel1.getComponent(i);
            
            button.addMouseListener( new MouseListener(){

                @Override
                public void mouseClicked(MouseEvent e) {                    
                    /* --------- controla el juego en si -------- */
                    if( button.isFront ){//si imagen esta tapada
                    
                        if( character1.isEmpty() ){
                            character1.setKey( button.getIndex() );
                            character1.setName( button.getNameCharacter() );                        
                        }else if( character2.isEmpty() ){
                            character2.setKey( button.getIndex() );
                            character2.setName( button.getNameCharacter() );     
                            
                            //si figuras de ambas casillas son iguales
                            if(character1.getName().equals( character2.getName() ) ){
                                character1.setKey( -1 );
                                character1.setName( "" ); 
                                character2.setKey( -1 );
                                character2.setName( "" ); 
                                hits +=1; 
                                //completo el juego?
                                if(hits==8){//si
                                    JOptionPane.showMessageDialog(null, "--------------------------- YOU WIN!!! ---------------------------", "Atención", JOptionPane.INFORMATION_MESSAGE);
                                }
                            }else{//no son iguales
                                //se comienza un hilo que espera X tiempo hasta que la casilla de completamente la vuelta
                                new Thread(){
                                    @Override
                                    public void run()
                                    {
                                        try {
                                            Thread.sleep(500);
                                        } catch (InterruptedException ex) {}   
                                        //oculta figuras
                                        ((JFlipButton) jPanel1.getComponent(character1.getKey())).flipAnimate();
                                        ((JFlipButton) jPanel1.getComponent(character2.getKey())).flipAnimate();
                                        character1.setKey( -1 );
                                        character1.setName( "" ); 
                                        character2.setKey( -1 );
                                        character2.setName( "" ); 
                                    }                            
                                }.start();
                            }
                        }     

                    }else{                       
                       button.cancel();//se cancela animacion
                    }
                    
                }

                @Override
                public void mousePressed(MouseEvent e) {/* nada q ver circulando jovenes... */}

                @Override
                public void mouseReleased(MouseEvent e) {/* nada q ver circulando jovenes... */}

                @Override
                public void mouseEntered(MouseEvent e) {/* nada q ver circulando jovenes... */}

                @Override
                public void mouseExited(MouseEvent e) {/* nada q ver circulando jovenes... */}
                
            });
        }
        //
    }
 
    
    /**
     * Nuevo juegos
     */
    private void newGame(){
        characters.clear();
        
        //personajes
        characters.add("castulo");
        characters.add("bart");
        characters.add("homero");
        characters.add("lionel");
        characters.add("lisa");
        characters.add("maggie");
        characters.add("marge");
        characters.add("ned");
        
        characters.add("castulo");
        characters.add("bart");
        characters.add("homero");
        characters.add("lionel");
        characters.add("lisa");
        characters.add("maggie");
        characters.add("marge");
        characters.add("ned");
                
        //asigna los personajes a cada casilla
        for(int i=0;i<16;i++){
            ((JFlipButton) jPanel1.getComponent(i)).setNameCharacter(getCharacter());
            ((JFlipButton) jPanel1.getComponent(i)).setIndex(i);               

            if( !((JFlipButton) jPanel1.getComponent(i)).isFront )
                ((JFlipButton) jPanel1.getComponent(i)).flipAnimate();
        }
        //reinicia variables
        character1 = new Character();
        character2 = new Character();
        hits=0;
    }
    
    /**
     * desordena lista y retorna un personaje
     * @return String Nombre del personaje
     */
    private String getCharacter(){        
        Collections.shuffle(characters);
        return characters.remove(0);        
    }
    
    /**
     * clase privada para manejar las 2 figuras que deben ser comparadas
     */
    private class Character{
        
        private int key=-1;
        private String name="";        

        public int getKey() {
            return key;
        }

        public void setKey(int key) {
            this.key = key;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }    
        
        public boolean isEmpty(){
            if(key==-1 && name.equals(""))
               return true;
            else 
               return false;
        }
        
    }

Todo el proyecto se encuentra comentado hasta más no poder, cualquiera con un conocimiento intermedio de java podrá entenderlo, sino, abajo están los comentarios que responderé con gusto.

simpsons java

En el siguiente video un demo del juego en funcionamiento

Descarga el código desde este enlace pobre

enjoy!!!

Tags

Si te ha gustado podrías compartirlo o dejar un comentario. ¡Muchas gracias!
Autor: JC Mouse

Yo soy yo :) JC Mouse, Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.

Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye

Enjoy! :)

También Te Podría Interesar

Graficos estadisticos con javafx y swing

Graficos estadisticos con javafx y swing

En este post aprenderemos a usar los gráficos 2d que viene con JavaFX en nuestras aplicaciones java swing. Esto puede se...

Convertir imagenes JPEG a video MOV

Convertir imagenes JPEG a video MOV

Googleando me encontré con una interesante clase java “JpegImagesToMovie” que convierte imágenes JPEG a víde...

Colocar imagenes en un JComboBox

Colocar imagenes en un JComboBox

Para agregar imágenes a un JComboBox, partiremos de un proyecto Netbeans con la siguiente estructura: Tenemos dos clases...

Capturar webcam con VB.NET

Capturar webcam con VB.NET

¿Que haremos? Crearemos una aplicación en Visual Studio, la cual hará uso de una webcam para capturar el video en frames...

Evitar ejecutar un programa java más de una vez

Evitar ejecutar un programa java más de una vez

Cuando se hace uso de programas a veces no importa que este cree más de una instancia al mismo tiempo, por ejemplo podem...

Guía básica: Trabajando con GitHub y Netbeans

Guía básica: Trabajando con GitHub y Netbeans

Netbeans tiene soporte para trabajar con varias herramientas de control de versiones, GIT es una de ellas, esta herramie...

1 comentario en “Juego de memoria para niños (Código Fuente)”

  1. Maria jose dice:

    tengo un proyecto en la universidad pero en vez de pares son trios debo hacerlo atraves de matrices y arreglos . lo unico es que el profe nos mostro como deberia funcionar el codigo y no lo hizo con Jframes . el cuando le daba run al codigo iba designando cooredenadas y asi por decirlo de alguna manera volteaba las cartas de esa manera. Me podrias explicar como hacerlo es para el curso de programacion basica . Utilizo java en netbeans

Deja un comentario

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

*

Comparte lo que sabes

Categorias

Últimas entradas

Si quieres cambiar el nombre de tus atributos sin tener que reescribir código java por X o Y razón, GSON te permite reno...

Un JList nos permite almacenar objetos en una lista y mostrarlos gráficamente en una serie vertical en el cual el usuari...

El proyecto “Java Decompiler” tiene como objetivo desarrollar herramientas para descompilar y analizar byte...

En este post aprenderemos lo que es un JSON Web Token, como crear nuestro propio token de acceso y como usarlo en un Ser...

Android Bolivia

Bandera en Alto