我正在用Java开发一个俄罗斯方块的克隆体,一切似乎都很正常,直到我想要清除整行并删除上面的所有内容。尽管我的所有数据都正确地表示了转换,但我的paintComponent方法似乎只清除了行,但将上面显示的所有内容都保留为调用repaint()之前的样子。新的一块将通过幻影块落下,并落在底部一排看不见的块上,上面的块就会掉在那里。
下面是我的paint组件方法:
代码语言:javascript复制public void paintComponent(Graphics page)
{
super.paintComponent(page);
Graphics2D page2D = (Graphics2D) page;
for (int c = 0; c < 10; c++)
{
for (int r = 0; r < 18; r++)
{
if (well[c][r] != null) //Well is a 2D array of Block objects that have Rectangle object, coordinates and color
{
page2D.setColor(well[c][r].getColor());
page2D.fill(well[c][r].getSquare());
page2D.setColor(Color.gray);
page2D.draw(well[c][r].getSquare());
}
}
}
for (int i = 0; i < 4; i++) //tetro = the player's tetris piece
{
page2D.setColor(tetro.getColor());
page2D.fill(tetro.getBlock(i).getSquare());
page2D.setColor(Color.GRAY);
page2D.draw(tetro.getBlock(i).getSquare());
}
}这是我的计时器侦听器中actionPerformed方法的一部分,用于检测/清除块并调用repaint方法。
代码语言:javascript复制 int count = 0; //Number of occupied cells in well
int clears = 0; //number of rows to be clear
int lowestClear = -1; //Lowest row that was cleared, -1 if none
for (int row = 0; row < 18; row++)
{
for (int col = 0; col < 10; col++)
{
if (well[col][row] != null)
{
count++;
}
}
if (count == 10)
{
clears++;
if (lowestClear < 0)
{
lowestClear = row;
}
for (int col = 0; col < 10; col++)
{
well[col][row] = null;
}
}
count = 0;
}
if (clears > 0)
{
repaint(); //Doesn't call paintComponent()
for (int i = 1; i <= clears; i++)
{
for (int r = 16; r >= 0; r--)
{
if (r > lowestClear)
{
break;
}
for (int c = 0; c < 10; c++)
{
if (well[c][r] != null)
{
well[c][r+1] = well[c][r];
well[c][r] = null;
}
}
}
}
repaint(); //Does not call paintComponent()
}
tetro.fall();
repaint(); //DOES call paint component在调用第一个repaint()方法时,well数组正确地显示整行现在完全为空。我希望repaint()方法更新面板以显示这个空行,但似乎没有调用paintComponent()。第二个repaint()方法也是如此,我希望它在清空一行并将块拖放到新位置后更新帧,以显示新位置的块。同样,不会调用paintComponent()。然而,对于最后一次repaint()调用,我只想更新坠落的碎片的位置,而不管它之前可能需要或不需要进行任何更新,repaint()确实调用了paintComponent()。所以:第一个问题是,为什么paintComponent()只在repaint()调用的这个实例中调用。
但是,当调用paintComponent()并到达方法的末尾时,我会在调试模式下跟踪它,以查看面板在哪一行反映了更改。一旦它到达:"Repaintmanager.paintDirtyRegions(Map< Component,Rectangle >)“行:856,它就清除了该行并显示新的下降块,但具有不可见的块和幻块。
所以,我的第二个问题是,为什么paintComponent()会这样。显然,我需要对Repaintmanager和Java绘画做一些一般性的阅读,但如果有人能给我解释一下,我会非常感激。
如果重要,下面是main方法:
代码语言:javascript复制import javax.swing.JFrame;
public class TetrisDriver
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Tetris");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Matrix()); //Matrix = jPanel class
frame.pack();
frame.setVisible(true);
}}
如果这篇文章太长了,我很抱歉。