4

我是Java和一般编程的新手,我正在尝试用宇宙飞船和外星人编写一个小型射击游戏,但在图形方面遇到了很多麻烦。似乎我混合了很多不同类型的组件。

我该怎么做才对?
- 我应该使用 SwingJFrame然后添加一个Graphics对象吗?
- 我应该先制作一个面板然后在上面添加图形吗?
- 或者也许我应该使用画布而不是 JPanel?

有很多选择,在网上搜索答案让我很困惑。有些人建议使用该paint()方法,而其他人则在使用paintComponent()...

以正确顺序放置图形的首选方式是什么?我应该使用哪些类?

4

4 回答 4

5

对于严肃的游戏,不要使用 Swing,而是使用其他更特定于游戏的 GUI 库,例如LWJGL。对于简单的游戏,Swing 是可以的,但请务必先阅读图形教程,因为您对如何绘制的假设可能需要更改(我知道我的假设是这样)。例如,您不会使用 Graphics 类字段,但通常会paintComponent在 JComponent 的方法中被动绘制。

于 2013-02-02T22:41:24.097 回答
5

对于简单的游戏,Swing 很好,您可以依赖以下内容:

  1. 使用 Swing 并忘记 AWT。使用更少的代码,您将获得更好的结果。
  2. 使用 Swing Timer 调整游戏节奏
  3. 对于您的每个组件,扩展JComponentJPanel覆盖paintComponent。仅paintComponent执行绘图操作(不要更新模型或修改组件的状态)。
  4. 每当你想画东西时,修改你的组件状态然后调用repaint()
  5. 要处理图层,您可以随时使用JLayeredPane
于 2013-02-02T22:42:23.693 回答
2

我可以看到@Hovercraft 建议的使用游戏 API 的感觉,但感觉很多简单的游戏都可以没有它。

我同意@Guillaume 的前两点,但之后往往会朝着不同的方向发展。

让我们假设游戏:

  1. 是固定大小(即不可调整大小)。
  2. 没有组件出现在它上面。

在这种情况下,我倾向于BufferedImage在标签中显示的中进行渲染。

具体问题的答案

我应该使用 Swing JFrame 而不是将其添加为 Graphics 对象吗?

那不会编译。所以不行。

我应该先制作一个面板然后在上面添加图形吗?

这基本上是纪尧姆的建议,尽管我更喜欢使用图像作为画布。

或者也许我应该使用画布而不是 JPanel?

如果你的意思是“画布”,java.awt.Canvas那么没有。
如果你的意思是,java.awt.image.BufferedImage那么是的。

有些人建议使用该paint()方法,而其他人则在使用paintComponent()...

这是一个常见的混淆,因为万维网上有太多旧的和糟糕的代码。

唯一可以使用覆盖paint(Graphics)的组件是 AWT 和 Swing顶级容器的组件,例如JFrameJAppletJWindow.

  • AWT 是上个千年的 GUI 组件工具包。我们应该在这个千年使用 Swing。
  • 自定义绘制整个 GUI 是不寻常的。相反,它可能会被添加为报告玩家健康、剩余生命、得分等的主要组件。出于这个(和其他)原因,最好渲染到“非顶级容器”,这会让我们看到在JComponentor中进行自定义绘画JPanel

对于扩展面板或组件中的自定义绘画,覆盖paintComponent(Graphics). 这是为这些组件进行自定义绘制的正确方法。

其他提示

游戏的每个对象(例如ShipEnemyMissile)都应该知道如何绘制自己。在绘画例程中保留对每个游戏元素的引用,并简单地调用gameElement.paint(Graphics)(或Graphics2D)它正在绘画的图形实例。

如果游戏元素是从基于 Java-2D 的Shape实例中绘制的,或者如果Shape可以从现有的精灵图像中定义,那么碰撞检测就变得简单了。详情见:

  1. 使用动态形状获取鼠标检测的答案
  2. 复杂形状的碰撞检测的答案
于 2013-02-03T03:19:43.923 回答
1

我不得不为一个课程项目实现一个迷失的维京人游戏,并且不知道如何去做,心里有完全相同的问题。

我最终编写了负责绘制不同元素的方法(即,一种用于绘制敌人,一种用于绘制导弹等),然后在 paint() 方法中调用它们。我在主循环中调用了 repaint() 方法来重绘所有内容。

我不确定这是否是一个好习惯,但它确实有效。你可以在这里查看代码,不过,我必须警告你这是一个“该死的,我必须完成它”的项目。你应该专门看看 GameFrame.java。

于 2013-02-02T23:27:56.410 回答