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

这里写图片描述

猜你喜欢

转载自blog.csdn.net/aabbyyz/article/details/84137042