JAVA实现拼图游戏

简介:
效果图如下:



源码如下:

package org.test;


/**
* <p>Title: LoonFramework</p>
* <p>Description:拼图图像处理[未优化]</p>
* <p>Copyright: Copyright (c) 2007</p>
* <p>Company: LoonFramework</p>
* @author chenpeng    
* @email:[email]ceponline@yahoo.com.cn[/email] 
* @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);

        }

}

详细操作参见源码注释,所用图片如下(也可自由选取图形):




本代码算法支持自由成比例分隔图像行列,效果若下:






本文转自 cping 51CTO博客,原文链接:http://blog.51cto.com/cping1982/116705

相关文章
|
21天前
|
Java
Java猜数字游戏
Java猜数字游戏
17 2
|
1月前
|
Java Android开发
基于Java的坦克大战游戏的设计与实现
基于Java的坦克大战游戏的设计与实现
14 0
|
1月前
|
Java
【详识JAVA语言】猜数字游戏
【详识JAVA语言】猜数字游戏
21 1
|
4月前
|
Java 索引
Java综合实验1题目: 猜心术---猜姓氏游戏
Java综合实验1题目: 猜心术---猜姓氏游戏
52 1
|
1月前
|
算法 Java
游戏匹配系统的奥秘,Java代码揭秘
游戏匹配系统的奥秘,Java代码揭秘
25 1
|
1月前
|
Java
普通玩家也能掌握的Java游戏加点系统,专业到让你无敌!
普通玩家也能掌握的Java游戏加点系统,专业到让你无敌!
13 1
|
1月前
|
监控 Java 数据挖掘
用Java代码打造游戏反作弊系统
用Java代码打造游戏反作弊系统
22 0
|
1月前
|
Java
【Java每日一题】— —第二题:猜数游戏
【Java每日一题】— —第二题:猜数游戏
17 0
|
2月前
|
JavaScript 前端开发 Java
【热点话题】----还分不清Java和JavaScript嘛【JavaScript猜数字游戏】
【热点话题】----还分不清Java和JavaScript嘛【JavaScript猜数字游戏】
21 1
|
2月前
|
小程序 Java
java猜数字游戏并计数
java猜数字游戏并计数
23 4