最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java實現(xiàn)俄羅斯方塊小游戲

 更新時間:2021年01月19日 11:39:07   作者:江湖人稱小明  
這篇文章主要為大家詳細介紹了java實現(xiàn)俄羅斯方塊小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了java實現(xiàn)俄羅斯方塊的具體代碼,供大家參考,具體內(nèi)容如下

使用一個二維數(shù)組保存游戲的地圖:

// 游戲地圖格子,每個格子保存一個方塊,數(shù)組紀錄方塊的狀態(tài)
private State map[][] = new State[rows][columns];

游戲前先將所有地圖中的格子初始化為空:

/* 初始化所有的方塊為空 */
for (int i = 0; i < map.length; i++) {
 for (int j = 0; j < map[i].length; j++) {
 map[i][j] = State.EMPTY;
 }
}

玩游戲過程中,我們能夠看到界面上的方塊,那么就得將地圖中所有的方塊繪制出來,當然,除了需要繪制方塊外,游戲積分和游戲結束的字符串在必要的時候也需要繪制:

/**
 * 繪制窗體內(nèi)容,包括游戲方塊,游戲積分或結束字符串
 */
@Override
public void paint(Graphics g) {
 super.paint(g);
 for (int i = 0; i < rows; i++) {
 for (int j = 0; j < columns; j++) {
  if (map[i][j] == State.ACTIVE) { // 繪制活動塊
  g.setColor(activeColor);
  g.fillRoundRect(j * BLOCK_SIZE, i * BLOCK_SIZE + 25,
   BLOCK_SIZE - 1, BLOCK_SIZE - 1, BLOCK_SIZE / 5,
   BLOCK_SIZE / 5);
  } else if (map[i][j] == State.STOPED) { // 繪制靜止塊
  g.setColor(stopedColor);
  g.fillRoundRect(j * BLOCK_SIZE, i * BLOCK_SIZE + 25,
   BLOCK_SIZE - 1, BLOCK_SIZE - 1, BLOCK_SIZE / 5,
   BLOCK_SIZE / 5);
  }
 }
 }

 /* 打印得分 */
 g.setColor(scoreColor);
 g.setFont(new Font("Times New Roman", Font.BOLD, 30));
 g.drawString("SCORE : " + totalScore, 5, 70);

 // 游戲結束,打印結束字符串
 if (!isGoingOn) {
 g.setColor(Color.RED);
 g.setFont(new Font("Times New Roman", Font.BOLD, 40));
 g.drawString("GAME OVER !", this.getWidth() / 2 - 140,
  this.getHeight() / 2);
 }
}

通過隨機數(shù)的方式產(chǎn)生方塊所組成的幾種圖形,一般七種圖形:條形、田形、正7形、反7形、T形、Z形和反Z形,如生成條形:

map[0][randPos] = map[0][randPos - 1] = map[0][randPos + 1] 
  = map[0][randPos + 2] = State.ACTIVE;

生成圖形后,實現(xiàn)下落的操作。如果遇到阻礙,則不能再繼續(xù)下落:

isFall = true; // 是否能夠下落
// 從當前行檢查,如果遇到阻礙,則停止下落
for (int i = 0; i < blockRows; i++) {
 for (int j = 0; j < columns; j++) {
 // 遍歷到行中塊為活動塊,而下一行塊為靜止塊,則遇到阻礙
 if (map[rowIndex - i][j] == State.ACTIVE
  && map[rowIndex - i + 1][j] == State.STOPED) {
  isFall = false; // 停止下落
  break;
 }
 }
 if (!isFall)
 break;
}

如果未遇到阻礙,則下落的時候,方塊圖形整體向下移動一行:

// 圖形下落一行
for (int i = 0; i < blockRows; i++) {
 for (int j = 0; j < columns; j++) {
 if (map[rowIndex - i][j] == State.ACTIVE) { // 活動塊向下移動一行
  map[rowIndex - i][j] = State.EMPTY; // 原活動塊變成空塊
  map[rowIndex - i + 1][j] = State.ACTIVE; // 下一行塊變成活動塊
 }
 }
}

向左、向右方向移動時是類似的操作:

/**
 * 向左走
 */
