📄 puzzlecanvas.java
字号:
/*
* Copyright 2003, 2004 Symbian Ltd.
* For License terms see http://www.symbian.com/developer/techlib/codelicense.html
*/
package picturepuzzle;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import java.util.*;
/**
* The game Canvas. Displays the randomised image as a 4 x 4 grid of
* tiles. Allows the user to re-arrange the tiles. Indicates when the
* correct arrangement has been arrived at and the game is over.
*/
public class PuzzleCanvas extends Canvas implements CommandListener {
static final int IMAGE_WIDTH = 160;
static final int IMAGE_HEIGHT = 120;
static final int COLS = 4;
static final int ROWS = 4;
private TiledLayer imageLayer;
private Image image;
private int cursorX , cursorY;//position coordinates of cursor
private GameMIDlet midlet;
private boolean doublePaired;
private Command exitCommand;
private Command hintCommand;
private Command newCommand;
private int firstBlock = 0;
private int secondBlock = 0;
private int firstCol = 0;
private int firstRow = 0;
private int secondCol = 0;
private int secondRow = 0;
/**
* Creates the scrambled puzzle from an image.
* @param midlet The GameMIDlet instance.
* @param image The image.
*/
public PuzzleCanvas(GameMIDlet midlet , Image image) {
super();
this.midlet = midlet;
this.image = image;
exitCommand = new Command("Exit", Command.EXIT, 1);
hintCommand = new Command("Hint" , Command.SCREEN , 2) ;
newCommand = new Command("New game" , Command.SCREEN , 2);
addCommand(exitCommand);
addCommand(hintCommand);
setCommandListener(this);
createBoard();
cursorX = getWidthDiff() / 2;
cursorY = getHeightDiff() / 2;
imageLayer.setPosition(getWidthDiff() / 2, getHeightDiff() / 2);
doublePaired = true;
}
/**
* Service method.
* @return An int.
*/
public int getWidthDiff() {
return getWidth() - IMAGE_WIDTH;
}
/**
* Service method
* @return An int.
*/
public int getHeightDiff() {
return getHeight() - IMAGE_HEIGHT;
}
/** randomize the order of tiles in the image layer. */
private void createBoard() {
imageLayer = new TiledLayer(COLS, ROWS, image, IMAGE_WIDTH/COLS, IMAGE_HEIGHT/ROWS);
Random ran = new Random();
Vector v = new Vector(ROWS*COLS);
boolean b = true;
int i;
// get integer numbers from 1 to ROWS*COLS in random order
while (b) {
i = ran.nextInt()%(ROWS*COLS)+1;
if (i > 0 && i <= (ROWS*COLS)) {
if (!contain(v , i)) {
v.addElement(new Integer(i));
}
if (v.size() == ROWS*COLS) {
b = false;
}
}
}
for (int m = 0; m < ROWS*COLS; m++) {
int integer = ( (Integer) v.elementAt(m)).intValue();
imageLayer.setCell( m/ROWS, m%ROWS, integer);
}
}
private boolean contain(Vector v , int element) {
for (int i = 0; i < v.size(); i++) {
if ( ( (Integer) v.elementAt(i)).intValue() == element) {
return true;
}
}
return false;
}
/**
* Paints the current TiledLayer arrangement and draws the cursor. Also indicates
* "Game over" when the game has been sucessfully completed.
* @param g
*/
public void paint(Graphics g) {
g.setColor(255 , 255 , 255);// Paint a white background
g.fillRect(0 , 0 , getWidth() , getHeight());
imageLayer.paint(g);
g.setColor(255 , 0 , 0);
drawFrame(cursorX , cursorY , g);
if (isWinning()){
g.setFont(Font.getFont(Font.FACE_MONOSPACE , Font.STYLE_BOLD , Font.SIZE_LARGE));
g.drawString("Game Over!!" , getWidth() / 2 , getHeight() / 2 , Graphics.HCENTER | Graphics.TOP);
}
}
/**
* Responds to movement of the Joystick.
* @param keyCode
*/
public void keyPressed(int keyCode) {
int key = getGameAction(keyCode);
if (key == LEFT) {
moveLeft();
} else if (key == RIGHT) {
moveRight();
} else if (key == UP) {
moveUp();
} else if (key == DOWN) {
moveDown();
} else if (key == FIRE && !doublePaired) {
setSecondBlock();
if (isWinning()) {
addCommand(newCommand);
}
} else if (key == FIRE && doublePaired) {
setFirstBlock();
}
repaint();
}
/**
* Ascertains whether the current arrangement of tiles is equal to the original
* image and hence the game has been successfully completed.
* @return boolean indicating whether the game has been sucessfully completed.
*/
public boolean isWinning() {
int count = 1 ;
for (int row = 0 ; row < imageLayer.getRows() ; row++) {
for (int col = 0 ; col < imageLayer.getColumns() ; col++) {
if (imageLayer.getCell(col , row) != count) {
return false ;
}
count++;
}
}
return true;
}
private void drawFrame(int x , int y , Graphics g) {
g.drawRect(x , y , imageLayer.getCellWidth() , imageLayer.getCellHeight());
}
/**
* Moves cursor one tile up.
*/
public void moveUp() {
cursorY = cursorY - imageLayer.getCellHeight();
if (cursorY < getHeightDiff() / 2) {
cursorY = getHeightDiff() / 2;
}
}
/**
* Moves cursor one tile down.
*/
public void moveDown() {
cursorY = cursorY + imageLayer.getCellHeight();
if ( cursorY > IMAGE_HEIGHT + getHeightDiff() / 2 - imageLayer.getCellHeight()) {
cursorY = IMAGE_HEIGHT + getHeightDiff() / 2 - imageLayer.getCellHeight();
}
}
/**
* Moves cursor one tile left
*/
public void moveLeft() {
cursorX = cursorX - imageLayer.getCellWidth();
if (cursorX < getWidthDiff() / 2) {
cursorX = getWidthDiff() / 2;
}
}
/**
* Moves cursor one tile right.
*/
public void moveRight() {
cursorX = cursorX + imageLayer.getCellWidth();
if ( cursorX > IMAGE_WIDTH + getWidthDiff() / 2 - imageLayer.getCellWidth()) {
cursorX = IMAGE_WIDTH + getWidthDiff() / 2 - imageLayer.getCellWidth();
}
}
/**
* Gets the initial tile that the user has selected for transposition.
*/
public void setFirstBlock() {
firstCol = (cursorX - getWidthDiff() / 2) / imageLayer.getCellWidth();
firstRow = (cursorY - getHeightDiff() / 2) / imageLayer.getCellHeight();
firstBlock = imageLayer.getCell(firstCol , firstRow);
doublePaired = false;
}
/**
* Gets the destination tile selected by the user. Then interchanges the initial and
* destination tiles
*/
public void setSecondBlock() {
secondCol = (cursorX - getWidthDiff() / 2) / imageLayer.getCellWidth();
secondRow = (cursorY - getHeightDiff() / 2) / imageLayer.getCellHeight();
secondBlock = imageLayer.getCell(secondCol , secondRow);
// interchange two cells
imageLayer.setCell(firstCol , firstRow , secondBlock);
imageLayer.setCell(secondCol , secondRow , firstBlock);
doublePaired = true;
}
public void commandAction(Command command , Displayable displayable) {
if (command == exitCommand) {
midlet.exit();
} else if (command == hintCommand){
new Thread() {//to avoid blocking despatcher
public void run(){
midlet.displayHintCanvas(image);
}
}.start();
} else if (command == newCommand) {
midlet.displayChoiceForm();
image = null;
midlet = null;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -