首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用timestep更新JLayeredPane中重叠的JLayeredPane时闪烁

使用timestep更新JLayeredPane中重叠的JLayeredPane时闪烁
EN

Stack Overflow用户
提问于 2013-12-30 05:36:05
回答 1查看 972关注 0票数 1

我在用Java做游戏。基本上,我有两个不同的“平面”更新,我需要照顾。底层是实际的游戏绘画本身。它只是一个覆盖整个JPanel的JFrame,并被绘制为使用它的Graphics对象。

我使用一个固定的时间步骤来处理这些第一个图形更新。为了防止不必要的更新,我重写了paintComponent()方法,完全不做任何事情,因为我已经编写了一个自定义render(float interpolation)方法来处理这个问题。

但是,除了原始鼠标单击和键盘输入之外,此面板不能接受任何输入。我需要创建各种菜单,文本框等的能力,也是在屏幕上。喜欢各种能力,甚至是“菜单”按钮,通常出现在大多数游戏的左上角。

为了处理这个输入,比如创建按钮,我有第二个JPanel,它应用了setOpaque(false)。然后创建我可能需要的各种Swing组件,比如一个JButton。

要包含这两个JPanels,我使用一个JLayeredPane,并适当地设置它们的层,如下所示。这样,输入层应该始终位于实际游戏层的顶部。

下面的代码显示了如何创建和添加Swing组件。addLoginDialog()是一种为登录添加Swing组件的方法。它已经过测试并正常工作,而不是问题所在。

代码语言:javascript
复制
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次运行的代码。

代码语言:javascript
复制
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一样进行更新。当鼠标移动到按钮上时,当我的组件被移动或调整大小时,等等。

另外,请注意屏幕闪烁的方式:背景图像变为空白,然后重复出现。输入面板总是在那里,但实际上是绘制在游戏绘图的后面,这是不应该发生的,因为它被放置在默认层中。我知道它并没有完全消失的原因是因为游戏画是部分透明的,所以我可以看到它下面,我添加的按钮仍然在那里。

我的主要问题是,如何停止闪烁?为什么当游戏绘图在JLayeredPane中较低层的面板上绘制时,游戏绘图被绘制在输入组件之上?和我认为最重要的是,是什么导致了闪烁?谢谢你的帮助。

EN

回答 1

Stack Overflow用户

发布于 2013-12-30 06:32:45

为什么游戏绘图是在输入组件之上绘制的,而游戏绘图是在JLayeredPane中较低层的面板上进行的?

主要是因为你绕开了Swing的运作方式。

让我们从以下事实开始:Graphics上下文是一个共享资源(通常每个本机对等方都有一个Graphics上下文),也就是说,每个组件都获得相同的上下文,这意味着,当您使用自己的绘图例程时,您基本上是在绘制其他所有内容。

RepaintManager负责决定应该绘制什么和什么时候。所以你现在看到的是两位艺术家为了同一幅画布而斗争,想同时在画布上作画,这简直是一团糟。

再加上Swing的绘画过程并不是线程安全,你就会陷入一片混乱之中。

如果你绝对必须有控制,那么你需要从方程式中移除Swing的绘画引擎。

首先看一下被动渲染与主动渲染

ps-使用BufferStrategy也有硬件加速的好处。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20833913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档