程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> JAVA實現拼圖游戲

JAVA實現拼圖游戲

編輯:關於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 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);
    }
}

詳細操作參見源碼注釋,所用圖片如下(也可自由選取圖形):

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

本文出自 “Java究竟怎麼玩” 博客,請務必保留此出處http://cping1982.blog.51cto.com/601635/116705

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved