tl  tr
  Home | Tutorials | Articles | Videos | Products | Tools | Search
Interviews | Open Source | Tag Cloud | Follow Us | Bookmark | Contact   
 Java Game Programming > Basic > Image Puzzle

Image Puzzle 

This example shows a simple image puzzle. User needs to reconstruct the image in the left hand side by following the small original image shown in the right side. The rendered puzzle is as shown below,

puzzle


File Name  :  
com/bethecoder/tutorials/gameprog/Puzzle.java 
Author  :  Sudhakar KV
Email  :  [email protected]
   
package com.bethecoder.tutorials.gameprog;

import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;

import com.bethecoder.tutorials.random.Shuffle;

public class Puzzle extends JFrame implements ActionListener{

  private static final long serialVersionUID = 387273093383621728L;
  private static final int PUZZLE_ROWS = 3;
  private static final int PUZZLE_COLS = 4;
  
  private JButton [][] splitImgs = null;
  private JButton originalImg = null;

  public Puzzle(String name){

    super(name);              
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.getContentPane().setLayout(null);

    /**
     * Add Original Image
     */
    Image image= new ImageIcon("images/original.jpg").getImage();   
    originalImg = new JButton(new ImageIcon(image.getScaledInstance(12090, Image.SCALE_SMOOTH )));
    originalImg.setBounds(6104012090);
    this.getContentPane().add(originalImg);

    /**
     * Add Split Images
     */
    addSplitImage();
    
    /**
     * Start the title animation.
     */
    startTilteAnimation(name);

  }//end constructor 

  private void addSplitImage() {
    String img = null;
    ImageIcon icon = null;
    splitImgs = new JButton[PUZZLE_ROWS][PUZZLE_COLS];
    List imgVec = Shuffle.shuffle(112);
    
    for (int i = 0; i < PUZZLE_ROWS; i ++ ) {

      for (int j = 0; j < PUZZLE_COLS; j ++ ){

        img = "images/"+ imgVec.get((i*PUZZLE_COLS+ j".jpg";
        icon = new ImageIcon(img)
        this.splitImgs[i][j]=new JButton();

        /**
         * Show split image, except one button
         */
        if(!(i==2&&j==3)) { 
          this.splitImgs[i][j].setIcon(icon);
        }
        
        /**
         * Set split image positions
         */
        this.splitImgs[i][j].setBounds(j*144+20, i*144+20144144);
        this.splitImgs[i][j].addActionListener(this);
        this.getContentPane().add(this.splitImgs[i][j]);
      }
    }//end for
  }
  
  private void startTilteAnimation(final String nam){

    Thread rotateTitleThread = new Thread(){

      String temp="";
      String name=nam;

      public void run(){
        while(true){
          /**
           * Rotate the puzzle application title by one char
           */
          temp = name.substring(0,name.length()-1);
          name = name.substring(name.length()-1);
          name +=temp;
          Puzzle.this.setTitle(name)
          try {Thread.sleep(180)}catch(Exception e){ e.printStackTrace()};
        }//end while
      }  
    };      

    rotateTitleThread.start();

  }//end of method.


  public void actionPerformed(ActionEvent ae){

    for (int i=0; i < PUZZLE_ROWS; i++ ) {

      for (int j=0; j <PUZZLE_COLS ; j++) {
        
        if(ae.getSource() == this.splitImgs[i][j]){
          Icon clikedImg = this.splitImgs[i][j].getIcon();
          log("In actionPerformed clikedImg :: " + clikedImg);
          checkAndMoveButton(i, j)
        
      }
    }//end for          

  }//end action method

  private void checkAndMoveButton(int row, int col){
    
    JButton curButton = this.splitImgs[row][col]
    JButton swapButton = null
      
    if (isSwapAllowed(swapButton = getTopButton(row, col))) {
      swapIcon(curButton, swapButton);
    else if (isSwapAllowed(swapButton = getBottomButton(row, col))) {
      swapIcon(curButton, swapButton);
    else if (isSwapAllowed(swapButton = getLeftButton(row, col))) {
      swapIcon(curButton, swapButton);
    else if (isSwapAllowed(swapButton = getRightButton(row, col))) {
      swapIcon(curButton, swapButton);
    }
      
  }
  
  /**
   * Swap possible only if the button available and its empty.
   @param swapButton
   @return
   */
  private boolean isSwapAllowed(JButton swapButton) {
    return swapButton != null && swapButton.getIcon() == null;
  }

  private void swapIcon(JButton curButton, JButton swapButton) {
    
    if(swapButton != null && swapButton.getIcon() == null) {                                                 
      swapButton.setIcon(curButton.getIcon());
      curButton.setIcon(null);
    }
  }

  private JButton getTopButton(int row, int col) {
    return getButton(row - 1, col);
  }
  
  private JButton getBottomButton(int row, int col) {
    return getButton(row + 1, col);
  }
  
  private JButton getLeftButton(int row, int col) {
    return getButton(row, col - 1);
  }
  
  private JButton getRightButton(int row, int col) {
    return getButton(row, col + 1);
  }
  
  private JButton getButton(int row, int col) {
    
    if (row < || row >= PUZZLE_ROWS || col < || col >= PUZZLE_COLS) {
      return null;
    }
    
    return this.splitImgs[row][col];  
  }

  public static void log(String msg) {
    System.out.println(msg);
  }
  
  /**
   * Start the puzzle.
   @param args
   */
  public static void main(String [] args){
    try{
      String name=" _ , .~   ><##*>  ~. ,  _ ,. ~  \\_sudha_/  ,~  ,~." +
      "   ><$$*> ` ., _.   ><%%*>  ,.  ~ _.~  ` .~ .   ><$$*> ";  

      Puzzle p=new Puzzle(name);
      p.setSize(750,510);
      p.setLocation(20,20);    
      p.setVisible(true);
      p.setResizable(false)
    }catch(Exception e){
      e.printStackTrace();
    }
  }//end main

}//end class 
   



 
  


  
bl  br