使用图形进行游戏的最佳方式

时间:2013-02-02 22:30:35

标签: java swing animation awt java-2d

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

我该怎么办呢? - 我应该使用Swing JFrame然后添加Graphics对象吗? - 我应该先制作一个面板并将图形添加到它上面吗? - 或者我应该使用画布而不是JPanel?

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

时演示代码

按正确的顺序排列图形的首选方法是什么?我应该使用哪些类?

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

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

  1. 使用Swing并忘记AWT。使用更少的代码,您将获得更好的结果。
  2. 使用Swing Timer来调整游戏速度
  3. 对于您的每个组件,请展开JComponentJPanel并覆盖paintComponent。在paintComponent中仅执行绘图操作(不要更新模型或修改组件的状态)。
  4. 每当您想要绘制某些内容时,请修改您的组件状态,然后调用repaint()
  5. 要处理图层,您始终可以使用JLayeredPane

答案 2 :(得分:2)

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

我同意@Guillaume的前两点,但在那之后会倾向于另一个方向。

让我们假设游戏:

  1. 是固定大小(即不可调整大小)。
  2. 没有任何组件出现在它上面。
  3. 在这种情况下,我倾向于在标签中显示的BufferedImage中进行渲染。

    具体问题的答案

      

    我应该使用Swing JFrame而不是添加一个Graphics对象吗?

    那不会编译。所以..no。

      

    我应该首先制作一个面板并将图形添加到它上面吗?

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

      

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

    如果用'canvas'表示java.awt.Canvas则表示没有。
    如果你的意思是java.awt.image.BufferedImage那么是。

      

    有人建议使用paint()方法,而其他人在使用paintComponent()时展示代码......

    这是一个常见的混淆,因为World Wild Web中有太多旧的和坏的代码。

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

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

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

    其他提示

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

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

    1. This answerGet mouse detection with a dynamic shape
    2. This answerCollision detection with complex shapes

答案 3 :(得分:1)

我必须为一个课程项目实施像游戏一样的迷你维京人,并且没有一个单一的想法如何去做,心中有完全相同的问题。

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

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