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:ceponline@yahoo.com.cn 
 *  @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
这里写图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值