1. 程式人生 > >JAVA實現拼圖遊戲

JAVA實現拼圖遊戲

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

                package  org.test;



/**
 * <p>Title: LoonFramework</p>
 * <p>Description:拼圖影象處理[未優化](優化演算法已內置於loonframework-game框架中。)</p>
 * <p>Copyright: Copyright (c) 2007</p>
 * <p>Company: LoonFramework</p>
 * 
@author  chenpeng  
 * @email:[email protected] 
 * 
@version  0.1
 
*/

import  java.awt.Canvas;
import  java.awt.Color;
import  java.awt.Event;
import  java.awt.Frame;
import
 java.awt.Graphics;
import  java.awt.Image;
import  java.awt.MediaTracker;
import  java.awt.image.BufferedImage;

import  org.loon.framework.game.helper.ImageHelper;

public   class  BlockImage  extends  Canvas {
    
/**
     * 
     
*/
    
private   static   final   long  serialVersionUID  =   1L ;

    
private  Image _img;

    
private  Image _img2;

    
private  Graphics bg;

    
private  Image backimage;

    
private   int  blocks[];

    
private   boolean  isEvent;

    
private  MediaTracker mt;

    
private   int  _width;

    
private   int  _height;

    
private   int  _RS;

    
private   int  _CS;

    
private  Image screen  =   null ;

    
private  Graphics later  =   null ;

    
private   int  _objWidth;

    
private   int  _objHeight;

    
private   int  _COUNT;

    
/**
     * 解構函式,內部呼叫init方法。
     * 
     * 
@param  bImage
     * 
@param  overImage
     * 
@param  cs
     * 
@param  rs
     
*/
    
public  BlockImage(Image bImage, Image overImage,  int  cs,  int  rs) {
        init(bImage, overImage, cs, rs);
    }

    
/**
     * 初始化拼圖引數。
     * 
     * 
@param  bImage
     * 
@param  overImage
     * 
@param  cs
     * 
@param  rs
     
*/
    
public   void  init(Image bImage, Image overImage,  int  cs,  int  rs) {
        
//  列數
        _CS  =  cs;
        
//  行數
        _RS  =  rs;
        
//  載入拼圖用影象。
        _img  =  bImage;

        
//  獲得實際窗體寬。
        _width  =  _img.getWidth( null );
        
//  獲得實際窗體高。
        _height  =  _img.getHeight( null );
        
//  獲得單塊影象寬。
        _objWidth  =  _width  /  _CS;
        
//  獲得單塊影象高。
        _objHeight  =  _height  /  _RS;

        
//  本程式直接使用backimage上一塊圖形區域緩衝選擇項,所以實際背景影象高=圖形高+額外圖塊高。
        backimage  =   new  BufferedImage(_width, _height  +  _objHeight,  1 );
        
//  獲得生成的圖形
        later  =  backimage.getGraphics();
        
//  再建立一塊影象區域,作為影象快取用。
        screen  =   new  BufferedImage(_width, _height,  1 );
        
//  獲得快取的圖形
        bg  =  screen.getGraphics();
        
//  獲得等同圖片總數的陣列。
        _COUNT  =  _CS  *  _RS;
        blocks 
=   new   int [_COUNT];
        
//  初始化為非點選。
        isEvent  =   false ;
        
//  載入完成拼圖的顯示圖。
        _img2  =  overImage;
        
//  初始化圖塊引數。
         for  ( int  i  =   0 ; i  <  _COUNT; i ++ ) {
            blocks[i] 
=  i;
        }
        
//  載入MediaTracker,用以跟蹤影象狀態。
        mt  =   new  MediaTracker( this );
        
//  載入被跟蹤的影象。
        mt.addImage(_img,  0 );
        mt.addImage(_img2, 
0 );
        
//  同步載入。
         try  {
            mt.waitForID(
0 );
        } 
catch  (InterruptedException interruptedexception) {
            
return ;
        }
        
//  隨機生成影象面板內容。
        rndPannel();

    }

    
/**
     * 描繪窗體影象。
     
*/
    
public   void  paint(Graphics g) {
        
//  檢查影象載入。
         if  (mt.checkID( 0 )) {
            
//  描繪底層背景。
            bg.drawImage(backimage,  0 0 null );
            
//  判斷是否觸發完成事件。
             if  ( ! isEvent) {
                
//  設定背景色。
                bg.setColor(Color.black);
                
//  迴圈繪製小圖片於背景快取中。
                 for  ( int  i  =   0 ; i  <  _CS; i ++ ) {
                    
for  ( int  j  =   0 ; j  <  _RS; j ++ )
                        bg.drawRect(i 
*  _objWidth, j  *  _objHeight, _objWidth,
                                _objHeight);

                }

            }
            
//  僅當完成事件觸發並且有勝利圖片時,載入完成提示。
             if  (isEvent  &&  _img2  !=   null ) {
                bg.drawImage(_img2, 
0 0 null );
            }
        }
        
//  舉凡繪製圖像時,應遵循顯示影象僅繪製一次的基本原則,一次性的將背景繪製到窗體。
        
//  簡單來說,也就是採取[雙快取]的方式,所有複雜操作皆在快取區完成,也只有這樣才能避免產生延遲閃爍。
        g.drawImage(screen,  0 0 this );
        g.dispose();
    }

    
/**
     * 變更影象。
     
*/
    
public   void  update(Graphics g) {
        paint(g);
    }

    
/**
     * 滑鼠點選事件。
     
*/
    
public   boolean  mouseDown(Event event,  int  i,  int  j) {

        
if  (isEvent)
            
return   true ;
        
//  換算點選位置與小圖片。
         int  k  =  i  /  _objWidth;
        
int  l  =  j  /  _objHeight;
        copy(
0 0 0 , _RS);
        copy(k, l, 
0 0 );
        copy(
0 , _RS, k, l);
        
int  i1  =  blocks[ 0 ];
        
//  換算選中圖片儲存區。
        blocks[ 0 =  blocks[l  *  _CS  +  k];
        blocks[l 
*  _CS  +  k]  =  i1;
        
int  j1;
        
for  (j1  =   0 ; j1  <  _COUNT; j1 ++ ) {
            
if  (blocks[j1]  !=  j1) {
                
break ;
            }
        }
        
if  (j1  ==  _COUNT)
            isEvent 
=   true ;
        repaint();
        
return   true ;
    }

    
public   boolean  mouseUp(Event event,  int  i,  int  j) {
        
return   true ;
    }

    
public   boolean  mouseDrag(Event event,  int  i,  int  j) {
        
return   true ;
    }

    
/**
     * copy換算後的影象區域。
     * 
     * 
@param  i
     * 
@param  j
     * 
@param  k
     * 
@param  l
     
*/
    
void  copy( int  i,  int  j,  int  k,  int  l) {
        later.copyArea(i 
*  _objWidth, j  *  _objHeight, _objWidth, _objHeight,
                (k 
-  i)  *  _objWidth, (l  -  j)  *  _objHeight);
    }

    
/**
     * 事件觸發狀態。
     * 
@return
     
*/
    
public   boolean  isEvent() {
        
return  isEvent;
    }

    
public   void  setEvent( boolean  isEvent) {
        
this .isEvent  =  isEvent;
    }

    
/**
     * 隨機生成面板圖片。
     * 
     
*/
    
void  rndPannel() {
        later.drawImage(_img, 
0 0 this );
        
for  ( int  i  =   0 ; i  <  (_COUNT  *  _CS); i ++ ) {
            
int  j  =  ( int ) (( double ) _CS  *  Math.random());
            
int  k  =  ( int ) (( double ) _RS  *  Math.random());
            
int  l  =  ( int ) (( double ) _CS  *  Math.random());
            
int  i1  =  ( int ) (( double ) _RS  *  Math.random());
            copy(j, k, 
0 , _RS);
            copy(l, i1, j, k);
            copy(
0 , _RS, l, i1);
            
int  j1  =  blocks[k  *  _CS  +  j];
            blocks[k 
*  _CS  +  j]  =  blocks[i1  *  _CS  +  l];
            blocks[i1 
*  _CS  +  l]  =  j1;
        }

    }

    
public   static   void  main(String[] args) {

        Frame frm 
=   new  Frame( " 簡單的JAVA拼圖效果實現[由Loonframework框架提供] " );
        frm.setSize(
480 500 );
        frm.setResizable(
false );
        
/**
         * PS:ImageHelper.loadImage為Loonframework框架中helper下方法,為不依賴於javax擴充套件包而開發。
         * 可使用ImageIO相關方法代替。
         
*/
        
//  載入影象。
        Image backImage  =  ImageHelper.loadImage( " C:/backimage.jpg " true );
        Image overImage 
=  ImageHelper.loadImage( " C:/over.gif " true );
        
//  BlockImage中引數分別為 用於分解的拼圖,完成後顯示文字,拆分圖片為分幾列,分拆分圖片為幾行。
        
// 建議使用正方形圖片作為背景圖。
        frm.add( new  BlockImage(backImage, overImage,  4 4 ));
        backImage 
=   null ;
        overImage 
=   null ;
        
//  顯示窗體。
        frm.setVisible( true );

    }

}
 

詳細操作參見原始碼註釋,所用圖片如下(也可自由選取圖形):






本程式碼演算法支援自由成比例分隔影象行列,效果若下:



           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述