一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java實現(xiàn)俄羅斯方塊小游戲

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

2021-05-11 14:11江湖人稱小明 Java教程

這篇文章主要為大家詳細介紹了java實現(xiàn)俄羅斯方塊小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

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

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

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

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

?
1
2
3
4
5
6
/* 初始化所有的方塊為空 */
for (int i = 0; i < map.length; i++) {
  for (int j = 0; j < map[i].length; j++) {
    map[i][j] = state.empty;
  }
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
 * 繪制窗體內容,包括游戲方塊,游戲積分或結束字符串
 */
@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ù)的方式產生方塊所組成的幾種圖形,一般七種圖形:條形、田形、正7形、反7形、t形、z形和反z形,如生成條形:

?
1
2
map[0][randpos] = map[0][randpos - 1] = map[0][randpos + 1]
        = map[0][randpos + 2] = state.active;

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}

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

?
1
2
3
4
5
6
7
8
9
// 圖形下落一行
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; // 下一行塊變成活動塊
    }
  }
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
 * 向左走
 */
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)下落的時間間隔:

?
1
2
3
4
5
6
7
/**
 * 向下直走
 */
private void down() {
  // 標記可以加速下落
  immediate = true;
}

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

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
 * 旋轉方塊圖形
 */
private void rotate() {
  try {
    if (shape == 4) { // 方形,旋轉前后是同一個形狀
      return;
    } else if (shape == 0) { // 條狀
      // 臨時數(shù)組,放置旋轉后圖形
      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;
        }
      }
      // 查找旋轉之后是否有阻礙,如果有阻礙,則不旋轉
      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ù)組,放置旋轉后圖形
      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ù),然后再進行判斷:

?
1
2
3
4
5
6
7
8
9
10
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]++;
  }
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
/* 實現(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ù)
  }
}

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

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

運行效果:

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

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/zhliro/article/details/45746719

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国内自拍成人网在线视频 | vod国产成人精品视频 | 五月天视频网 | 金发美女与黑人做爰 | 99精品视频免费在线观看 | 人人澡 人人澡碰人人看软件 | 兽操人 | 姐姐不~不可以动漫在线观看 | 99久久精品在免费线18 | 涩情主播在线翻车 | 天天色影视综合网 | 欧美日韩精彩视频 | 国产午夜精品久久久久 | 92国产福利视频一区二区 | 激情影院免费观看 | 成人在线播放视频 | 亚洲精品在线看 | 日剧整部剧护妻狂魔免费观看全集 | 午夜办公室在线观看高清电影 | 欧美亚洲天堂 | 亚洲国产综合久久精品 | 免费观看成年肉动漫网站 | 亚洲国产精品久久久久久 | 91麻豆国产精品91久久久 | 欧美bbxx | 美女张开腿让男人桶的 视频 | 关晓彤一级做a爰片性色毛片 | 91综合精品网站久久 | 国产日韩欧美 | 色综合久久最新中文字幕 | 手机av影院| 亚洲人成毛片线播放 | 香蕉精品国产高清自在自线 | 欧美区视频 | 天码毛片一区二区三区入口 | 亚洲 日本 中文字幕 制服 | 亚洲AV永久无码精品老司机蜜桃 | 国产区香蕉精品系列在线观看不卡 | 国产一卡二卡3卡4卡四卡在线视频 | 韩国甜性涩爱在线播放 | 国内小情侣一二三区在线视频 |