【发布时间】:2013-12-30 05:36:05
【问题描述】:
我正在用 Java 制作游戏。基本上,我需要处理两个不同的更新“平面”。基础层是实际的游戏绘画本身。它只是一个覆盖整个 JFrame 的 JPanel,并使用其 Graphics 对象进行绘制。
我使用固定的时间步来处理这些第一次图形更新。我已经覆盖了 paintComponent() 方法,完全没有做任何事情,因为我已经编写了一个自定义的 render(float interpolation) 方法来处理这个问题,以防止不需要的更新。
但是,除了原始的鼠标点击和键盘输入之外,此面板不接受任何输入。我需要能够在屏幕上创建各种菜单、文本框等。比如各种能力,甚至是大多数游戏左上角通常出现的“菜单”按钮。
为了处理该输入,例如创建按钮,我有第二个 JPanel,它应用了 setOpaque(false)。然后我创建了我可能需要的各种 Swing 组件,例如 JButton。
为了包含两个 JPanel,我使用了 JLayeredPane,并适当地设置了它们的层,如下所示。这样,输入层应该始终位于实际游戏层之上。
下面的代码展示了我如何创建 Swing 组件并将它们相互添加。 addLoginDialog() 是一种为登录添加 Swing 组件的方法。它已经过测试并且工作正常,不是问题。
private void initComponents()
{
//This code is inside of the JFrame
wholePane = new JLayeredPane();
add(wholePane);
guiPanel = new GUIPanel();
guiPanel.setOpaque(false);
gamePanel = new RPGPanel();
gamePanel.setOpaque(false);
wholePane.add(gamePanel, JLayeredPane.DEFAULT_LAYER);
wholePane.add(guiPanel, JLayeredPane.POPUP_LAYER);
guiPanel.addLoginDialog();
}
所以当我运行代码时,我得到了可怕的闪烁。这是从我的固定时间步长约每秒 60 次运行的代码。
public void handleRepaint()
{
//I don't use repaint() for the game drawing so I can be sure that fps is controlled.
Graphics g = gamePanel.getGraphics();
gamePanel.render(g);
g.dispose();
wholePane.repaint();
}
我认为,问题在于两种不同的屏幕更新系统正在发生冲突。标准的paintComponent() 系统非常适合更多静态屏幕,但是当我需要持续更新并跟踪 fps 时,我不能随机更新。
但是,对于输入层,我只想像 Swing 一样进行更新。当鼠标移动到按钮上时,当 I 组件被移动或调整大小等时。
另外,请注意屏幕闪烁的方式:背景图像变为空白,然后反复出现。输入面板总是在那里,但实际上是在游戏绘图后面绘制的,这不应该发生,因为它被放置在默认图层中。我知道它没有完全消失的原因是因为游戏画面是部分透明的,所以我可以看到它的下面,而且我添加的按钮仍然存在。
我的主要问题是,我怎样才能停止闪烁? 为什么在 JLayeredPane 中较低层的 Panel 上进行游戏绘图时,游戏绘图被绘制在输入组件的顶部? 我想最重要的是,是什么导致了闪烁?感谢您的帮助。
【问题讨论】:
-
如需尽快获得更好的帮助,请发帖SSCCE。
-
wholePane.setSize(getSize());布局管理器更有可能遵守所引用的尺寸,而不是尺寸,但我们也不应该设置。见Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?(是的。) -
@AndrewThompson 尺寸不是问题,所以我现在不太担心。
-
@AndrewThompson 实际上我已经阅读了多个教程,他们都告诉我,当仅涉及绘图代码时,使用渲染方法并确保不要使用 paintComponent 以避免不必要的绘画调用。
-
@user3144349 你只是“禁用”了渲染引擎,这不是 Swing 的设计方式。它是按照这种方式工作的。你不妨试着在冰箱里烤一烤……对不起,但事实就是如此。我想任何告诉你避免使用
paintComponent的教程也应该告诉你改用BufferStrategy。这是控制油漆过程的唯一方法。这里的问题是,Swing 组件被设计为使用被动渲染引擎...catch 22...
标签: java swing jpanel jlayeredpane