1

我环顾四周,似乎没有人能回答我。我有一个JPanel在它运行时添加/删除标签的地方。问题是每次我添加一个新标签时,我都必须添加新标签才能revalidate()显示出来。每次我revalidate(),我都会得到一个非常烦人的闪烁,我所有的标签都会在我的窗口顶部出现一毫秒,然后返回它们正在做的事情。我唯一一次打电话revalidate()是在我添加标签之后;我不改变绘画方法或任何东西只做了

public void paintComponent(Graphics page)
{
    super.paintComponent(page);
}

这样我的页面就不会看起来很糟糕。我真的可以在这方面使用一些帮助。我用JFrame,Jlabel和游戏制作了一个小行星Jpanel游戏;它工作得很好,但是这种闪烁和组件“快速重影到面板顶部”令人无法忍受,而且我知道事实上这是revalidate()方法。

4

4 回答 4

2

使用标签(或通常是 GUI 组件)来表示快速动画、动态创建/移动的对象是不切实际的。就像开车从客厅开到厨房一样。

Swing 组件有很多不错的特性,例如它们可以确定它们需要的空间,并且布局管理器可以使用它来自动放置它们。不幸的是,对于一款游戏来说,你既不需要所有的好东西,也不想支付与之相关的处理开销。swing 多平台功能使事情变得更加复杂,这些功能要求每个组件都有一个对等组件(对等组件负责将组件呈现为活动外观)。

为了解决这个问题,您不要将单个游戏对象表示为挥杆组件。相反,您使用单个摆动组件(通常是 JPanel)作为画布来绘制您的游戏对象。您只需定期调用该 JPanel 的 repaint()(例如每秒 30 或 60 次)。当然,您将覆盖 JPanel 上的 paintComponent() 以使用您自己的代码绘制所有游戏对象。

编辑:概述您如何进行自己的渲染

您需要决定如何组织与游戏相关的对象。一个非常简单的骨架可能看起来像这样(省略了 getter/setter):

public class GameObject {
    public int x;
    public int y;
    public Image image;
}

实际上,此类将具有其他成员(例如控制对象如何移动的行为,可能还有一些动画状态/计数器)。它也可以是抽象的,每个可能的行为(如船、小行星和子弹)都有一个具体的子类。GameObject 的所有实例都在某种集合中进行管理,我假设您使用列表。

在实现 paintComponent 时,它归结为遍历列表并渲染每个对象的图像:

public void paintComponent(Graphics g) {
    List<GameObject> list = ... // however you obtain it in your game
    for (GameObject gobject : list) {
        g.drawImage(gobject.image, gobject.x, gobject.y, (ImageObserver) null);
    }
}

更复杂的游戏可能会命令游戏对象控制游戏对象如何相互重叠。但原则上它非常简单。

于 2013-02-16T15:18:07.560 回答
2

您是否考虑过重用它们——即setVisible(false)在不需要它们时使用它们?

不确定添加和删除标签是否是实现游戏所需的最佳方式。我个人很想自己管理这幅画。

于 2013-02-16T14:37:37.790 回答
2

作为一个具体的例子,Asteroids根本不闪烁。这里有几个原因:

  • 它在事件调度线程上运行。

  • 它使用JPanel,默认情况下是双缓冲的。

  • 它使用 来调整动画javax.swing.Timer,更新游戏的模型actionPerformed()

  • 它会覆盖paintComponent(),但可以安全地省略super.paintComponent(),因为动作侦听器会重新绘制整个面板。

  • 侦听器调用paintImmediately()以避免任何潜在的延迟;替代repaint()以查看您的平台是否有任何差异。

附录:如本反例所示revalidate()不会引起闪烁。不要替换标签,而是更新标签的图标,如此所示。

于 2013-02-16T14:17:51.707 回答
2

当我在过滤 Swing 组件时遇到问题时,结果证明是并发问题。既然你在做游戏,这意味着你在做动画,这里可能就是这种情况。

注意仅从AWT-EVENT thread. 使用SwingUtilities.invokeLater或使用javax.swing.Timer.

于 2013-02-16T10:51:24.503 回答