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

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

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

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

java實現俄羅斯方塊小游戲

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

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

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

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

?
1
2
// 游戲地圖格子,每個格子保存一個方塊,數組紀錄方塊的狀態
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);
  }
}

通過隨機數的方式產生方塊所組成的幾種圖形,一般七種圖形:條形、田形、正7形、反7形、t形、z形和反z形,如生成條形:

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

生成圖形后,實現下落的操作。如果遇到阻礙,則不能再繼續下落:

?
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; // 有阻礙,不用再循環判斷行
    } 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; // 有阻礙,不用再循環判斷列
        }
      }
      if (hasblock)
        break; // 有阻礙,不用再循環判斷行
    }
  }
 
  /* 左邊沒有阻礙,則將圖形向左移動一個塊的距離 */
  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();
  }
}

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

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

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

 

?
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) { // 條狀
      // 臨時數組,放置旋轉后圖形
      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 {
      // 臨時數組,放置旋轉后圖形
      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) {
   // 遇到數組下標越界,說明不能變換圖形形狀,不作任何處理
  }
}

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

?
1
2
3
4
5
6
7
8
9
10
int[] blockscount = new int[rows]; // 記錄每行有方塊的列數
int eliminaterows = 0; // 消除的行數
/* 計算每行方塊數量 */
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
/* 實現有滿行的方塊消除操作 */
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++; // 記錄消除行數
  }
}

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

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

運行效果:

java實現俄羅斯方塊小游戲

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

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲免费福利视频 | 动漫美女隐私尿口图片 | 国产精品一区二区久久不卡 | 国内自拍网红在线综合 | 亚洲精品视频在线 | 1024免费观看完整版在线播放 | 成品人视频w免费观看w | 秋霞黄色片 | ts视频在线观看 | bt7086新片速递亚洲最新合集 | 99久久精品6在线播放 | 免费午夜影片在线观看影院 | 91久久精品视频 | 日本免费观看95视频网站 | 日本视频高清免费观看xxx | 国产在视频线精品视频 | 叉逼视频| 草草剧场 | 精品久久成人免费第三区 | 成熟女人50岁一级毛片不卡 | 狠狠撸在线影院 | 天美传媒tm0087 | www.四虎影| 国产成人亚洲精品乱码在线观看 | 天堂网www在线观看 天堂欧美 | 高h短篇辣肉各种姿势bl | 2018久久精品热在线观看 | 91精品久久一区二区三区 | 成人免费一区二区三区在线观看 | 调教开发新婚娇妻放荡 | blackedhd 18sex| 国产草 | 国产一区二区视频在线 | 久久中文字幕无线观看 | 国产精品久久久久网站 | 乌克兰黄色录像 | 午夜久久免影院欧洲 | 亚洲国产美女精品久久 | 亚洲精品网址 | 亚洲狠狠婷婷综合久久久久网站 | 近亲乱中文字幕 |