【问题标题】:Space Invaders in Java... Components or paintJava 中的 Space Invaders... 组件或绘图
【发布时间】:2012-06-23 03:49:33
【问题描述】:

我在 Java 方面经验丰富,并且在 Swing(表单类型应用程序)方面做了一些工作,但我从来不需要比这更强大的功能,所以我不太了解 GUI 引擎盖下发生的事情 -明智的。这是我从我一直在做的一点点阅读中收集到的。我确定它已经关闭了。

在编写太空侵略者类型的游戏时,我想到的两种方法是:

  1. 为所有增量绘画和分层创建一个大组件和代码。
  2. 在包含文本和图像的 JLayeredPane 中创建一组嵌套绝对定位的 JPanel,然后仅对可能需要重绘的 JPanel 调用 repaint()。然后覆盖paintComponent()(不确定是否自动清除以前的内容)。根据我的阅读,这将处理组件的分层和重绘,而无需重绘整个屏幕。

这是正确的吗?如果是,哪种方法更适合该项目?

【问题讨论】:

  • @Charles 谢谢!对于那个很抱歉。我真的很重视我在这里得到的帮助。我要勤奋地说出来!
  • 我建议完全远离 Swing,正如您正确指出的那样 - 它是用于 GUI,而不是游戏。对可用的游戏特定 Java 库进行一些研究。

标签: java swing user-interface


【解决方案1】:

当谈到用 Java 进行游戏编程时,真正需要考虑的一件事是切换到主动渲染。

我们知道,Swing 负责在另一个线程中进行渲染,称为 Event Dispatch Thread。这称为被动渲染,因为您并没有真正渲染自己的可视化组件,而是您定义了应用的外观,Swing 会在他需要时实际绘制它。

游戏通常在全屏模式下运行,并且通常需要更多地控制“何时”、“如何”和“什么”将被绘制。这称为主动渲染。在这种情况下,您必须禁用 Even Dispatch Thread 并自己进行渲染。

这一切都说得通,因为游戏通常在一个大循环中运行。游戏循环的一个示例是:

  1. 获取输入数据(键盘、操纵杆等)
  2. 网络通信(在客户端-服务器游戏的情况下)
  3. 根据输入数据处理逻辑。 (最终,当用户告诉它时,这将导致游戏退出)。
  4. 更新游戏的状态机。
  5. 根据新状态重绘场景
  6. 重启循环。

有很多来源,但我建议先阅读一下以澄清这一点:Passive vs Active Rendering

【讨论】:

  • 另一个更完整的资源:@​​987654322@
  • 非常有趣...看起来该应用程序不一定能很好地调整窗口大小等,对吧?如果您将所有渲染代码放在一个顶级组件中,然后有一个循环调用 repaint() 会怎样?你能得到窗口事件并有更多的控制权吗?
  • 事实上,当您激活全屏模式时,您将窗口设置为操作系统/显卡支持的尺寸之一。这样,窗口实际上占据了整个屏幕。如果您需要调整它的大小,它实际上是在任何游戏中完成的:您以编程方式将活动维度设置为支持的显示模式之一。 java.awt.DisplayMode 是一组宽度、高度、位深度和刷新率。
  • 能否建议您查看exampledepot.com/egs/java.awt/screen_FullWin.html 中的Java 全屏模式示例以及“相关示例”小节中的其他功能?其他功能包括如何获取可用显示模式的示例。
  • 在游戏中,通常在获得所有已安装图形设备及其各自显示模式的列表后,您会向用户提供从其中一个选项中进行选择的选项。我现在想起了许多游戏:我选择了一个“视频选项”对话框,然后我看到了一组明确的分辨率,然后我选择了一个。当我按下“激活”时,游戏引擎会切换到它。
【解决方案2】:

对您的方法的一些想法

第一种方法可能会执行得更好,因为您可以只为整个绘图使用一个 VolatileImage。但是,您说得对,它比第二种方法更复杂,因为您必须自己处理所有分层。

第二种方法很好,不仅仅是因为您已经陈述的原因,还因为如果您需要在鼠标进入屏幕上的特定“精灵”时执行处理之类的操作,Java 的 JPanel 会自动为您提供执行。也就是说... Space Invaders 克隆通常由键盘控制,因此您是否实际使用此功能完全是另一回事。

底线...我通常最终在paint() 范式中做这种事情。分层油漆一点也不难,特别是对于像 Space Invaders 这样简单的游戏,如果您决定使用 VolatileImage 作为后台缓冲区,它将更容易提高性能。

其他想法

正如其他人所说,很难在 swing 中获得一致的“帧速率”,因为您无法控制“何时”渲染某些内容 - 这是由 EDT 决定的,它与您的代码异步运行。如果您决定依赖 EDT,您可以尝试使用 SwingTimer 进行渲染。请格外小心,以正确同步您的渲染和更新到底层游戏状态。

【讨论】:

    猜你喜欢
    • 2013-11-06
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多