Indonesia

Minggu, 29 Mei 2011

Membuat Game J2ME Bernama “PUSH PUZZLE”

game ini dibuat oleh kelompok delapan kelas 3ia16 yang beranggotakan :
1. agung arianto
2. barron satrio baskhoro
3. febriady yusuf kasmiran
game ini kami buat untuk memenuhi tugas dalam mata kuliah perkembangan technology game saat ini, yang di ajar oleh bapak remi senjaya.
pertama tama dalam kami akan menjelaskan tentang tujuan kami dalam membuat game push puzzle ini. Tujuan dari pembuatan game ini adalah untuk memahami lebih dalam tentang perkembangan game saat ini. Selain itu penulis juga bertujuan untuk meningkatkan daya pikir terhadap otak dalam pembuatan game ini. Dalam game ini terdapat permainan yang membutuhkan daya pikir yang baik dalam menyelesaikan game ini. jadi game ini dibuat agar kita dapat berpikir secara tepat dan akurat dalam memainkan game ini.
selanjutnya kami akan menjelaskan tentang cara memainkan game push puzzle ini, yaitu :
—Cara memainkanya cukup mudah, anda hanya akan disuruh untuk menyusun beberapa kotak yang tersebar dibeberapa bagian. Selanjutnya anda susun kotak tersebut secara berurutan sesuai dengan gambar kotak kotak yang sudah disediakan. Jika anda menuyusunya tidak sesuai dengan gambar kotak kotak yang disediakan, anda tidak dapat menyelesaikan game ini. Namun, dalam permainan pushpuzle ini tidak ada game over, disini anda bisa meng-undo jika anda salah langkah dalam memindahkan kotak tersebut. Didalam game ini terdapat tembok  yang menjadi penghalang buat anda dalam menyelesaikan game ini. Selanjutnya jika tidak bisa menyelesaikan game ini pada level tertentu, maka anda bisa memilih menu, lalu pilih ”next level”. Artinya adalah untuk menuju ke level berikutnya atau level yang kita inginkan, karena disini anda bisa memlih level yang anda inginkan. disini dalam game ini tidak terdapat game over, jad kita bisa pilih level yang menurut kita bisa lalui.
Dalam pembuatan game ini kita menggunakan spesifikasi hardware yang digunakan adalah :
1.Processor intel pentium 4.
2.Kapasitas RAM sebesar 512 mb.
3.Kapasitas hard disk 40 Gb.
4.Vga NVIDIA 64 mb.
selain hardware, kita juga menggunakan spesifikasi software berupa :
1.Windows XP-Service pack 2.
2.Java™2 SDK, Standard Edition Versi 1.5.0
3.Java™ Wireless Toolkit (J2ME WTK) Versi 2.5.2.
4.Notepad ++
Selanjutnya kami akan menjelaskan tentang listing dalam game ini, disini terdapat 4 coding java yang merupakan bagian dari pembuatan game ini. listing listing tersebut antara lain :
1.PUSHPUZZLE.JAVA
2.PUSHPUZZLECANVAS.JAVA
3.SCORE.JAVA
4.BOARD.JAVA
A.  PUSHPUZZLE.JAVA
listingnya adalah sebagai berikut :
 */
