JAVA實現拼圖遊戲
阿新 • • 發佈:2018-11-16
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!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>
*
* @email:[email protected]
* @version 0.1
*/
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Event;
import java.awt.Frame;
import
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 );
}
}
詳細操作參見原始碼註釋,所用圖片如下(也可自由選取圖形):
本程式碼演算法支援自由成比例分隔影象行列,效果若下: