我和我的朋友用Java制作了一个类似俄罗斯方块的游戏,一开始它能正常运行一段时间,但在总方块数达到某个特定值时就会突然出现bug。例如,有时候在放置了42个方块后出现问题,下一次可能是46个,再下一次是44个。
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][2][2][ ][ ][ ][ ][ ][ ][7]
[ ][2][2][2][3][3][ ][4][ ][7]
[2][2][1][3][3][1][ ][4][ ][7]
上面是一个在bug发生之前的样例。不要过于解读上面的示例,因为bug并不依赖于棋子位置等因素。
以下是bug发生后网格的样子...
[ ][ ][ ][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]
注意到2一直延伸到网格的顶部了吗?这就是发生的事情。
现在事情变得有趣了。我们已经将其限制为特定的函数和特定的代码行。
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本身的一个bug吗?我已经花了几个小时来调试这段代码,但我从来没有遇到过找不到的bug(虽然我通常使用Python编程,但是Java对我来说还是相对较新的)。
此外,似乎这个bug受到网格大小的影响。如果我将网格的高度设置为较低的数字,就需要更少的方块才能引起bug。同样地,如果我制作一个更高的网格,则需要更多的方块。
希望Java专家们能够帮助解决这个问题。
附加信息:
p.s. 我在Mac上使用Eclipse编程,使用JRE JVM 1.6。我也尝试了JRE JVM 1.4,但出现了相同的情况。
private Grid grid[][] = new Grid[dimx][dimy];
以上代码是创建网格时的代码。Grid是一个类:
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()。
如果您需要更多信息,请告诉我。
更多附加信息:
这是该程序的所有文件。
- Legend.java: http://pastebin.com/mWL7wACW(传送门)
- Listener.java: http://pastebin.com/8A2BgicD(传送门)
- TetrisFrame.java: http://pastebin.com/1HKgc1uS(90%的代码在此处)
- Grid.java: http://pastebin.com/6HgKZsaF(传送门)
- Tetris.java: http://pastebin.com/kHdnvHyT(传送门)
- Piece.java: http://pastebin.com/k5PZpCzd(传送门)
哦,这里还有一段调试日志的摘录,以便为您提供更多信息。
它包括成功放置一个棋子(即在错误发生之前放置的最后一个棋子),然后显示错误发生。函数的所有变量都被打印出来,没有一个变量出现错位。该错误会发生在网格上任何位置放置任何棋子时。每次调用我上面提到的代码行后都会打印出网格。如果需要更多信息,请告诉我。我希望解决这个错误。
grid
和打印它的代码吗? - Ted Hopp