package example.pushpuzzle;import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;/**
* PushPuzzle is the MIDlet that drives the game.  It puts up the
* screens and handles all the commands that are invoked on each
* screen.
*/
public class PushPuzzle extends MIDlet implements CommandListener {
Display display;
private PushPuzzleCanvas canvas;
private Score score;
private Screen scoreScreen;
private Screen levelScreen;
private Alert alert;
private Command undoCommand = new Command(“Undo”, Command.BACK, 1);
private Command restartCommand = new Command(“Start Over”, Command.CANCEL, 21);
private Command exitCommand = new Command(“Exit”, Command.EXIT, 60);
private Command scoresCommand = new Command(“Show Scores”, Command.SCREEN, 26);
private Command okCommand = new Command(“OK”, Command.OK, 30);
private Command levelCommand = new Command(“Change Level”, Command.SCREEN, 24);
private Command nextCommand = new Command(“Next Level”, Command.SCREEN, 22);
private Command prevCommand = new Command(“Previous Level”, Command.SCREEN, 23);
private Command themeCommand = new Command(“Switch Theme”, Command.SCREEN, 25); /**
* Creates new PushPuzzle MIDlet.
*/
public PushPuzzle() {
display = Display.getDisplay(this);
score = new Score();
canvas = new PushPuzzleCanvas(this, score);
alert = new Alert(“Warning”);
if (!score.open()) {
System.out.println(“Score open failed”);
}
canvas.init();
canvas.addCommand(undoCommand);
canvas.addCommand(scoresCommand);
canvas.addCommand(restartCommand);
canvas.addCommand(levelCommand);
canvas.addCommand(exitCommand);
canvas.addCommand(nextCommand);
canvas.addCommand(prevCommand);
canvas.addCommand(themeCommand);
canvas.setCommandListener(this);
}
/**
* Start creates the thread to do the timing.
* It should return immediately to keep the dispatcher
* from hanging.
*/
public void startApp() {
display.setCurrent(canvas);
}
/**
* Pause signals the thread to stop by clearing the thread field.
* If stopped before done with the iterations it will
* be restarted from scratch later.
*/
public void pauseApp() {
}
/**
* Destroy must cleanup everything.
* Only objects exist so the GC will do all the cleanup
* after the last reference is removed.
*/
public void destroyApp(boolean unconditional) {
display.setCurrent(null);
canvas.destroy();
if (score != null) {
score.close();
}
}
/**
* Respond to a commands issued on any Screen
*/
public void commandAction(Command c, Displayable s) {
if (c == undoCommand) {
canvas.undoMove();
} else if (c == restartCommand) {
canvas.restartLevel();
} else if (c == levelCommand) {
levelScreen = canvas.getLevelScreen();
levelScreen.addCommand(okCommand);
levelScreen.setCommandListener(this);
display.setCurrent(levelScreen);
} else if ((c == okCommand) && (s == levelScreen)) {
if (!canvas.gotoLevel()) {
alert.setString(“Could not load level”);
display.setCurrent(alert, canvas);
} else {
display.setCurrent(canvas);
}
} else if (c == scoresCommand) {
scoreScreen = canvas.getScoreScreen();
scoreScreen.addCommand(okCommand);
scoreScreen.setCommandListener(this);
display.setCurrent(scoreScreen);
} else if ((c == okCommand) && (s == scoreScreen)) {
display.setCurrent(canvas);
} else if (c == exitCommand) {
destroyApp(false);
notifyDestroyed();
} else if ((c == List.SELECT_COMMAND) && (s == canvas)) {
// Solved the level
scoreScreen = canvas.getScoreScreen();
scoreScreen.addCommand(okCommand);
scoreScreen.setCommandListener(this);
display.setCurrent(scoreScreen);
// Read the next screen.
canvas.nextLevel(1);
} else if (c == nextCommand) {
if (!canvas.nextLevel(1)) {
alert.setString(“Could not load level ” + (canvas.getLevel() + 1));
display.setCurrent(alert, canvas);
} else {
display.setCurrent(canvas);
}
if (s == canvas) {
canvas.repaint();
}
} else if (c == prevCommand) {
if (!canvas.nextLevel(-1)) {
alert.setString(“Could not load level ” + (canvas.getLevel() – 1));
display.setCurrent(alert, canvas);
} else {
display.setCurrent(canvas);
}
if (s == canvas) {
canvas.repaint();
}
} else if (c == themeCommand) {
canvas.changeTheme();
}
}
}
statement diatas adalah listing untuk membuat tampilan awal pada game push puzzle ini. selain itu listing ini adalah untuk memilih level mana dan tema apa yang anda inginkan.
2.PUSHPUZZLECANVAS.JAVA
listingnya adalah sebagai berikut :
package example.pushpuzzle;import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.TiledLayer;
import javax.microedition.media.Manager;
import javax.microedition.media.Player;
import javax.microedition.media.control.ToneControl;
import java.io.IOException;
import java.io.InputStream; /**
* PushPuzzleCanvas displays the game board and handles key events.
* The PushPuzzle game logic and algorithms are separated into Board.java.
* PushPuzzleCanvas does not setup or use any Commands.  Commands for each
* screen and listeners should be setup outside this class.
* PushPuzzleCanvas generates a SELECT_COMMAND when the current level
* is solved. Sequencing through screens is done in the PushPuzzle MIDlet.
* <p/>
* PushPuzzleCanvas handles the reading, initialization, and sequencing
* of individual puzzle screens.
* <p/>
* PushPuzzleCanvas uses the Score class to restore and save game levels
* and scores for each level. To display the scores use getScoreScreen.
* It will be initialized with the current scores.
* To select a new level use the getLevelScreen and gotoLevel
* methods.
* <p/>
* PushPuzzleCanvas handled key events for LEFT, RIGHT, UP, and DOWN to
* move the pusher in the game board.  Pointer pressed events
* are used to move the pusher to the target location (if possible).
* <p/>
*/
class PushPuzzleCanvas extends GameCanvas implements Runnable {
/** Pan Rate; number of milliseconds between screen updates */
private static final int PanRate = 50;
private static final int GroundColor0 = 0xffffff;
private static final int PacketColor0 = 0xff6d00;
private static final int StoreColor0 = 0xb60055;
private static final int WallColor0 = 0x006D55;
private static final int PusherColor0 = 0x6d6dff;
/** The current level */
private int level = 1;
/** The current theme index */
private int theme;
/** True if the level has been solved */
private boolean solved;
/** number of pixels per cell (updated by readscreen) */
private int cell = 1;
/** The width of the canvas */
private int width;
/** The height of the canvas */
private int height;
/** The width of the board */
private int bwidth;
/** The height of the board */
private int bheight;
/** The board containing the location of each packet, ground, walls, etc */
private final Board board;
/** The score object */
private Score score;
/** The listener used to report solved events */
private CommandListener listener;
/** The TextBox to input new level numbers */
private TextBox levelText; // for input of new level
/** The index in the image of the Ground */
public final int TILE_GROUND = 1;
/** The index in the image of the Packet */
public final int TILE_PACKET = 2;
/** The index in the image of the Store */
public final int TILE_STORE = 3;
/** The index in the image of the Wall */
public final int TILE_WALL = 4;
/** The index in the image of the Pusher */
public final int TILE_PUSHER = 5;
/** Background image */
private Image themeImage;
/** Tiles forming the background */
private TiledLayer tiles;
/** The Sprite that is the pusher */
private Sprite sprite;
/** Layer manager */
private LayerManager layers;
/** Thread used for key handling and animation */
private Thread thread;
/** The target cell for runTo */
private int targetx;
/** The target cell for runTo */
private int targety;
/** The Tone player */
private Player tonePlayer;
/** The ToneController */
private ToneControl toneControl;
/** Tune to play when puzzle level is solved. */
private byte[] solvedTune = {ToneControl.VERSION, 1, 74, 8, // 1/8 note
75, 8, 73, 8};
/** Tune to play when a packet enters a store */
private byte[] storedTune = {ToneControl.VERSION, 1, 50, 8, // 1/8 note
60, 8, 70, 8};
/**
* Construct a new canvas
*
* @param pushpuzzle the main MIDlet
* @param s the score object
*/
public PushPuzzleCanvas(PushPuzzle pushpuzzle, Score s) {
super(false); // Don’t suppress key events
score = s;
board = new Board();
layers = new LayerManager();
setupTheme();
targetx = targety = -1;
height = getHeight();
width = getWidth();
}
/**
* Read the previous level number from the score file.
* Read in the level data.
*/
public void init() {
// Read the last level; if it can’t be found, revert to level 0
theme = score.getTheme();
setupTheme();
level = score.getLevel();
if (!readScreen(level)) {
level = 0;
readScreen(level);
}
}
/** Cleanup and destroy. */
public void destroy() {
hideNotify();
}
/**
* Change themes.
* Cycle to the next index and try it
*/
public void changeTheme() {
theme++;
setupTheme();
score.setLevel(level, theme); // save the level and theme
setupTiles();
updateSprite(0);
}
/**
* Undo the last move if possible. Redraw the cell
* the pusher occupies after the undone move and the cells
* in the direction of the original move.
* Here so undo can be triggered by a command.
*/
public void undoMove() {
int pos = board.getPusherLocation();
int dir = board.undoMove();
if (dir >= 0) {
updateTilesNear(pos, dir);
updateSprite(dir);
}
solved = board.solved();
}
/** Restart the current level. */
public void restartLevel() {
readScreen(level);
solved = false;
}
/**
* Start the next level.
*
* @param offset of the next level
* @return true if the new level was loaded
*/
public boolean nextLevel(int offset) {
updateScores(); // save best scores
if (((level + offset) >= 0) && readScreen(level + offset)) {
level += offset;
score.setLevel(level, theme);
solved = false;
return true;
}
return false;
}
/**
* Get the current level.
*
* @return the current level.
*/
public int getLevel() {
return level;
}
/**
* Get a screen to let the user change the level.
* A simple numeric TextBox will do.
*
* @return the textbox used to change the level number
*/
public Screen getLevelScreen() {
if (levelText == null) {
levelText =
new TextBox(“Enter Level”, Integer.toString(level), // default
4, TextField.NUMERIC);
} else {
levelText.setString(Integer.toString(level));
}
return levelText;
}
/**
* Go to the chosen Level.
*
* @return true if the new level was loaded.
*/
public boolean gotoLevel() {
if (levelText != null) {
String s = levelText.getString();
int l;
try {
l = Integer.parseInt(s);
} catch (java.lang.NumberFormatException e) {
return false;
}
updateScores();
if ((l >= 0) && readScreen(l)) {
level = l;
score.setLevel(level, theme);
solved = false;
return true;
}
}
return false;
}
/**
* Read and setup the next level.
* Opens the resource file with the name “/Screen.<lev>”
* and tells the board to read from the stream.
* <STRONG>Must be called only with the board locked.</STRONG>
*
* @param lev the level number to read.
* @return true if the reading of the level worked, false otherwise.
*/
private boolean readScreen(int lev) {
if (lev <= 0) {
board.screen0(); // Initialize the default zero screen.
} else {
InputStream is;
try {
is = getClass().getResourceAsStream(“/example/pushpuzzle/data/screen.” + lev);
if (is != null) {
board.read(is, lev);
is.close();
} else {
System.out.println(“Could not find the game board for level ” + lev);
return false;
}
} catch (java.io.IOException ex) {
return false;
}
}
bwidth = board.getWidth();
bheight = board.getHeight();
setupTiles();
updateSprite(0);
return true;
}
/** Create the Tiled layer to represent the current board. */
private void setupTiles() {
if (tiles != null) {
layers.remove(tiles);
}
// Figure out how many cells are needed to cover canvas.
int w = ((width + cell) – 1) / cell;
int h = ((height + cell) – 1) / cell;
tiles = new TiledLayer((w > bwidth) ? w : bwidth, (h > bheight) ? h : bheight, themeImage,
cell, cell);
/** Fill it all with background */
tiles.fillCells(0, 0, w, h, TILE_GROUND);
// Initialize the background tileset
for (int y = 0; y < bheight; y++) {
for (int x = 0; x < bwidth; x++) {
updateTile(x, y);
}
}
layers.append(tiles);
}
/**
* Update the tile at the location.
*
* @param x the offset of the tile to update
* @param y the offset of the tile to update
*/
private void updateTile(int x, int y) {
int tile;
byte v = board.get(x, y);
switch (v & ~Board.PUSHER) {
case Board.WALL:
tile = TILE_WALL;
break;
case Board.PACKET:
case Board.PACKET | Board.STORE:
tile = TILE_PACKET;
break;
case Board.STORE:
tile = TILE_STORE;
break;
case Board.GROUND:
default:
tile = TILE_GROUND;
}
tiles.setCell(x, y, tile);
}
/**
* Setup Theme-0 generated to match screen
* size and board size.
*/
private void setupTheme0() {
int bwidth = board.getWidth();
int bheight = board.getHeight();
int w = getWidth();
int h = getHeight(); // height of Canvas
cell = (((h – 14) / bheight) < (w / bwidth)) ? ((h – 14) / bheight) : (w / bwidth);
// Create a mutable image and initialize
themeImage = Image.createImage(cell * 5, cell);
Graphics g = themeImage.getGraphics();
g.setColor(GroundColor0);
g.fillRect((TILE_GROUND – 1) * cell, 0, cell * TILE_PUSHER, cell);
g.setColor(PacketColor0);
g.fillRect(((TILE_PACKET – 1) * cell) + 1, 1, cell – 2, cell – 2);
g.setColor(StoreColor0);
g.drawRect(((TILE_STORE – 1) * cell) + 1, 1, cell – 2, cell – 2);
g.setColor(WallColor0);
g.fillRect((TILE_WALL – 1) * cell, 0, cell, cell);
g.setColor(PusherColor0);
g.fillArc((TILE_PUSHER – 1) * cell, 0, cell, cell, 0, 360);
}
/**
* Setup the theme by reading the images and setting up
* the sprite and picking the tile size.
* Uses the current theme index.
* If the image with the current index can’t be found
* retry with theme = 0.
*
* @param image containing all the frames used for the board.
*/
private void setupTheme() {
if (sprite != null) {
layers.remove(sprite);
sprite = null;
}
if (theme > 0) {
try {
StringBuffer name = new StringBuffer(“/example/pushpuzzle/images/Theme-”);
name.append(theme);
name.append(“.png”);
themeImage = Image.createImage(name.toString());
// Cells are square using the minimum of the width and height
int h = themeImage.getHeight();
int w = themeImage.getWidth();
cell = (w < h) ? w : h;
} catch (IOException e) {
theme = 0;
setupTheme0();
}
} else {
setupTheme0();
}
sprite = new Sprite(themeImage, cell, cell);
sprite.defineReferencePixel(cell / 2, cell / 2);
int[] seq = new int[]{TILE_PUSHER – 1};
sprite.setFrameSequence(seq);
layers.insert(sprite, 0);
}
/**
* Return the Screen to display scores.
* It returns a screen with the current scores.
*
* @return a screen initialized with the current score information.
*/
public Screen getScoreScreen() {
int currPushes = board.getPushes();
int bestPushes = score.getPushes();
int currMoves = board.getMoves();
int bestMoves = score.getMoves();
boolean newbest = solved && ((bestPushes == 0) || (currPushes < bestPushes));
// Temp until form can do setItem
Form scoreForm = new Form(null);
scoreForm.append(new StringItem(newbest ? “New Best:\n” : “Current:\n”,
currPushes + ” pushes\n” + currMoves + ” moves”));
scoreForm.append(new StringItem(newbest ? “Old Best:\n” : “Best:\n”,
bestPushes + ” pushes\n” + bestMoves + ” moves”));
String title = “Scores”;
if (newbest) {
title = “Congratulations”;
}
scoreForm.setTitle(title);
return scoreForm;
}
/**
* Handle a repeated arrow keys as though it were another press.
*
* @param keyCode the key pressed.
*/
protected void keyRepeated(int keyCode) {
int action = getGameAction(keyCode);
switch (action) {
case Canvas.LEFT:
case Canvas.RIGHT:
case Canvas.UP:
case Canvas.DOWN:
keyPressed(keyCode);
break;
default:
break;
}
}
/**
* Handle a single key event.
* The LEFT, RIGHT, UP, and DOWN keys are used to
* move the pusher within the Board.
* Other keys are ignored and have no effect.
* Repaint the screen on every action key.
*/
protected void keyPressed(int keyCode) {
// Protect the data from changing during painting.
synchronized (board) {
cancelTo();
int action = getGameAction(keyCode);
int move;
switch (action) {
case Canvas.LEFT:
move = Board.LEFT;
break;
case Canvas.RIGHT:
move = Board.RIGHT;
break;
case Canvas.DOWN:
move = Board.DOWN;
break;
case Canvas.UP:
move = Board.UP;
break;
// case 0: // Ignore keycode that don’t map to actions.
default:
return;
}
// Tell the board to move the piece
int stored = board.getStored();
int dir = board.move(move);
if (stored < board.getStored()) {
// Play a note if a packet hit the spot.
play(storedTune);
}
int pos = board.getPusherLocation();
updateTilesNear(pos, dir);
updateSprite(dir);
} // End of synchronization on the Board.
}
/**
* Update the scores for the current level if it has
* been solved and the scores are better than before.
*/
private void updateScores() {
if (!solved) {
return;
}
int sp = score.getPushes();
int bp = board.getPushes();
int bm = board.getMoves();
/*
* Update the scores.  If the score for this level is lower
* than the last recorded score save the lower scores.
*/
if ((sp == 0) || (bp < sp)) {
score.setLevelScore(bp, bm);
}
}
/** Cancel the animation. */
private void cancelTo() {
targetx = -1;
targety = -1;
}
/**
* Called when the pointer is pressed.
* Record the target for the pusher.
*
* @param x location in the Canvas
* @param y location in the Canvas
*/
protected void pointerPressed(int x, int y) {
targetx = (x – tiles.getX()) / cell;
targety = (y – tiles.getY()) / cell;
}
/**
* Add a listener to notify when the level is solved.
* The listener is send a List.SELECT_COMMAND when the
* level is solved.
*
* @param l the object implementing interface CommandListener
*/
public void setCommandListener(CommandListener l) {
super.setCommandListener(l);
listener = l;
}
/**
* Update the Sprite location from the board supplied position
*
* @param dir the sprite is moving
*/
private void updateSprite(int dir) {
int loc = board.getPusherLocation();
int x = (loc & 0x7fff) * cell;
int y = ((loc >> 16) & 0x7fff) * cell;
// Update sprite location
sprite.setPosition(tiles.getX() + x, tiles.getY() + y);
dir = Board.RIGHT; // Graphics.drawRegion doesn’t do xofrm
switch (dir & 0×03) {
case Board.LEFT:
sprite.setTransform(Sprite.TRANS_ROT180);
break;
case Board.UP:
sprite.setTransform(Sprite.TRANS_ROT90);
break;
case Board.DOWN:
sprite.setTransform(Sprite.TRANS_ROT270);
break;
default:
sprite.setTransform(Sprite.TRANS_NONE);
break;
}
}
/**
* Queue a repaint for an area around the specified location.
*
* @param loc an encoded location from Board.getPusherLocation
* @param dir that the pusher moved and flag if it pushed a packet
*/
void updateTilesNear(int loc, int dir) {
int x = loc & 0x7fff;
int y = (loc >> 16) & 0x7fff;
// Update cells if any were moved
if ((dir >= 0) && ((dir & Board.MOVEPACKET) != 0)) {
updateTile(x, y);
updateTile(x + 1, y);
updateTile(x – 1, y);
updateTile(x, y + 1);
updateTile(x, y – 1);
}
}
/**
* Paint the contents of the Canvas.
* The clip rectangle of the canvas is retrieved and used
* to determine which cells of the board should be repainted.
*
* @param g Graphics context to paint to.
*/
public void paint(Graphics g) {
flushGraphics();
}
/**
* The canvas is being displayed.
* Stop the event handling and animation thread.
*/
protected void showNotify() {
thread = new Thread(this);
thread.start();
}
/**
* The canvas is being removed from the screen.
* Stop the event handling and animation thread.
*/
protected void hideNotify() {
thread = null;
}
/**
* The main event processor. Events are polled and
* actions taken based on the directional events.
*/
public void run() {
Graphics g = getGraphics(); // Of the buffered screen image
Thread mythread = Thread.currentThread();
// Loop handling events
while (mythread == thread) {
try { // Start of exception handler
boolean newlySolved = false;
if (!solved && board.solved()) {
newlySolved = solved = true;
play(solvedTune);
}
if (newlySolved && (listener != null)) {
listener.commandAction(List.SELECT_COMMAND, this);
}
if ((targetx >= 0) && (targety >= 0)) {
int dir = board.runTo(targetx, targety, 1);
int pos = board.getPusherLocation();
if (dir < 0) {
targetx = targety = -1; // Cancel target
} else {
updateTilesNear(pos, dir);
updateSprite(dir);
}
}
// Check that the pusher is not to close to the edge
int loc = board.getPusherLocation();
int x = (loc & 0x7fff) * cell;
int y = ((loc >> 16) & 0x7fff) * cell;
int lx = tiles.getX();
int ly = tiles.getY();
int panScale = cell / 4;
if (panScale < 1) {
panScale = 1;
}
// If the sprite is too near the edge (or off) pan
if ((lx + x) > (width – cell – cell)) {
tiles.move(-panScale, 0);
sprite.move(-panScale, 0);
}
if ((lx + x) < cell) {
tiles.move(panScale, 0);
sprite.move(panScale, 0);
}
if ((ly + y) > (height – cell – cell)) {
tiles.move(0, -panScale);
sprite.move(0, -panScale);
}
if ((ly + y) < cell) {
tiles.move(0, panScale);
sprite.move(0, panScale);
}
// Draw all the layers and flush
layers.paint(g, 0, 0);
if (mythread == thread) {
flushGraphics();
}
// g.drawString(“PushPuzzle Level ” + level, 0, height,
//                 Graphics.BOTTOM|Graphics.LEFT);
try {
mythread.sleep(PanRate);
} catch (java.lang.InterruptedException e) {
// Ignore
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/** Play the simple tune supplied. */
void play(byte[] tune) {
try {
if (tonePlayer == null) {
// First time open the tonePlayer
tonePlayer = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
tonePlayer.realize();
toneControl = (ToneControl) tonePlayer.getControl(
“javax.microedition.media.control.ToneControl”);
}
tonePlayer.deallocate();
toneControl.setSequence(tune);
tonePlayer.start();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
/*
* Close the tune player and release resources.
*/
void closePlayer() {
if (tonePlayer != null) {
toneControl = null;
tonePlayer.close();
tonePlayer = null;
}
}
listing ini bertujuan untuk mngatur control dalam game push puzzle ini.
3. BOARD.JAVA
Listingnya adalah sebagai berikut :
package example.pushpuzzle;import javax.microedition.lcdui.*; /**
* The class Board knows how the pieces move, handles undo, and
* handles reading of screens.
*/
public class Board {
// Move directions
public static final int LEFT = 0;
public static final int RIGHT = 3;
public static final int UP = 1;
public static final int DOWN = 2;
public static final int MOVEPACKET = 4;
// Bit definitions for pieces of each board position
public static final byte GROUND = 0; // If nothing there
public static final byte STORE = 1; // If it is a storage place
public static final byte PACKET = 2; // If it has a packet
public static final byte WALL = 4; // If it is a wall
public static final byte PUSHER = 8; // If the pusher is there
private int level;
private byte[] array;
private byte[] pathmap; // used for runTo to find shortest path
private int width;
private int height;
private int pusher; // position of the pusher at index into array
private int packets = 0; // total number of packets
private int stored = 0; // number of packets in Stores
private byte[] moves; // recorded moves
private int nmoves; // number of moves executed
private int npushes; // number of pushes executed
/**
* Creates new Board initialized to a simple puzzle.
*/
public Board() {
moves = new byte[200];
screen0();
}
/**
* Create the hard coded simple game board.
*/
public void screen0() {
width = 9;
height = 7;
array = new byte[width * height];
level = 0;
nmoves = 0;
npushes = 0;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
byte t =
((x == 0) || (y == 0) || (x == (width – 1)) || (y == (height – 1))) ? WALL
: GROUND;
set(x, y, t);
}
}
packets = 2;
stored = 0;
set(2, 2, PACKET);
set(4, 4, PACKET);
set(4, 2, STORE);
set(6, 4, STORE);
pusher = index(1, 1);
}
/**
* Move the pusher in the direction indicated.
* If there is a wall, don’t move.
* if there is a packet in that direction, try to move it.
* @param move the direction; one of LEFT, RIGHT, UP, DOWN
* @return the direction actually moved, -1 if not moved
*/
public int move(int move) {
int obj = pusher + indexOffset(move);
// Handle the simple cases
if ((array[obj] & WALL) != 0) {
return -1;
}
int m = movePacket(obj, move);
if (m < 0) {
return -1; // If can’t move packet, done!
}
pusher = obj; // move the pusher to the new spot
saveMove(m);
return m;
}
/**
* Move the packet in the direction indicated relative to
* the pusher.  If it fits into a store position remember.
* @return -1 if can’t be moved or the updated move
* including the packet flag if there was a packet to move.
*/
private int movePacket(int index, int move) {
if ((array[index] & PACKET) == 0) {
return move; // no packet to move
}
int dest = index + indexOffset(move);
if (array[dest] > STORE) {
return -1; // can’t move packet into next spot.
}
// Remove packet from current location
array[index] &= ~PACKET;
if ((array[index] & STORE) != 0) {
stored–;
}

// Insert packet into new location
array[dest] |= PACKET;
if ((array[dest] & STORE) != 0) {
stored++;
}
npushes++; // count pushes done
return move + MOVEPACKET;
}
/*
* Save a move, extending the array if necessary.
*/
private void saveMove(int move) {
if (nmoves >= moves.length) {
byte[] n = new byte[moves.length + 50];
System.arraycopy(moves, 0, n, 0, moves.length);
moves = n;
}
moves[nmoves++] = (byte)move;
}
/**
* Undo the most recent move
* @return the move undone;  if none -1 is returned;
*  See LEFT, RIGHT, UP, DOWN, and MOVEPACKET
*/
public int undoMove() {
if (nmoves <= 0) {
return -1;
}
int move = moves[--nmoves];
int rev = (move & 3) ^ 3; // reverse the direction
int back = pusher + indexOffset(rev);
if ((move & MOVEPACKET) != 0) {
npushes–; // “unpush”
movePacket(pusher + indexOffset(move), rev); // move packet
}
pusher = back;
return move;
}
/**
* Determine if the screen has been solved.
*/
public boolean solved() {
return packets == stored;
}
/**
* Move the player to the position (x,y), if possible. Return
* the direction it moved if successful, otherwise -1.
* The position (x,y) must be empty.
* @param x window coordinate
* @param y window coordinate
* @return the direction that it moved, -1 is not moved;
*  See LEFT, RIGHT, UP, DOWN, MOVEPACKET
*/
public int runTo(int x, int y, int max) {
int target = index(x, y);
if ((target < 0) || (target >= array.length)) {
return -1;
}
if (target == pusher) {
return -1; // already there
}
/* Fill the path map */
if ((pathmap == null) || (pathmap.length != array.length)) {
pathmap = new byte[array.length];
}
// Fill with unset value.
for (int i = 0; i < pathmap.length; i++)
pathmap[i] = 127;
// flood fill search to find a shortest path to the push point.
findTarget(target, (byte)0);
/*
* if we didn’t make it back to the players position,
* there is no valid path to that place.
*/
if (pathmap[pusher] == 127) {
return -1;
} else {
// We made it back, so let’s walk the path we just built up
// Save the final move to return
int pathlen = pathmap[pusher];
int pathmin = pathlen – max;
int dir = -1;
for (pathlen–; pathlen >= pathmin; pathlen–) {
if (pathmap[pusher - 1] == pathlen) {
dir = LEFT;
saveMove(dir);
pusher–;
} else if (pathmap[pusher + 1] == pathlen) {
dir = RIGHT;
saveMove(dir);
pusher++;
} else if (pathmap[pusher - width] == pathlen) {
dir = UP;
saveMove(dir);
pusher -= width;
} else if (pathmap[pusher + width] == pathlen) {
dir = DOWN;
saveMove(dir);
pusher += width;
} else {
/*
* if we get here, something is SERIOUSLY wrong,
* so we should abort
*/
throw new RuntimeException(“runTo abort”);
}
}
return dir;
}
}
/**
* Find the shortest path to the pusher via a fill search algorithm
*/
private void findTarget(int t, byte pathlen) {
if (array[t] > STORE) {
return; // Either a wall or looped back to player
}
// Already tried here and this way is longer
if (pathmap[t] <= pathlen) {
return;
}
pathmap[t] = pathlen++; // set path length to this location
if (t == pusher) {
return;
}
// avoiding ArrayIndexOutOfBoundException
if ((t – 1) >= 0) {
findTarget(t – 1, pathlen); // to previous cell
}
if ((t + 1) < array.length) {
findTarget(t + 1, pathlen); // to next cell
}
if ((t – width) >= 0) {
findTarget(t – width, pathlen); // to previous row
}
if ((t + width) < array.length) {
findTarget(t + width, pathlen); // to next row
}
}
/**
* Return the pieces at the location.
* @param x location in the board.
* @param y location in the board.
* @return flags indicating what pieces are in this board location.
* Bit flags; combinations of WALL, PUSHER, STORE, PACKET.
*/
public byte get(int x, int y) {
int offset = index(x, y);
if (offset == pusher) {
return (byte)(array[offset] | PUSHER);
} else {
return array[offset];
}
}
/**
* Set the value of the location.
*/
private void set(int x, int y, byte value) {
array[index(x, y)] = value;
}
/**
* Compute the index in the array of the x, y location.
*/
private int index(int x, int y) {
if ((x < 0) || (x >= width) || (y < 0) || (y >= height)) {
return -1;
}
return (y * width) + x;
}
/**
* Get the location of the pusher.
* It is returned as an int with the lower 16 bits being
* the x index and the upper 16 bits being the y index.
* @return the encoded location of the pusher.
*/
public int getPusherLocation() {
int x = pusher % width;
int y = pusher / width;
return (y << 16) + x;
}
/**
* Compute the offset in the array of the cell relative
* to the current pusher location in the direction of the move.
* Note: the walls around the edge always make a +/- guard band.
* Also, the order of evaluation should never try to get to +/- 2.
*/
private int indexOffset(int move) {
switch (move & 3) {
case LEFT:
return -1;
case RIGHT:
return +1;
case UP:
return -width;
case DOWN:
return +width;
}
return 0;
}
/**
* Read a board from a stream.
* Read it into a fixed size array and then shrink to fit.
*/
public void read(java.io.InputStream is, int l) {
final int W = 20;
final int H = 20;
byte[] b = new byte[W * H];
// Add resize code later.
int c;
// Add resize code later.
int w = 0;
int x = 0;
int y = 0;
int xn = 0;
int yn = 0;
int npackets = 0;
try {
while ((c = is.read()) != -1) {
switch (c) {
case ‘\n’:
if (x > w) {
w = x;
}
y++;
x = 0;
break;
case ‘$’:
b[(y * W) + x++] = PACKET;
npackets++;
break;
case ‘#’:
b[(y * W) + x++] = WALL;
break;
case ‘ ‘:
b[(y * W) + x++] = GROUND;
break;
case ‘.’:
b[(y * W) + x++] = STORE;
break;
case ‘*’:
b[(y * W) + x] = PACKET;
b[(y * W) + x++] |= STORE;
npackets++;
stored++;
break;
case ‘+’: // player and store in same place
b[(y * W) + x++] = STORE;
case ‘@’:
xn = x;
yn = y;
x++;
break;
}
}
} catch (java.io.IOException ex) {
ex.printStackTrace();
}
if (y > 0) {
array = new byte[w * y];
if (y > w) { // Switch x for y while copying
width = y;
height = w;
for (y = 0; y < width; y++) {
for (x = 0; x < w; x++) {
array[index(y, x)] = b[(y * W) + x];
}
}
pusher = index(yn, xn);
} else {
width = w;
height = y;
array = new byte[width * height];
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
array[index(x, y)] = b[(y * W) + x];
}
}
pusher = index(xn, yn);
}
stored = 0;
packets = npackets;
level = l;
nmoves = 0;
npushes = 0;
}
}
/**
* Get the width of the game board.
*/
public int getWidth() {
return width;
}
/**
* Get the height of the board.
*/
public int getHeight() {
return height;
}
/**
* Get the number of moves to get this far.
*/
public int getMoves() {
return nmoves;
}
/**
* Get the number of packets pushed around.
*/
public int getPushes() {
return npushes;
}
/**
* Get the number of packets stored.
*/
public int getStored() {
return stored;
}
/**
* Convert a left/right direction into an offset.
*/
private int dx(int dir) {
if (dir == LEFT) {
return -1;
}
if (dir == RIGHT) {
return +1;
}
return 0;
}
/**
* Convert a up/down direction into an offset.
*/
private int dy(int dir) {
if (dir == UP) {
return -1;
}
if (dir == DOWN) {
return +1;
}
return 0;
}
}
listing ini adalah untuk mengkonfigurasikan antara control pada keyboard atau joystik dengan game ini.
4.SCORE.JAVA
Listingnya adalah sebagai berikut :
package example.pushpuzzle;import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException; /**
* Keep track of the last level played.
* For each level keep track of the number of moves.
* <p>
* The scores are kept in a RecordStore named PushPuzzleScores.
* There are two types of records:
* – Last level
* – Level history
*   Name of level (either resource name “/…” or…)
*/
class Score {
private static final int LEVEL_LEN = 9;
private static final byte LEVEL_TAG = 1;
private static final int SCORE_LEN = 13;
private static final byte SCORE_TAG = 2;
// Current level record = {byte LEVEL_TAG; int level;}
private int levelId; // The record Id of the level record
private byte[] levelRec; // Byte array holding the level
// Score for level = {byte SCORE_TAG; int level, int pushes; int moves;}
private int scoreId; // The record Id of the current level
private byte[] scoreRec; // scores for the current level.
private RecordStore store; // Record store, null if not open
/*
* Construct a new Score handler.
*/
Score() {
store = null;
levelId = 0;
levelRec = new byte[LEVEL_LEN];
levelRec[0] = LEVEL_TAG;
putInt(levelRec, 1, 0);
putInt(levelRec, 5, 0);
scoreId = 0;
scoreRec = new byte[SCORE_LEN];
scoreRec[0] = SCORE_TAG;
putInt(scoreRec, 1, 0);
}
/**
* Open the record store and locate
* the record with the level number in it.
*/
boolean open() {
try {
store = RecordStore.openRecordStore(“PushPuzzleScores”, true);
} catch (RecordStoreException ex) {
}
if (store == null) {
return false;
}
try {
/*
* Locate the record containing the level.
*/
levelId = 0;
RecordEnumeration enm = store.enumerateRecords(null, null, false);
while (enm.hasNextElement()) {
int ndx = enm.nextRecordId();
if (store.getRecordSize(ndx) == LEVEL_LEN) {
int l = store.getRecord(ndx, levelRec, 0);
if ((l == LEVEL_LEN) && (levelRec[0] == LEVEL_TAG)) {
levelId = ndx;
break;
}
}
}
} catch (RecordStoreException ex) {
ex.printStackTrace();
return false;
}
return true;
}
/**
* Get the current Theme number.
*/
int getTheme() {
return getInt(levelRec, 5);
}
/**
* Retrieve the level from the level record.  It should
* have already been read from the store or created.
* The first byte is a tag, the second byte the level.
*/
int getLevel() {
return getInt(levelRec, 1);
}
/**
* Set the level and theme into the RecordStore.
* @param level the current level
* @param theme the current theme
*/
boolean setLevel(int level, int theme) {
putInt(levelRec, 1, level);
putInt(levelRec, 5, theme);
putInt(scoreRec, 1, level);
if (store == null) {
return false;
}
try {
if (levelId == 0) {
levelId = store.addRecord(levelRec, 0, levelRec.length);
} else {
store.setRecord(levelId, levelRec, 0, levelRec.length);
}
} catch (RecordStoreException ex) {
System.out.println(“RecordStoreException”);
ex.printStackTrace();
return false;
}
readScore(level); // get the score for the level
return true;
}
/**
* Get the number of pushes on the current level.
*/
int getPushes() {
return getInt(scoreRec, 5);
}
/**
* Get the number of moved on the current level.
*/
int getMoves() {
return getInt(scoreRec, 9);
}
/**
* Read the score for the current level.
* Read through the records looking for the one for this level.
*/
boolean readScore(int level) {
try {
scoreId = 0;
// Locate the matching record
RecordEnumeration enm = store.enumerateRecords(null, null, false);
while (enm.hasNextElement()) {
int ndx = enm.nextRecordId();
if (store.getRecordSize(ndx) == SCORE_LEN) {
int l = store.getRecord(ndx, scoreRec, 0);
if ((l == SCORE_LEN) && (scoreRec[0] == SCORE_TAG) &&
(getInt(scoreRec, 1) == level)) {
scoreId = ndx;
return true;
}
}
}
} catch (RecordStoreException ex) {
ex.printStackTrace();
return false;
}
// No record found, start fresh
scoreRec[0] = SCORE_TAG;
putInt(scoreRec, 1, level);
putInt(scoreRec, 5, 0);
putInt(scoreRec, 9, 0);
return true;
}
/**
* Set the updated score to the RecordStore.
*/
boolean setLevelScore(int pushes, int moves) {
// Update the scores in the buffer.
putInt(scoreRec, 5, pushes);
putInt(scoreRec, 9, moves);
try {
// Write/Add the record to the  store
if (scoreId == 0) {
scoreId = store.addRecord(scoreRec, 0, scoreRec.length);
} else {
store.setRecord(scoreId, scoreRec, 0, scoreRec.length);
}
} catch (RecordStoreException ex) {
ex.printStackTrace();
return false;
}
return true;
}
/**
* Get an integer from an array.
*/
private int getInt(byte[] buf, int offset) {
return ((buf[offset + 0] & 0xff) << 24) | ((buf[offset + 1] & 0xff) << 16) |
((buf[offset + 2] & 0xff) << 8) | (buf[offset + 3] & 0xff);
}
/**
* Put an integer to an array
*/
private void putInt(byte[] buf, int offset, int value) {
buf[offset + 0] = (byte)((value >> 24) & 0xff);
buf[offset + 1] = (byte)((value >> 16) & 0xff);
buf[offset + 2] = (byte)((value >> 8) & 0xff);
buf[offset + 3] = (byte)((value >> 0) & 0xff);
}
/**
* Close the store.
*/
void close() {
try {
if (store != null) {
store.closeRecordStore();
}
} catch (RecordStoreException ex) {
ex.printStackTrace();
}
}
}
ini adalah listing ubtuk memberikan pengaturan skor ketika anda berhasil memindahkan kotak kotak tersebut sesuai dengan bata yang ditentukan.
Selanjutnya kami akan menambahkan tamilan pada game ini, tampilanya adalah sebagai berikut :
ini adalah tampilan awal dalam memulai game push puzzle ini.
lalu tampilan ke duanya adalah sebagai berikut :
selanjutnya adalah kami akan menampilkan level yang lainya, adalah sebagai berikut :
dan terakhir adalah akan menampilkan tema yang lainya dengan level yang sama seperti diatas.
 
 
disini kami juga memberi link kepada anda yang telah membaca postingan ini, jika handphone anda berbasis java anda bisa mendownload game ini. alamatnya adalah ebagai berikut :
http://www.ziddu.com/download/15133965/GamesPushPuzzle.rar.html
Didalamnya sudah terdapat  folder lengkap beserta listingnya dan pada folder bin terdapat file berekstensi .jar yang langsung bisa anda kirim  ke hp anda, dan anda bisa langsung menginstallnya di handphone anda yang berbasis java.
sekian dari penjelasan kami di postingan kali ini, terima kasih.
salam dari kami kelompok delapan kelas 3IA16