Criando o jogo Labirinto para dispositivos móveis
Veja nesta dica como desenvolver o jogo Labirinto para aparelhos J2ME.
import
java.util.Random;
import
java.util.Vector;
import
javax.microedition.midlet.*;
import
javax.microedition.lcdui.*;
public class
Maze
extends
MIDlet
implements
CommandListener {
private
MazeCanvas myCanvas;
private
SelectScreen mySelectScreen;
private
Command myExitCommand =
new
Command(
"Exit"
, Command.EXIT,
99
);
private
Command myNewCommand =
new
Command(
"New Maze"
, Command.SCREEN,
1
);
private
Command myAlertDoneCommand =
new
Command(
"Done"
, Command.EXIT,
1
);
private
Command myPrefsCommand
=
new
Command(
"Size Preferences"
, Command.SCREEN,
1
);
public
Maze() {
try
{ myCanvas =
new
MazeCanvas(Display.getDisplay(
this
));
myCanvas.addCommand(myExitCommand);
myCanvas.addCommand(myNewCommand);
myCanvas.addCommand(myPrefsCommand);
myCanvas.setCommandListener(
this
);
}
catch
(Exception e) {
Alert errorAlert =
new
Alert(
"error"
,
e.getMessage(), null, AlertType.ERROR);
errorAlert.setCommandListener(
this
);
errorAlert.setTimeout(Alert.FOREVER);
errorAlert.addCommand(myAlertDoneCommand);
Display.getDisplay(
this
).setCurrent(errorAlert);
}
}
public void
startApp()
throws
MIDletStateChangeException {
if
(myCanvas !=
null
) {
myCanvas.start();
}
}
public void
destroyApp(
boolean
unconditional)
throws
MIDletStateChangeException {
myCanvas =
null
;
System.gc();
}
public void
pauseApp() {
}
public void
commandAction(Command c, Displayable s) {
if
(c == myNewCommand) {
myCanvas.newMaze();
}
else if
(c == myAlertDoneCommand) {
try
{
destroyApp(
false
);
notifyDestroyed();
}
catch
(MIDletStateChangeException ex) {
}
}
else if
(c == myPrefsCommand) {
if
(mySelectScreen ==
null
) {
mySelectScreen =
new
SelectScreen(myCanvas);
}
Display.getDisplay(
this
).setCurrent(mySelectScreen);
}
else if
(c == myExitCommand) {
try
{
destroyApp(
false
);
notifyDestroyed();
}
catch
(MIDletStateChangeException ex) {
}
}
}
}
class
MazeCanvas
extends
javax.microedition.lcdui.Canvas {
public static final int
BLACK =
0
;
public static final int
WHITE =
0xffffff
;
private
Display myDisplay;
private
Grid myGrid;
private boolean
myGameOver =
false
;
private int
mySquareSize;
private int
myMaxSquareSize;
private int
myMinSquareSize;
private int
myStartX =
0
;
private int
myStartY =
0
;
private int
myGridHeight;
private int
myGridWidth;
private int
myMaxGridWidth;
private int
myMinGridWidth;
private int
myOldX =
1
;
private int
myOldY =
1
;
private int
myPlayerX =
1
;
private int
myPlayerY =
1
;
int
setColWidth(
int
colWidth) {
if
(colWidth <
2
) {
mySquareSize =
2
;
}
else
{
mySquareSize = colWidth;
}
myGridWidth = getWidth() / mySquareSize;
if
(myGridWidth %
2
==
0
) {
myGridWidth -=
1
;
}
myGridHeight = getHeight() / mySquareSize;
if
(myGridHeight %
2
==
0
) {
myGridHeight -=
1
;
}
myGrid =
null
;
return
(myGridWidth);
}
int
getMinColWidth() {
return
(myMinSquareSize);
}
int
getMaxColWidth() {
return
(myMaxSquareSize);
}
int
getMaxNumCols() {
return
(myMaxGridWidth);
}
int
getColWidth() {
return
(mySquareSize);
}
int
getNumCols() {
return
(myGridWidth);
}
public
MazeCanvas(Display d)
throws
Exception {
myDisplay = d;
int
width = getWidth();
int
height = getHeight();
mySquareSize =
5
;
myMinSquareSize =
3
;
myMaxGridWidth = width / myMinSquareSize;
if
(myMaxGridWidth %
2
==
0
) {
myMaxGridWidth -=
1
;
}
myGridWidth = width / mySquareSize;
if
(myGridWidth %
2
==
0
) {
myGridWidth -=
1
;
}
myGridHeight = height / mySquareSize;
if
(myGridHeight %
2
==
0
) {
myGridHeight -=
1
;
}
myMinGridWidth =
15
;
myMaxSquareSize = width / myMinGridWidth;
if
(myMaxSquareSize > height / myMinGridWidth) {
myMaxSquareSize = height / myMinGridWidth;
}
if
(myMaxSquareSize < mySquareSize) {
throw
(
new
Exception(
"Display too small"
));
}
}
void
start() {
myDisplay.setCurrent(
this
);
repaint();
}
void
newMaze() {
myGameOver =
false
;
myGrid =
null
;
myPlayerX =
1
;
myPlayerY =
1
;
myOldX =
1
;
myOldY =
1
;
myDisplay.setCurrent(
this
);
repaint();
}
protected void
paint(Graphics g) {
if
(myGrid ==
null
) {
int
width = getWidth();
int
height = getHeight();
myGrid =
new
Grid(myGridWidth, myGridHeight);
for
(
int
i =
0
; i < myGridWidth; i++) {
for
(
int
j =
0
; j < myGridHeight; j++) {
if
(myGrid.mySquares[i][j] ==
0
) {
g.setColor(BLACK);
}
else
{
g.setColor(WHITE);
}
g.fillRect(myStartX + (i*mySquareSize),
myStartY + (j*mySquareSize),
mySquareSize, mySquareSize);
}
}
g.setColor(BLACK);
g.fillRect(myStartX + ((myGridWidth-
1
) * mySquareSize),
myStartY, width, height);
g.setColor(WHITE);
g.fillRect(myStartX + ((myGridWidth-
1
) * mySquareSize),
myStartY + ((myGridHeight-
2
) * mySquareSize), width, height);
g.setColor(BLACK);
g.fillRect(myStartX,
myStartY + ((myGridHeight-
1
) * mySquareSize), width, height);
}
g.setColor(
255
,
0
,
0
);
g.fillRoundRect(myStartX + (mySquareSize)*myPlayerX,
myStartY + (mySquareSize)*myPlayerY,
mySquareSize, mySquareSize,
mySquareSize, mySquareSize);
if
((myOldX != myPlayerX) || (myOldY != myPlayerY)) {
g.setColor(WHITE);
g.fillRect(myStartX + (mySquareSize)*myOldX,
myStartY + (mySquareSize)*myOldY,
mySquareSize, mySquareSize);}
if
(myGameOver) {
int
width = getWidth();
int
height = getHeight();
Font font = g.getFont();
int
fontHeight = font.getHeight();
int
fontWidth = font.stringWidth(
"Maze Completed"
);
g.setColor(WHITE);
g.fillRect((width - fontWidth)/
2
, (height - fontHeight)/
2
,
fontWidth +
2
, fontHeight);
g.setColor(
255
,
0
,
0
);
g.setFont(font);
g.drawString(
"Maze Completed"
, (width - fontWidth)/
2
,
(height - fontHeight)/
2
,
g.TOP|g.LEFT);
}
}
public void
keyPressed(
int
keyCode) {
if
(! myGameOver) {
int
action = getGameAction(keyCode);
switch
(action) {
case
LEFT:
if
((myGrid.mySquares[myPlayerX-
1
][myPlayerY] ==
1
) &&
(myPlayerX !=
1
)) {
myOldX = myPlayerX;
myOldY = myPlayerY;
myPlayerX -=
2
;
repaint();
}
break
;
case
RIGHT:
if
(myGrid.mySquares[myPlayerX+
1
][myPlayerY] ==
1
) {
myOldX = myPlayerX;
myOldY = myPlayerY;
myPlayerX +=
2
;
repaint();
}
else if
((myPlayerX == myGrid.mySquares.length -
2
) &&
(myPlayerY == myGrid.mySquares[
0
].length -
2
)) {
myOldX = myPlayerX;
myOldY = myPlayerY;
myPlayerX +=
2
;
myGameOver =
true
;
repaint();
}
break
;
case
UP:
if
(myGrid.mySquares[myPlayerX][myPlayerY-
1
] ==
1
) {
myOldX = myPlayerX;
myOldY = myPlayerY;
myPlayerY -=
2
;
repaint();
}
break
;
case
DOWN:
if
(myGrid.mySquares[myPlayerX][myPlayerY+
1
] ==
1
) {
myOldX = myPlayerX;
myOldY = myPlayerY;
myPlayerY +=
2
;
repaint();
}
break
;
}
}
}
}
class
SelectScreen
extends
Form
implements
ItemStateListener, CommandListener {
private
Command myExitCommand =
new
Command(
"Done"
, Command.EXIT,
1
);
private
Gauge myWidthGauge;
private
Gauge myColumnsGauge;
private
MazeCanvas myCanvas;
public
SelectScreen(MazeCanvas canvas) {
super
(
"Size Preferences"
);
addCommand(myExitCommand);
setCommandListener(
this
);
myCanvas = canvas;
setItemStateListener(
this
);
myWidthGauge =
new
Gauge(
"Column Width"
, true,
myCanvas.getMaxColWidth(),
myCanvas.getColWidth());
myColumnsGauge =
new
Gauge(
"Number of Columns"
, false,
myCanvas.getMaxNumCols(),
myCanvas.getNumCols());
append(myWidthGauge);
append(myColumnsGauge);
}
public void
itemStateChanged(Item item) {
if
(item == myWidthGauge) {
int
val = myWidthGauge.getValue();
if
(val < myCanvas.getMinColWidth()) {
myWidthGauge.setValue(myCanvas.getMinColWidth());
}
else
{
int
numCols = myCanvas.setColWidth(val);
myColumnsGauge.setValue(numCols);
}
}
}
public void
commandAction(Command c, Displayable s) {
if
(c == myExitCommand) {
myCanvas.newMaze();
}
}
}
class
Grid {
private
Random myRandom =
new
Random();
int
[][] mySquares;
public
Grid(
int
width,
int
height) {
mySquares =
new int
[width][height];
for
(
int
i =
1
; i < width -
1
; i++) {
for
(
int
j =
1
; j < height -
1
; j++) {
if
((i %
2
==
1
) || (j %
2
==
1
)) {
mySquares[i][j] =
1
;
}
}
}
mySquares[
0
][
1
] =
1
;
createMaze();
}
private void
createMaze() {
// create an initial framework of black squares.
for
(
int
i =
1
; i < mySquares.length -
1
; i++) {
for
(
int
j =
1
; j < mySquares[i].length -
1
; j++) {
if
((i + j) %
2
==
1
) {
mySquares[i][j] =
0
;
}
}
}
for
(
int
i =
1
; i < mySquares.length -
1
; i+=
2
) {
for
(
int
j =
1
; j < mySquares[i].length -
1
; j+=
2
) {
mySquares[i][j] =
3
;
}
}
Vector possibleSquares =
new
Vector(mySquares.length
* mySquares[
0
].length);
int
[] startSquare =
new int
[
2
];
startSquare[
0
] = getRandomInt(mySquares.length /
2
)*
2
+
1
;
startSquare[
1
] = getRandomInt(mySquares[
0
].length /
2
)*
2
+
1
;
mySquares[startSquare[
0
]][startSquare[
1
]] =
2
;
possibleSquares.addElement(startSquare);
while
(possibleSquares.size() >
0
) {
int
chosenIndex = getRandomInt(possibleSquares.size());
int
[] chosenSquare = (
int
[])possibleSquares.elementAt(chosenIndex);
mySquares[chosenSquare[
0
]][chosenSquare[
1
]] =
1
;
possibleSquares.removeElementAt(chosenIndex);
link(chosenSquare, possibleSquares);
}
possibleSquares =
null
;
System.gc();
}
private void
link(
int
[] chosenSquare, Vector possibleSquares) {
int
linkCount =
0
;
int
i = chosenSquare[
0
];
int
j = chosenSquare[
1
];
int
[] links =
new int
[
8
];
if
(i >=
3
) {
if
(mySquares[i -
2
][j] ==
1
) {
links[
2
*linkCount] = i -
1
;
links[
2
*linkCount +
1
] = j;
linkCount++;
}
else if
(mySquares[i -
2
][j] ==
3
) {
mySquares[i -
2
][j] =
2
;
int
[] newSquare =
new int
[
2
];
newSquare[
0
] = i -
2
;
newSquare[
1
] = j;
possibleSquares.addElement(newSquare);
}
}
if
(j +
3
<= mySquares[i].length) {
if
(mySquares[i][j +
2
] ==
3
) {
mySquares[i][j +
2
] =
2
;
int
[] newSquare =
new int
[
2
];
newSquare[
0
] = i;
newSquare[
1
] = j +
2
;
possibleSquares.addElement(newSquare);
}
else if
(mySquares[i][j +
2
] ==
1
) {
links[
2
*linkCount] = i;
links[
2
*linkCount +
1
] = j +
1
;
linkCount++;
}
}
if
(j >=
3
) {
if
(mySquares[i][j -
2
] ==
3
) {
mySquares[i][j -
2
] =
2
;
int
[] newSquare =
new int
[
2
];
newSquare[
0
] = i;
newSquare[
1
] = j -
2
;
possibleSquares.addElement(newSquare);
}
else if
(mySquares[i][j -
2
] ==
1
) {
links[
2
*linkCount] = i;
links[
2
*linkCount +
1
] = j -
1
;
linkCount++;
}
}
if
(i +
3
<= mySquares.length) {
if
(mySquares[i +
2
][j] ==
3
) {
mySquares[i +
2
][j] =
2
;
int
[] newSquare =
new int
[
2
];
newSquare[
0
] = i +
2
;
newSquare[
1
] = j;
possibleSquares.addElement(newSquare);
}
else if
(mySquares[i +
2
][j] ==
1
) {
links[
2
*linkCount] = i +
1
;
links[
2
*linkCount +
1
] = j;
linkCount++;
}
}
if
(linkCount >
0
) {
int
linkChoice = getRandomInt(linkCount);
int
linkX = links[
2
*linkChoice];
int
linkY = links[
2
*linkChoice +
1
];
mySquares[linkX][linkY] =
1
;
int
[] removeSquare =
new int
[
2
];
removeSquare[
0
] = linkX;
removeSquare[
1
] = linkY;
possibleSquares.removeElement(removeSquare);
}
}
public int
getRandomInt(
int
upper) {
int
retVal = myRandom.nextInt() % upper;
if
(retVal <
0
) {
retVal += upper;
}
return
(retVal);
}
}