private void left() {
 // 標記左邊是否有阻礙
 boolean hasBlock = false;

 /* 判斷是否左邊有阻礙 */
 for (int i = 0; i < blockRows; i++) {
 if (map[rowIndex - i][0] == State.ACTIVE) { // 判斷左邊是否為墻
  hasBlock = true;
  break; // 有阻礙,不用再循環(huán)判斷行
 } else {
  for (int j = 1; j < columns; j++) { // 判斷左邊是否有其它塊
  if (map[rowIndex - i][j] == State.ACTIVE
   && map[rowIndex - i][j - 1] == State.STOPED) {
   hasBlock = true;
   break; // 有阻礙,不用再循環(huán)判斷列
  }
  }
  if (hasBlock)
  break; // 有阻礙,不用再循環(huán)判斷行
 }
 }

 /* 左邊沒有阻礙,則將圖形向左移動一個塊的距離 */
 if (!hasBlock) {
 for (int i = 0; i < blockRows; i++) {
  for (int j = 1; j < columns; j++) {
  if (map[rowIndex - i][j] == State.ACTIVE) {
   map[rowIndex - i][j] = State.EMPTY;
   map[rowIndex - i][j - 1] = State.ACTIVE;
  }
  }
 }

 // 重繪
 repaint();
 }
}

向下加速移動時,就是減小每次正常狀態(tài)下落的時間間隔:

/**
 * 向下直走
 */
private void down() {
 // 標記可以加速下落
 immediate = true;
}

如何變換圖形方向,這里僅使用了非常簡單的方法來實現(xiàn)方向變換,當然可以有更優(yōu)的算法實現(xiàn)方向變換操作,大家可以自己研究:

/**
 * 旋轉(zhuǎn)方塊圖形
 */
private void rotate() {
 try {
 if (shape == 4) { // 方形,旋轉(zhuǎn)前后是同一個形狀
  return;
 } else if (shape == 0) { // 條狀
  // 臨時數(shù)組,放置旋轉(zhuǎn)后圖形
  State[][] tmp = new State[4][4];
  int startColumn = 0;
  // 找到圖形開始的第一個方塊位置
  for (int i = 0; i < columns; i++) {
  if (map[rowIndex][i] == State.ACTIVE) {
   startColumn = i;
   break;
  }
  }
  // 查找旋轉(zhuǎn)之后是否有阻礙,如果有阻礙,則不旋轉(zhuǎn)
  for (int i = 0; i < 4; i++) {
  for (int j = 0; j < 4; j++) {
   if (map[rowIndex - 3 + i][j + startColumn] == State.STOPED) {
   return;
   }
  }
  }

  if (map[rowIndex][startColumn + 1] == State.ACTIVE) { // 橫向條形,變換為豎立條形
  for (int i = 0; i < 4; i++) {
   tmp[i][0] = State.ACTIVE;
   for (int j = 1; j < 4; j++) {
   tmp[i][j] = State.EMPTY;
   }
  }
  blockRows = 4;
  } else { // 豎立條形,變換為橫向條形
  for (int j = 0; j < 4; j++) {
   tmp[3][j] = State.ACTIVE;
   for (int i = 0; i < 3; i++) {
   tmp[i][j] = State.EMPTY;
   }
  }
  blockRows = 1;
  }
  // 將原地圖中圖形修改為變換后圖形
  for (int i = 0; i < 4; i++) {
  for (int j = 0; j < 4; j++) {
   map[rowIndex - 3 + i][startColumn + j] = tmp[i][j];
  }
  }
 } else {
  // 臨時數(shù)組,放置旋轉(zhuǎn)后圖形
  State[][] tmp = new State[3][3];
  int startColumn = columns;
  // 找到圖形開始的第一個方塊位置
  for (int j = 0; j < 3; j++) {
  for (int i = 0; i < columns; i++) {
   if (map[rowIndex - j][i] == State.ACTIVE) {
   startColumn = i < startColumn ? i : startColumn;
   }
  }
  }
  // 判斷變換后是否會遇到阻礙
  for (int i = 0; i < 3; i++) {
  for (int j = 0; j < 3; j++) {
   if (map[rowIndex - 2 + j][startColumn + 2 - i] == State.STOPED)
   return;
  }
  }
  // 變換
  for (int i = 0; i < 3; i++) {
  for (int j = 0; j < 3; j++) {
   tmp[2 - j][i] = map[rowIndex - 2 + i][startColumn + j];
  }
  }
  // 將原地圖中圖形修改為變換后圖形
  for (int i = 0; i < 3; i++) {
  for (int j = 0; j < 3; j++) {
   map[rowIndex - 2 + i][startColumn + j] = tmp[i][j];
  }
  }

  // 重繪
  repaint();
  // 重新修改行指針
  for (int i = 0; i < 3; i++) {
  for (int j = 0; j < 3; j++) {
   if (map[rowIndex - i][startColumn + j] != null
    || map[rowIndex - i][startColumn + j] != State.EMPTY) {
   rowIndex = rowIndex - i;
   blockRows = 3;
   return;
   }
  }
  }
 }
 } catch (Exception e) {
 // 遇到數(shù)組下標越界,說明不能變換圖形形狀,不作任何處理
 }
}

