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

Crea un plugin WP con panel de administracion

Crea un plugin WP con panel de administracion

En este post crearemos un plugin para el CMS WordPress el cual comprende el plugin en si, un panel de administración y e...

Rompecabezas en C# (Tutorial)

Rompecabezas en C# (Tutorial)

En este tutorial crearemos un sencillo rompecabezas de un tamaño de 4×6 con 24 piezas que se podrán mover haciendo...

Descargar Doodle Google Pacman

Descargar Doodle Google Pacman

Hace un par de años atras google para el aniversario del juego de Pacman saco un doodle en su homenaje, ese doodle que s...

Mapas en HTML5 – Uniendo todo – Parte 6

Mapas en HTML5 – Uniendo todo – Parte 6

Última parte del tutorial “Mapas interactivos HTML5”, vamos uniendo todo todo el código. En la parte 5 de es...

TextToSpeech: Convierte texto a voz

TextToSpeech: Convierte texto a voz

TextToSpeech o TTS, es el sintetizador de voz para android, en los celulares inteligentes viene un motor TTS por defecto...

Procedimientos almacenados en MySQL con Megan Fox

Procedimientos almacenados en MySQL con Megan Fox

Los procedimientos almacenados en MySQL son similares a los procedimientos de otros lenguajes de programación en el sent...

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

“Material Design es una guía integral para el diseño visual, de movimientos y de interacción en distintas platafor...

Un TextView autocompletado nos facilita el ingreso de información en aplicaciones móviles ya que te muestra posibles opc...

Un Tabbed Activity te permite cambiar la vista entre  fragmentos desplazando el dedo  de izquierda a derecha o de derech...

Este 12 de Mayo de 2017 se produjo un ataque masivo mundial del ransomware WannaCry  el  que afecto a más de 200000 comp...

Android Bolivia

Bandera en Alto