經典 J2ME 連連看(Link Game)核心代碼,包含 Canvas 界面繪製、遊戲邏輯引擎、連線判定演算法(直連、一折、兩折、邊界延伸),適合學習行動裝置遊戲開發基礎。
LinkCanvas extends Canvas implements Runnable:繪製、按鍵處理、主迴圈GameEngine:地圖數據、選擇狀態、連線判定、繪製輔助public class LinkCanvas extends Canvas implements Runnable {
private GameEngine engine;
private int width, height;
public LinkCanvas() {
engine = new GameEngine();
width = getWidth(); height = getHeight();
new Thread(this).start();
}
protected void paint(Graphics g) {
clearScreen(g);
engine.paintMap(g);
engine.paintSelectArea(g);
engine.paintLinkLine(g);
}
private void clearScreen(Graphics g) {
g.setColor(0xFFFFFF); g.fillRect(0, 0, width, height); g.setColor(0);
}
public void keyPressed(int keyCode) {
switch (getGameAction(keyCode)) {
case UP: engine.moveUP(); break;
case DOWN: engine.moveDown(); break;
case LEFT: engine.moveLeft(); break;
case RIGHT: engine.moveRight(); break;
case FIRE: engine.fire(); break;
}
}
public void run() {
try {
while (true) { Thread.sleep(100); engine.action(); repaint(); }
} catch (Exception e) { e.printStackTrace(); }
}
}
private final int MAX_ROW = 10, MAX_COL = 10;
private int[][] map = new int[MAX_ROW][MAX_COL];
private Random ran = new Random();
private void initMap() {
for (int r=0;r<MAX_ROW;r++) for (int c=0;c<MAX_COL;c++) map[r][c] = r+1;
for (int i=0;i<10;i++) for (int r=0;r<MAX_ROW;r++) for (int c=0;c<MAX_COL;c++) {
int tr = Math.abs(ran.nextInt()%10), tc = Math.abs(ran.nextInt()%10);
if (tr!=r || tc!=c) { int tmp=map[r][c]; map[r][c]=map[tr][tc]; map[tr][tc]=tmp; }
}
}
// 連線類型常數
private static final int NO_LINK=0, H_LINK=1, V_LINK=2, ONE_CORNER_X=3, ONE_CORNER_Y=4, TWO_CORNER=5;
private int linkType; private int[] p = new int[4]; // 兩折轉折點座標
private int logic() {
if (map[firstRow][firstCol] != map[secondRow][secondCol]) return NO_LINK;
if (isEmptyRow(firstRow,firstCol,secondRow,secondCol)) return H_LINK;
if (isEmptyCol(firstRow,firstCol,secondRow,secondCol)) return V_LINK;
int r = isOneCornerLink(firstRow,firstCol,secondRow,secondCol);
if (r != NO_LINK) return r;
if (isTwoCornerLink(firstRow,firstCol,secondRow,secondCol)) return TWO_CORNER;
return NO_LINK;
}
// 同行/同列無阻擋
private boolean isEmptyRow(int r1,int c1,int r2,int c2) { /* 略 */ }
private boolean isEmptyCol(int r1,int c1,int r2,int c2) { /* 略 */ }
// 一折:轉折點為空且兩段均通
private int isOneCornerLink(int r1,int c1,int r2,int c2) {
if (isEmptyCell(r1,c2) && isEmptyRow(r1,c1,r1,c2) && isEmptyCol(r1,c2,r2,c2)) return ONE_CORNER_X;
if (isEmptyCell(r2,c1) && isEmptyCol(r1,c1,r2,c1) && isEmptyRow(r2,c1,r2,c2)) return ONE_CORNER_Y;
return NO_LINK;
}
// 兩折:從首塊四方向延伸,每步嘗試一折連接終點,含邊界外延伸
private boolean isTwoCornerLink(int r1,int c1,int r2,int c2) { /* 詳見源碼 */ }
public boolean action() {
if (selectTileNum != 2) return false;
linkType = logic();
if (linkType != NO_LINK) {
map[firstRow][firstCol] = 0;
map[secondRow][secondCol] = 0;
selectTileNum = 0;
return true;
}
selectTileNum = 0;
return false;
}
完整源碼含詳細中文註釋,可直接作為 J2ME 遊戲開發教學範例或二次開發基礎。