java实现俄罗斯方块小游戏

2025-05-29 0 93

本文实例为大家分享了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实现俄罗斯方块小游戏

完整示例代码:俄罗斯方块

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

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

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 java实现俄罗斯方块小游戏 https://www.kuaiidc.com/111299.html

相关文章

发表评论
暂无评论