拼圖遊戲是圖形處理與事件驅動程式設計的經典練習。本專案實作支援任意行列數(N×M)分割、圖片隨機打亂、滑鼠點擊交換塊塊、雙緩衝無閃爍渲染、完成偵測與過關圖片顯示等功能,核心邏輯僅 300 行,極適合學習 Java 2D 繪圖與遊戲迴圈架構。

支援自訂分割數,如 3×5、5×3 等非正方形拼圖:

BlockImage extends Canvas
├─ init(Image src, Image over, int cols, int rows) // 初始化資源與參數
├─ paint(Graphics g) // 雙緩衝繪製
├─ mouseDown(Event e, int x, int y) // 滑鼠點擊交換邏輯
├─ copy(int sx, int sy, int dx, int dy) // 區域複製(核心交換操作)
├─ rndPannel() // 隨機打亂演算法
└─ main() // 啟動示範
// 兩層緩衝:backimage 作為操作緩衝,screen 作為顯示緩衝
backimage = new BufferedImage(width, height + blockH, BufferedImage.TYPE_INT_ARGB);
screen = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
later = backimage.getGraphics();
bg = screen.getGraphics();
public void paint(Graphics g) {
bg.drawImage(backimage, 0, 0, null); // 將操作緩衝畫到顯示緩衝
g.drawImage(screen, 0, 0, this); // 一次性繪製到螢幕
}
所有拼圖塊移動、交換操作皆在 backimage 上透過 copyArea() 完成,最後一次 drawImage 送顯示,徹底消除閃爍。
void rndPannel() {
later.drawImage(srcImage, 0, 0, this); // 重置為原圖
for (int i = 0; i < COUNT * CS; i++) { // 足夠次數的隨機交換
int c1 = (int)(Math.random() * CS), r1 = (int)(Math.random() * RS);
int c2 = (int)(Math.random() * CS), r2 = (int)(Math.random() * RS);
copy(c1, r1, 0, RS); // 存入暫存區
copy(c2, r2, c1, r1); // 目標移到來源
copy(0, RS, c2, r2); // 暫存區移到目標
swap(blocks[r1*CS+c1], blocks[r2*CS+c2]); // 同步邏輯陣列
}
}
利用額外一列(height + blockH)作為暫存區,三步 copyArea 完成兩塊交換,同步更新邏輯位置陣列 blocks[]。
public boolean mouseDown(Event e, int x, int y) {
int col = x / blockW, row = y / blockH;
copy(0, 0, 0, RS); // 空白塊(0,0) -> 暫存區
copy(col, row, 0, 0); // 點擊塊 -> 空白塊位置
copy(0, RS, col, row); // 暫存區 -> 點擊塊原位置
swap(blocks[0], blocks[row*CS+col]); // 邏輯陣列同步
// 檢查是否全部歸位
boolean done = true;
for (int i = 0; i < COUNT; i++) if (blocks[i] != i) { done = false; break; }
if (done) isEvent = true; // 觸發完成狀態
repaint();
return true;
}
空白塊固定在邏輯位置 0,每次點擊即將目標塊與空白塊交換,邏輯簡潔高效。
backimage.jpg)。over.gif)。完整原始碼已內文提供,可直接複製編譯執行。本文轉載自「Java究竟怎麼玩」博客,原文地址:https://cping1982.blog.51cto.com/601635/116705