Criando o jogo Labirinto para dispositivos móveis

 

Veja nesta dica como desenvolver o jogo Labirinto para aparelhos J2ME.

 

fig01labirintoJ2ME.jpg           fig02labirintoJ2ME.jpg

 

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 % == 0) {
      myGridWidth -= 1;
    }
    myGridHeight = getHeight() / mySquareSize;
    if(myGridHeight % == 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 % == 0) {
      myMaxGridWidth -= 1;
    }
    myGridWidth = width / mySquareSize;
    if(myGridWidth % == 0) {
      myGridWidth -= 1;
    }
    myGridHeight = height / mySquareSize;
    if(myGridHeight % == 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(25500);
    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(25500);
      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 % == 1) || (j % == 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) % == 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)*1;
    startSquare[1] = getRandomInt(mySquares[0].length / 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 + <= 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 + <= 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);
  }

}