博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA实现拼图游戏
阅读量:6118 次
发布时间:2019-06-21

本文共 5011 字,大约阅读时间需要 16 分钟。

效果图如下:




源码如下:


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

转载地址:http://bjtka.baihongyu.com/

你可能感兴趣的文章
linux:yum和apt-get的区别
查看>>
Sentinel 1.5.0 正式发布,引入 Reactive 支持
查看>>
如何对网站进行归档
查看>>
数据库之MySQL
查看>>
2019/1/15 批量删除数据库相关数据
查看>>
数据类型的一些方法
查看>>
Mindjet MindManager 2019使用教程:
查看>>
这3条将是云计算2019年发展趋势
查看>>
游戏设计的基本构成要素有哪些?
查看>>
详解 CSS 绝对定位
查看>>
AOP
查看>>
我的友情链接
查看>>
AIX学习笔记之(一) 用户和安全管理
查看>>
mysql主从监控
查看>>
Centos6.9下 yum 安装 nginx1.10 + mysql5.6 + php5.6
查看>>
报表图表控件文档帮助手册
查看>>
源码安装版本管理Subversion
查看>>
shell中的时间值提取(date)
查看>>
iOS开发那些事--创建基于故事板的iOS 6的HelloWorld
查看>>
如何在App中实现朋友圈功能之八页面加载功能的逻辑与实现——箭扣科技Arrownock...
查看>>