【发布时间】:2017-05-30 11:13:34
【问题描述】:
我正在使用 Swing 用 Java 制作 Snake 游戏。我用Timer 制作了游戏循环。现在我无法在蛇的每一个动作之后重新绘制我的游戏板。
这是使用计时器执行的代码:
@Override
public void actionPerformed(ActionEvent e) {
if(!isWon()) {
inputDirection = inputManager.getCapturedDirection();
try {
snake.move(inputDirection);
} catch (LosingMove losingMove) {
gameLoop.stop();
showGameOverDialog();
}
} else {
gameLoop.stop();
showWinDialog();
}
board.repaint();
}
所以我告诉我的棋盘对象 Board 扩展 JPanel 类在每次移动后重新绘制棋盘。它的paintComponent() 方法如下所示:
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
for (int row = 0; row < size.height; row++) {
for (int col = 0; col < size.width; col++) {
g2d.setColor(Color.WHITE);
g2d.fill(fields[row][col].getGraphicRepresentation());
g2d.setColor(Color.BLACK);
g2d.draw(fields[row][col].getGraphicRepresentation());
if (fields[row][col].getContent() instanceof Snake.SnakeNode) {
g2d.setColor(Color.DARK_GRAY);
g2d.fill(fields[row][col].getContent().getGraphicRepresentation());
g2d.setColor(Color.BLACK);
g2d.draw(fields[row][col].getContent().getGraphicRepresentation());
} else if (fields[row][col].getContent() instanceof Apple) {
g2d.setColor(Color.GREEN);
g2d.fill(fields[row][col].getContent().getGraphicRepresentation());
g2d.setColor(Color.BLACK);
g2d.draw(fields[row][col].getContent().getGraphicRepresentation());
}
}
}
}
graphicRepresentation 只是一个 Shape 对象。
在调试器中执行此代码,但它不会影响我的游戏板的窗口。游戏在后台运行,并且蛇正在改变它在内存中游戏板阵列上的位置,但它没有正确重新绘制。所有显示的都是空字段,一个在棋盘上位置不正确的蛇字段(内存中的坐标正确),还有一个苹果字段也在错误的位置但内存中的值正确。
如何以正确的方式做到这一点?
【问题讨论】:
-
任何时候你
@OverridepaintComponent()方法,你需要调用super.paintComponent()传递Graphics对象。我不知道这是否会解决您的问题,因为我不知道您正在使用的坐标值。fields的数组类型是什么 -
它并没有消除问题,但感谢您提醒我。字段的类型为
Field,其中包含有关元素坐标的信息(Point),它的内容(apple、snake、null)和graphicRepresentation为Rectangle2D。 -
你有游戏循环吗?类似:
while(running)?如果是这样,在那个循环的某个地方,你应该在你正在绘画的JPanel上调用repaint()。这样它会重新绘制每一帧 -
repaint()在actionPerformed()中每秒调用一次(这是计时器的延迟时间) -
在 repaint() 之前调用 invalidate()。这可能会有所帮助。
标签: java swing user-interface graphics2d