我和我的朋友用 Java 制作了一个类似俄罗斯方块的游戏,它运行了一段时间,然后突然出现每次大约相同数量的总块数的错误。例如,它可能会出现一次 42 件错误,下一次是 46 件,然后是 44 件。
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][2][2][ ][ ][ ][ ][ ][ ][7]
[ ][2][2][2][3][3][ ][4][ ][7]
[2][2][1][3][3][1][ ][4][ ][7]
以上是错误发生之前的示例。不要试图过多地阅读上面的示例,因为错误不依赖于棋子位置等。
这是错误发生后网格的样子......
[ ][ ][ ][2][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][2][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][2][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][2][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][2][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][2][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][2][ ][ ][ ][ ][ ][ ]
[ ][2][2][ ][ ][ ][ ][ ][ ][7]
[ ][2][2][2][3][3][ ][4][ ][7]
[2][2][1][3][3][1][ ][4][ ][7]
注意到这两个一直到网格的顶部吗?这就是正在发生的事情。
这就是事情变得有趣的地方。我们将其限制为特定的功能和特定的代码行。
grid[x+legend[piece.type].fetch(i, 0, piece.rotate)]
[y+legend[piece.type].fetch(i, 1, piece.rotate)]
.type = piece.type+1;
上面的代码行是被认为导致问题的确切代码行。问题是那行代码没有任何问题。我已经调试整个程序大约一周了,每次更改后我都会让它记录网格。
上面两个网格之间的区别是对该行的一次调用。它应该不可能分配网格中的所有其他单元格。调试日志说变量是:
i: 0
legend[piece.type].block.length: 4
legend[piece.type].fetch(i, 0, piece.rotate): 0
legend[piece.type].fetch(i, 1, piece.rotate): 0
piece.type: 1
piece.rotate: 3
x: 3
y: 6
这些是影响上面第二个网格的变量。错误的代码行应该是:
grid[3+0][6+0].type = 1+1;
我们是否有可能在 Java 本身中发现了一个错误?我花了好几个小时调试这段代码,但我从来没有遇到过我找不到的错误(我通常用 python 编写代码,不过……Java 对我来说相当新)
此外,似乎该错误受网格大小的影响。如果我将网格的高度设置为较低的数字,则导致错误所需的碎片更少。同样,如果我制作更高的网格,它需要更多的碎片。
希望那里的 Java 专家可以帮助阐明这种情况。
ps 我正在使用 JRE JVM 1.6 在 Mac 上的 Eclipse 中编程。我也尝试了 JRE JVM 1.4 并且发生了同样的事情。
附加信息:
private Grid grid[][] = new Grid[dimx][dimy];
上面的代码是创建网格的时候。网格是一个类:
public class Grid {
int type;
public Grid(int type) {
}
}
这是大量调试日志代码的一部分...这是打印基于文本的网格的函数。
public void printGrid(int line) {
System.out.print("\n\n\n"+line+":\n");
for (int y = 0;y < grid[0].length;y++) {
for (int x = 0;x < grid.length;x++) {
if (grid[x][y].type == 0) {
System.out.print("[ ]");
} else {
System.out.print("["+grid[x][y].type+"]");
}
}
System.out.println();
}
System.out.println("\n\n");
}
变量 'line' 并不重要,它只是告诉我们调用 printGrid() 函数的行号。
让我知道你们是否需要更多信息。
更多附加信息:
这是该程序的所有文件。
- 图例.java: http ://pastebin.com/mWL7wACW
- Listener.java:http://pastebin.com/8A2BgicD _
- TetrisFrame.java: http://pastebin.com/1HKgc1uS (90% 的代码在这里)
- Grid.java:http://pastebin.com/6HgKZsaF _
- 俄罗斯方块.java: http ://pastebin.com/kHdnvHyT
- Piece.java:http://pastebin.com/k5PZpCzd _
哦,这是调试日志的摘录,可为您提供更多信息。
它包括成功放置一块(放置在错误之前的最后一块),然后显示正在发生的错误。该函数的所有变量都被打印出来,没有一个出现不合适的地方。该错误发生在放置在网格上任何位置的任何一块上。每次调用我上面谈到的行后,都会打印网格。让我知道你们是否需要更多信息。我想把这个虫子压扁。