當圖形下落遇到阻礙時停止,我們就需要判斷這時是否有某一行或幾行可以消除掉,這時可以先獲取每行中方塊的個數(shù),然后再進行判斷:

int[] blocksCount = new int[rows]; // 記錄每行有方塊的列數(shù)
int eliminateRows = 0; // 消除的行數(shù)
/* 計算每行方塊數(shù)量 */
for (int i = 0; i < rows; i++) {
 blocksCount[i] = 0;
 for (int j = 0; j < columns; j++) {
 if (map[i][j] == State.STOPED)
  blocksCount[i]++;
 }
}

如果有滿行的方塊,則消除掉該行方塊:

/* 實現(xiàn)有滿行的方塊消除操作 */
for (int i = 0; i < rows; i++) {
 if (blocksCount[i] == columns) {
 // 清除一行
 for (int m = i; m >= 0; m--) {
  for (int n = 0; n < columns; n++) {
  map[m][n] = (m == 0) ? State.EMPTY : map[m - 1][n];
  }
 }
  eliminateRows++; // 記錄消除行數(shù)
 }
}

最后我們再重繪顯示積分就可以了。

重復以上的生成圖形、圖形下落、左右下移動、判斷消除行的操作,一個簡單的俄羅斯方塊就完成了。

運行效果:

完整示例代碼:俄羅斯方塊

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 使用java連接Redis,Maven管理操作

    使用java連接Redis,Maven管理操作

    這篇文章主要介紹了使用java連接Redis,Maven管理操作,具有很好的參考價值,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • dubbo如何實現(xiàn)consumer從多個group中調(diào)用指定group的provider

    dubbo如何實現(xiàn)consumer從多個group中調(diào)用指定group的provider

    這篇文章主要介紹了dubbo如何實現(xiàn)consumer從多個group中調(diào)用指定group的provider問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 基于Java的打包jar、war、ear包的作用與區(qū)別詳解

    基于Java的打包jar、war、ear包的作用與區(qū)別詳解

    本篇文章,小編為大家介紹,基于Java的打包jar、war、ear包的作用與區(qū)別詳解。需要的朋友參考下
    2013-04-04
  • Java多線程事務回滾@Transactional失效處理方案

    Java多線程事務回滾@Transactional失效處理方案

    這篇文章主要介紹了Java多線程事務回滾@Transactional失效處理方案,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-08-08
  • Java實現(xiàn)圖片比率縮放

    Java實現(xiàn)圖片比率縮放

    這篇文章主要為大家詳細介紹了Java通過Thumbnails實現(xiàn)圖片比率縮放,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Spring Boot 3.0升級指南

    Spring Boot 3.0升級指南

    這篇文章主要為大家介紹了Spring Boot 3.0升級指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • Java中Date日期時間類具體使用

    Java中Date日期時間類具體使用

    本文主要介紹了Java中Date日期時間類具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • 一文詳解Java17中LinkedList類的用法和應用場景

    一文詳解Java17中LinkedList類的用法和應用場景

    LinkedList 是 Java 集合框架中基于雙向鏈表實現(xiàn)的類,實現(xiàn)了 List 和 Deque 接口,本文將為大家介紹一下它在Java 17 中如何更高效的使用吧
    2025-03-03
  • 簡單談一談Java中的Unsafe類

    簡單談一談Java中的Unsafe類

    其實Java官方不推薦使用Unsafe類,因為官方認為,這個類別人很難正確使用,非正確使用會給JVM帶來致命錯誤。但還是要會使用,下面這篇文章就來給大家簡單的談一談關于Java中Unsafe類的相關資料,需要的朋友可以參考下
    2018-05-05
  • Java異常處理中的各種細節(jié)匯總

    Java異常處理中的各種細節(jié)匯總

    這篇文章主要給大家介紹了關于Java異常處理中的各種細節(jié)的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-01-01

最新評論

油尖旺区| 南安市| 同德县| 岚皋县| 曲靖市| 望城县| 青田县| 夏津县| 厦门市| 华阴市| 彭泽县| 塔河县| 万荣县| 黔江区| 贵南县| 托里县| 岑巩县| 菏泽市| 连平县| 长子县| 右玉县| 新绛县| 榆社县| 财经| 吴堡县| 旌德县| 保山市| 绥芬河市| 千阳县| 汉寿县| 华坪县| 卢氏县| 东光县| 资溪县| 博爱县| 汕尾市| 长顺县| 惠来县| 莱阳市| 湖南省| 苏尼特左旗|