冰浪

          哥已不再年輕 - 堅定夢想,畢生追求!
          posts - 85, comments - 90, trackbacks - 0, articles - 3
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          J2ME連連看基礎(chǔ)功能源代碼

          Posted on 2009-04-09 10:25 冰浪 閱讀(264) 評論(0)  編輯  收藏 所屬分類: J2ME
          J2ME連連看基礎(chǔ)功能源代碼(含詳細注釋)
          作者:陳躍峰
          出自:http://blog.csdn.net/mailbomb

          //界面類代碼
          import javax.microedition.lcdui.Canvas;
          import javax.microedition.lcdui.Graphics;

          /**
           * 連連看游戲界面
           */
          public class LinkCanvas extends Canvas implements Runnable{
              /**游戲邏輯類*/
              GameEngine engine;   
              /**屏幕寬度*/
              int width;
              /**屏幕高度*/
              int height;
              public LinkCanvas(){
                  //創(chuàng)建對象
                  engine = new GameEngine();
                  //獲得屏幕的高度和寬度
                  width = getWidth();
                  height = getHeight();
                  //啟動線程
                  Thread t = new Thread(this);
                  t.start();
              }
             
              /**
               * 繪制方法
               */
              protected void paint(Graphics g) {
                  //清屏
                  clearScreen(g);
                  //繪制地圖
                  engine.paintMap(g);
                  //繪制選擇框
                  engine.paintSelectArea(g);
                  //繪制連線
                  engine.paintLinkLine(g);
              }
             
              /**
               * 清屏方法
               * @param g 畫筆
               */
              private void clearScreen(Graphics g){
                  g.setColor(0xffffff);
                  g.fillRect(0, 0, width, height);
                  g.setColor(0);
              }
             
              public void keyPressed(int keyCode){
                  int action = getGameAction(keyCode);
                  switch(action){
                  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();
                  }
              }
          }

          //邏輯類源代碼
          import java.util.*;
          import javax.microedition.lcdui.*;
          /**
           * 游戲數(shù)據(jù)和邏輯類
           */
          public class GameEngine {
              /**選中塊的個數(shù)*/
              private int selectTileNum = 0;
              //第一個選擇塊的行號和列號
              /**行號*/
              private int firstRow;
              /**列號*/
              private int firstCol;
              //第二個選擇塊的行號和列號
              /**行號*/
              private int secondRow;
              /**列號*/
              private int secondCol;
             
              //當(dāng)前選擇框,默認在左上角
              /**當(dāng)前選擇框的行號*/
              private int cRow;
              /**當(dāng)前選擇框的列號*/
              private int cCol;
             
              /**最大行數(shù)*/
              private final int MAX_ROW = 10;
              /**最大列數(shù)*/
              private final int MAX_COL = 10;
             
              /**地圖數(shù)據(jù),0代表空,數(shù)據(jù)1-10分別代表十種不同的結(jié)構(gòu)*/
              private int[][] map = new int[MAX_ROW][MAX_COL];
              /**隨機數(shù)對象*/
              private Random ran = new Random();
             
              //地圖區(qū)域左上角的坐標(biāo)
              private final int LEFTX = 20;
              private final int LEFTY = 50;
             
              /**每個單元格的寬度*/
              private final int TILE_WIDTH = 20;
              /**每個單元格的高度*/
              private final int TILE_HEIGHT = 20;
             
              /**連線類型*/
              private int linkType;
             
              /**無法連線*/
              private final int NO_LINK = 0;
              /**水平連線*/
              private final int H_LINK = 1;
              /**垂直聯(lián)系*/
              private final int V_LINK = 2;
              /**一個拐點,先移動x*/
              private final int ONE_CORNER_FIRSTX = 3;
              /**一個拐點,先移動y*/
              private final int ONE_CORNER_FIRSTY = 4;
              /**兩個拐點,待完善*/
              private final int TWO_CORNER = 5;
             
              /**
               * 兩次拐彎的行號和列號
               * 數(shù)據(jù)格式為:
               *   第一個拐點的行號,第一個拐點的列號,第二個拐點的行號,第二個拐點的列號
               */
              int[] p = new int[4];
             
              public GameEngine(){
                  //初始化地圖數(shù)據(jù)
                  initMap();
              }
             
              /**
               * 初始化地圖數(shù)據(jù)
               */
              private void initMap(){
                  for(int row = 0;row < map.length;row++){
                      for(int col = 0;col < map[row].length;col++){
                          map[row][col] = row + 1;
                      }
                  }
                  //循環(huán)打亂10次
                  int tempRow;
                  int tempCol;
                  int temp;
                  for(int i = 0;i < 10;i++){
                      for(int row = 0;row < map.length;row++){
                          for(int col = 0;col < map[row].length;col++){
                              //隨機行號
                              tempRow = Math.abs(ran.nextInt() % 10);
                              //隨機列號
                              tempCol = Math.abs(ran.nextInt() % 10);
                              //如果不是同一個單元格,則交換數(shù)據(jù)
                              if(!((tempRow == row) && (tempCol == col))){
                                  temp = map[row][col];
                                  map[row][col] = map[tempRow][tempCol];
                                  map[tempRow][tempCol] = temp;
                              }
                          }
                      }
                  }
              }
             
              /**
               * 繪制地圖數(shù)據(jù)
               * @param g 畫筆
               */
              public void paintMap(Graphics g){
                  for(int row = 0;row < map.length;row++){
                      for(int col = 0;col < map[row].length;col++){
                          //如果沒有數(shù)據(jù),則跳過
                          if(map[row][col] == 0){
                              continue;
                          }else{//繪制方塊
                              //繪制方框
                              g.drawRect(LEFTX + col * TILE_WIDTH, LEFTY + row * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
                              //繪制數(shù)字
                              g.drawString(String.valueOf(map[row][col]), LEFTX + col * TILE_WIDTH + 5,
                                      LEFTY + row * TILE_HEIGHT + 4,
                                      Graphics.TOP | Graphics.LEFT);
                          }
                      }
                  }
              }
             
              /**
               * 繪制選擇框
               * @param g 畫筆
               */
              public void paintSelectArea(Graphics g){
                  //繪制當(dāng)前選擇框
                  g.setColor(0xff00);
                  g.drawRect(LEFTX + cCol * TILE_WIDTH, LEFTY + cRow * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
                  g.setColor(0);
                 
                  //繪制選中項
                  switch(selectTileNum){
                  case 1:  //選擇一個
                      g.setColor(0xff0000);
                      g.drawRect(LEFTX + firstCol * TILE_WIDTH, LEFTY + firstRow * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
                      g.setColor(0);
                      break;
                  case 2:  //選中兩個
                      g.setColor(0xff0000);
                      g.drawRect(LEFTX + firstCol * TILE_WIDTH, LEFTY + firstRow * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
                      g.drawRect(LEFTX + secondCol * TILE_WIDTH, LEFTY + secondRow * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
                      g.setColor(0);
                      break;
                  }
              }
             
              /**
               * 繪制方塊連線
               * @param g 畫筆
               */
              public void paintLinkLine(Graphics g){
                  //如果無連線,則直接返回
                  if(linkType == NO_LINK){
                      return;
                  }
                  //根據(jù)連線類型實現(xiàn)繪制
                  //繪制到方塊的中心點
                  switch(linkType){
                  case H_LINK://水平
                  case V_LINK://垂直
                      paintLine(g,firstRow,firstCol,secondRow,secondCol);
                      break;
                  case ONE_CORNER_FIRSTX://一個拐彎,先移動X
                      //水平線
                      paintLine(g,firstRow,firstCol,firstRow,secondCol);
                      //垂直線
                      paintLine(g,firstRow,secondCol,secondRow,secondCol);
                      break;
                  case ONE_CORNER_FIRSTY://一個拐彎,先移動Y
                      //水平線
                      paintLine(g,firstRow,firstCol,secondRow,firstCol);
                      //垂直線
                      paintLine(g,secondRow,firstCol,secondRow,secondCol);
                      break;
                  case TWO_CORNER:
                      //塊1到第一個拐點的連線
                      paintLine(g,firstRow,firstCol,p[0],p[1]);
                      //兩個拐點之間的連線
                      paintLine(g,p[0],p[1],p[2],p[3]);
                      //第二個拐點到塊2的連線
                      paintLine(g,p[2],p[3],secondRow,secondCol);
                      break;
                  }
                  //邏輯代碼,清除連接類型
                  linkType = NO_LINK;
              }
             
              /**
               * 繪制兩個方塊中心點的連線
               * @param g  畫筆
               * @param r1 方塊1的行號
               * @param c1 方塊1的列號
               * @param r2 方塊2的行號
               * @param c2 方塊2的列號
               */
              private void paintLine(Graphics g,int r1,int c1,int r2,int c2){
                  g.drawLine(LEFTX + c1 * TILE_WIDTH + TILE_WIDTH/2,
                          LEFTY + r1 * TILE_HEIGHT + TILE_HEIGHT/2,
                          LEFTX + c2 * TILE_WIDTH + TILE_WIDTH/2,
                          LEFTY + r2 * TILE_HEIGHT + TILE_HEIGHT/2);
                 
              }
             
              /**
               * 向左移動選擇框
               */
              public void moveLeft(){
                  if(cCol > 0){
                      cCol--;
                  }
              }
             
              /**
               * 向右移動選擇框
               */
              public void moveRight(){
                  if(cCol < MAX_COL -1){
                      cCol++;
                  }
              }
             
              /**
               * 向上移動選擇框
               */
              public void moveUP(){
                  if(cRow > 0){
                      cRow--;
                  }
              }
             
              /**
               * 向下移動選擇框
               */
              public void moveDown(){
                  if(cRow < MAX_ROW - 1){
                      cRow++;
                  }
              }
             
              /**
               * 確定鍵邏輯處理
               */
              public void fire(){
                  //如果選擇的塊為空,則直接返回
                  if(map[cRow][cCol] == 0){
                      return;
                  }
                  //選中的塊的數(shù)量增加1
                  selectTileNum++;
                  //判別存儲位置
                  switch(selectTileNum){
                  case 1: //第一次選擇
                      firstRow = cRow;
                      firstCol = cCol;
                      break;
                  case 2: //第二次選擇
                      //選擇同一個塊,2個選擇塊都失去選中
                      if((firstRow == cRow) && (firstCol == cCol)){
                          selectTileNum = 0;
                          return;
                      }
                      secondRow = cRow;
                      secondCol = cCol;
                      break;
                  }
              }
             
              /**
               * 判斷(r1,c1)塊和(r2,c2)塊中間是否為空行
               * 不包含這兩個塊
               * @param r1 塊1的行號
               * @param c1 塊1的列號
               * @param r2 塊2的行號
               * @param c2 塊2的列號
               * @return true代表為空,false代表不為空
               */     
              private boolean isEmptyRow(int r1,int c1,int r2,int c2){
                  //判斷是否位于同一行
                  if(r1 != r2){
                      return false;
                  }
                  //判斷兩個塊的相對位置
                  if(c1 > c2){ //第一塊位于右側(cè)
                      for(int col = c1 - 1;col > c2;col--){
                          //如果有非空塊
                          if(map[r1][col] != 0){
                              return false;
                          }
                      }
                  }else{ //第一塊位于左側(cè)
                      for(int col = c2 - 1;col > c1;col--){
                          //如果有非空塊
                          if(map[r1][col] != 0){
                              return false;
                          }
                      }
                  }
                  return true;
              }
             
              /**
               * 判斷塊(r1,c1)和塊(r2,c2)之間是否是空列
               * 不包含這兩個塊
               * @param r1 塊1的行號
               * @param c1 塊1的列號
               * @param r2 塊2的行號
               * @param c2 塊2的列號
               * @return true代表為空,false代表不為空
               */
              private boolean isEmptyCol(int r1,int c1,int r2,int c2){
                  //判斷是否位于同一列
                  if(c1 != c2){
                      return false;
                  }
                  //判斷兩個塊的相對位置
                  if(r2 > r1){//第一個塊在上方
                      for(int row = r1 + 1;row < r2;row++){
                          //如果有非空塊
                          if(map[row][c1] != 0){
                              return false;
                          }
                      }
                  }else{//第二個塊在上方
                      for(int row = r2 + 1;row < r1;row++){
                          //如果有非空塊
                          if(map[row][c1] != 0){
                              return false;
                          }
                      }
                  }
                  return true;
              }
             
              /**
               * 判斷一個塊是否為空
               * @param r 塊的行號
               * @param c 塊的列號
               * @return true代表為空,false代表不空
               */
              private boolean isEmptyCell(int r,int c){
                  return map[r][c] == 0;
              }   
                 
              /**
               * 是否是一次轉(zhuǎn)彎實現(xiàn)連線
               * @return NO_LINK代表沒有連線,其他值代表對應(yīng)的連線類型
               */
              private int isOneCornerLink(int r1,int c1,int r2,int c2){
                  //先移動行,再移動列
                  if(isEmptyCell(r1,c2)){ //轉(zhuǎn)折點為空
                      if(isEmptyRow(r1,c1,r1,c2) & isEmptyCol(r1,c2,r2,c2)){
                          return ONE_CORNER_FIRSTX;
                      }
                  }
                  //先移動列,再移動行
                  if(isEmptyCell(r2,c1)){//轉(zhuǎn)折點為空
                      if(isEmptyCol(r1,c1,r2,c1) & isEmptyRow(r2,c1,r2,c2)) {
                          return ONE_CORNER_FIRSTY;
                      }
                  }
                  //無連接
                  return NO_LINK;
              }
             
              /**
               * 是否經(jīng)過2次轉(zhuǎn)折實現(xiàn)連接
               * @param r1 塊1的行號
               * @param c1 塊1的列號
               * @param r2 塊2的行號
               * @param c2 塊2的列號
               * @return true代表可以連接,false代表不能
               */
              private boolean isTwoCornerLink(int r1,int c1,int r2,int c2){
                  int result;
                  //正常情況,劃分成4個方向
                  //塊1向上
                  for(int row = r1 -1;row >= 0;row--){
                      //如果有數(shù)據(jù)不為空,則直接結(jié)束該方向的嘗試
                      if(map[row][c1] != 0){
                          break;
                      }
                      //存儲第一個拐點的坐標(biāo)
                      p[0] = row;
                      p[1] = c1;
                      //每次都嘗試轉(zhuǎn)折,則變成一個轉(zhuǎn)點的操作
                      result = isOneCornerLink(row,c1,r2,c2);
                      //如果可以連接
                      if(result != NO_LINK){
                          //存儲第二個拐點的位置
                          switch(result){
                          case ONE_CORNER_FIRSTX:
                              p[2] = row;
                              p[3] = c2;
                              break;
                          case ONE_CORNER_FIRSTY:
                              p[2] = r2;
                              p[3] = c1;
                              break;
                          }
                          return true;
                      }
                  }
                  //塊1向下
                  for(int row = r1 + 1;row < MAX_ROW;row++){
                      //如果有數(shù)據(jù)不為空,則直接結(jié)束該方向的嘗試
                      if(map[row][c1] != 0){
                          break;
                      }
                      //存儲第一個拐點的坐標(biāo)
                      p[0] = row;
                      p[1] = c1;
                      //每次都嘗試轉(zhuǎn)折,則變成一個轉(zhuǎn)點的操作
                      result = isOneCornerLink(row,c1,r2,c2);
                      //如果可以連接
                      if(result != NO_LINK){
                          //存儲第二個拐點的位置
                          switch(result){
                          case ONE_CORNER_FIRSTX:
                              p[2] = row;
                              p[3] = c2;
                              break;
                          case ONE_CORNER_FIRSTY:
                              p[2] = r2;
                              p[3] = c1;
                              break;
                          }
                          return true;
                      }
                  }
                  //塊1向左
                  for(int col = c1 -1;col >= 0;col--){
                      //如果有數(shù)據(jù)不為空,則直接結(jié)束該方向的嘗試
                      if(map[r1][col] != 0){
                          break;
                      }
                      //存儲第一個拐點的坐標(biāo)
                      p[0] = r1;
                      p[1] = col;
                      //每次都嘗試轉(zhuǎn)折,則變成一個轉(zhuǎn)點的操作
                      result = isOneCornerLink(r1,col,r2,c2);
                      //如果可以連接
                      if(result != NO_LINK){
                          //存儲第二個拐點的位置
                          switch(result){
                          case ONE_CORNER_FIRSTX:
                              p[2] = r1;
                              p[3] = c2;
                              break;
                          case ONE_CORNER_FIRSTY:
                              p[2] = r2;
                              p[3] = col;
                              break;
                          }
                          return true;
                      }
                  }
                  //塊1向右
                  for(int col = c1  + 1;col < MAX_COL;col++){
                      //如果有數(shù)據(jù)不為空,則直接結(jié)束該方向的嘗試
                      if(map[r1][col] != 0){
                          break;
                      }
                      //存儲第一個拐點的坐標(biāo)
                      p[0] = r1;
                      p[1] = col;
                      //每次都嘗試轉(zhuǎn)折,則變成一個轉(zhuǎn)點的操作
                      result = isOneCornerLink(r1,col,r2,c2);
                      //如果可以連接
                      if(result != NO_LINK){
                          //存儲第二個拐點的位置
                          switch(result){
                          case ONE_CORNER_FIRSTX:
                              p[2] = r1;
                              p[3] = c2;
                              break;
                          case ONE_CORNER_FIRSTY:
                              p[2] = r2;
                              p[3] = col;
                              break;
                          }
                          return true;
                      }
                  }
                 
                  //四個特例,也就是超出地圖區(qū)域的連接
                  //實現(xiàn)地圖區(qū)域上側(cè)的連接,也就是到上側(cè)是一個空列
                  if((isEmptyCol(r1,c1,-1,c1)) & (isEmptyCol(r2,c2,-1,c2))){
                      p[0] = -1;
                      p[1] = c1;
                      p[2] = -1;
                      p[3] = c2;
                      return true;
                  }
                  //左側(cè)
                  if((isEmptyRow(r1,c1,r1,-1)) & (isEmptyRow(r2,c2,r2,-1))){
                      p[0] = r1;
                      p[1] = -1;
                      p[2] = r2;
                      p[3] = -1;
                      return true;
                  }
                  //下側(cè)
                  if((isEmptyCol(r1,c1,MAX_ROW,c1)) & (isEmptyCol(r2,c2,MAX_ROW,c2))){
                      p[0] = MAX_ROW;
                      p[1] = c1;
                      p[2] = MAX_ROW;
                      p[3] = c2;
                      return true;
                  }
                  //右側(cè)
                  if((isEmptyRow(r1,c1,r1,MAX_COL)) & (isEmptyRow(r2,c2,r2,MAX_COL))){
                      p[0] = r1;
                      p[1] = MAX_COL;
                      p[2] = r2;
                      p[3] = MAX_COL;
                      return true;
                  }       
                  return false;
              }
             
              /**
               * 邏輯判斷是否有連線
               * @return NO_LINK代表無連線,其它數(shù)據(jù)代表有連線
               */
              private int logic(){
                  //如果數(shù)值不同
                  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;
                  }
                  //一個轉(zhuǎn)點的連接
                  int result = isOneCornerLink(firstRow,firstCol,secondRow,secondCol);
                  if(result != NO_LINK){
                      return result;
                  }
                  //兩個轉(zhuǎn)點的連接
                  if(isTwoCornerLink(firstRow,firstCol,secondRow,secondCol)){
                      return TWO_CORNER;
                  }       
                  //返回?zé)o連接
                  return NO_LINK;
              }
             
              /**
               * 邏輯判別和邏輯處理
               */
              public boolean action(){
                  //判斷是否選擇兩個方塊
                  if(selectTileNum != 2){
                      return false;
                  }
                  boolean b = false;
                  //判斷是否有連線
                  linkType = logic();
                  //如果有連線,則消失
                  if(linkType != NO_LINK){
                      map[firstRow][firstCol] = 0;
                      map[secondRow][secondCol] = 0;
                      b = true;
                  }
                  //選擇的塊數(shù)初始化
                  selectTileNum = 0;
                  return b;
              }
          }
          主站蜘蛛池模板: 随州市| 沾益县| 昆明市| 江川县| 台山市| 岚皋县| 比如县| 富民县| 庆阳市| 天水市| 五家渠市| 林口县| 兴化市| 南靖县| 大冶市| 枣阳市| 遂昌县| 石屏县| 许昌市| 大名县| 黄陵县| 灵丘县| 沙洋县| 古浪县| 大港区| 九江市| 偃师市| 永年县| 潍坊市| 阳江市| 于田县| 塘沽区| 永和县| 大连市| 繁昌县| 定结县| 扶绥县| 菏泽市| 扎兰屯市| 台湾省| 庆云县|