【问题标题】:Java Game Engines [closed]Java游戏引擎[关闭]
【发布时间】:2011-01-25 17:08:18
【问题描述】:

我最近一直在研究游戏开发,我的第一门编程语言是 Java。在玩了许多用 c++ 开发的令人惊叹的游戏之后,我想知道为什么 Java 在游戏行业中没有大量使用。我查看了 jMonkeyEngine 3 和其他一些游戏引擎环境,但我看到的屏幕截图远没有那么令人惊叹。 EA 的《极品飞车》热追和 ubisoft 的《刺客信条》等游戏都传达了这种真实感。 为什么Java不能出这样的行业实力游戏? 是艺术品吗?

Java 和 C# 具有自动垃圾回收功能,而 C++ 则没有。程序员必须密切注意内存使用情况,以避免出现悬空指针等问题。

谢谢大家。

【问题讨论】:

  • 试试看 LWJGL,它是一个很棒的 Java 图形库。不过,如果没记错的话,它是相当新的。

标签: java game-engine


【解决方案1】:

Java 和 C# 有自动垃圾 集合而 C++ 没有。这 程序员必须更加关注 到内存使用来避免悬空 指针等等。

你自己已经回答了你的问题。

在游戏编程中,垃圾收集不是优势。即使 Java 在大多数任务上的性能或多或少与 C++ 相当,而且 JIT 甚至可以进行非常激进的优化,超过静态分析期间可以完成的优化;垃圾回收可以让帧率在最糟糕的时刻下降。

此外,对于图形密集型任务,Java 也不是很合适,因为有很多东西被运行时认为是不安全的,因此是被禁止的(比如转换指针以重新解释数据)。

另一个重要的问题是行业中已经确定的技术。 C++在游戏行业的惯性是巨大的。今天所有的游戏开发者都知道 C 和 C++。拥有庞大的开发人员库可减少管理风险之一,即离开公司的关键人员。

但尽管如此,还是有一些成功的游戏,其中一些部分是用 Java 编写的,比如Vampire: The Masquerade - Redemption

Minecraft 这样的最新游戏完全用Java 编写;但它没有采用最先进的图形,因为重点更多地放在了虚拟环境的动态特性上。

许多其他游戏和引擎的运行时支持基于高性能渲染和网络平台(用 C/C++ 编写)构建的托管(安全自动内存分配和收集)脚本语言,例如 Unreal Engine 用于例子。

【讨论】:

  • 你有关于“吸血鬼:化妆舞会 - 血统”的任何参考,其中使用了 Java 的任何部分吗?我现在硬盘上有游戏,如果使用 python,其他所有内容似乎都是本机代码(C/C++ DLL),但任何地方都没有 JAR 文件的踪迹。我在互联网上找不到任何参考资料。我错过了什么吗?
  • @paercebal 你是对的,这是《吸血鬼:化装舞会 - 救赎》系列中的前一个游戏,它是用 Java 编写的,Bloodlines 似乎是用 Python 编写的(查看此采访: gamasutra.com/view/feature/3147/…)
  • @fortran:很棒的链接!我是一个粉丝,并且承认 Redemption 实际上在我的 GOG 图书馆等着我。现在,在 Redemption 中,Java 不是用于实际的游戏引擎,而是用于脚本部分,这不是性能密集型的。我怀疑问题是关于 Java 的那种使用...
【解决方案2】:

一般来说,这里所说的一切都是不移植到 Java 进行游戏开发的理由; 曾经。游戏行业目前正在发生范式转变。三件事已经改变或正在改变游戏行业:

  • 盗版
  • 客户端-服务器程序模型
  • 模块化网络程序模型

游戏不再完全依赖于自身。前者(低级语言)中存在的主要优势正在放缓,但被 C# 和 Java(高级语言)等语言中存在的优势所抵消。两个粗略但不可否认的例子是在 Facebook 上运行的游戏,以及手机、平板电脑等远程媒体

重要的是要说明在所有两种情况下,上面列出的所有三个问题都已解决。没有服务器就无法运行的游戏无需担心被复制侵权(不包括通过逆向工程进行的私人托管)。对网络相关游戏的需求需要一种能够平衡系统性能和网络性能的语言(通常是 Java 和 C/C++ 之间的僵局偏爱 C/C++,严格来说是因为丰富的现有库)。但是,在模块化网络程序模块中设计的游戏对于使用 C/C++ 等低级语言进行开发是不切实际的。一家有兴趣使用 C/C++ 为模块化网络程序模型设计游戏的公司将不得不创建一个完全专用于该游戏的虚拟机,或者对游戏进行多次重新编程/重新编译,这简直让人无法想象。 IMO,虽然现在说哪种语言是首选语言可能还为时过早,但出于三个关键原因,我将赌注押在 Java 上。

  • 1) JVM 允许基于 Java 的应用程序在任何 平台,无论是 Apple、Android、Windows 8 还是 Linux/UNIX 派生的 (实际上也支持任何硬件平台)。

  • 2) Java 使用 OpenJL(OpenGL 衍生产品,将在 OpenGL 上运行 作为客户端 - jMonkey 是在 OpenJL 中设计的引擎)。它是 需要注意的是,只有 Microsoft Windows 使用 DirectX,同样好 尽管可能,它只有一个缺点。几乎所有可以运行游戏的操作系统都将 能够在 OpenGL 中渲染和模块化设计正在推动这一点 前所未有。 (请注意,微软试图通过垄断 Windows 8 的发行来绕过这个问题。

  • 3) Java 支持 JVM 内部的线程,这允许它 充分利用多核处理器而不使用 任何第三方库。目前,这对所有其他 语言(尤其是为手机开发的语言)。

虽然 JVM 确实存在延迟问题,但应该注意的是,这些问题可以通过线程来消除。我也不会太担心 Windows 8 和微软的推动。谷歌的股票为每股 720 美元,苹果为 526 美元,微软为 27 美元。虽然苹果很可能会受到微软的推动,主要是因为使用了 C#,但另一方面,谷歌很可能会从中获利。微软在与谷歌竞争时从来没有太多幸运,谷歌/Android 大量使用 Java。 Angry Birds 最初是用 Java 设计的,仅供参考,然后移植到 iPhone 上的 C#。如果 Google/Android 强制执行标准化,微软将像苍蝇一样坠落,将苹果带走。

【讨论】:

  • “iPhone 上的 C#”——你的意思是目标 C,对吧?
  • 不确定个股价格与它有什么关系。市值可能稍微相关一些,但仍然没有太大关系。
  • 3 年后,我知道,但我想指出 Xamarin 早于您的评论,所以他本来可以谈论这个。 @大卫
【解决方案3】:

我只想解决这个问题的一个方面,但垃圾收集对于创建 AAA 类型游戏引擎的低级、性能关键方面没有必要帮助。事实上,避免这种对象的引用和收集系统是有帮助的。您甚至希望用户定义的类型在内存中是连续的,并适合缓存中的相邻对象等。

除了定期收集垃圾和将对象分散到内存中的性能问题之外,游戏无法承受其庞大的资源造成的泄漏,而垃圾收集器会阻碍那里的事情。是的,我刚刚说过GC 会阻碍避免泄漏的能力

垃圾收集并不是防止资源泄漏的灵丹妙药。

虽然听起来有悖常理,但请看看当今最泄漏的应用程序:您使用它们的时间越长,内存使用量就会越来越多地持续上升。通常它们不是 C 或 C++ 应用程序。 C/C++ 应用程序可能因崩溃而臭名昭著,但泄漏却并非如此。那些泄漏的代码更经常用带有垃圾收集的语言编写。

以 Flash 游戏为例。那里有很多,而不仅仅是完整的业余软件,它们使用越来越多的资源并且玩游戏的时间越长越慢,迫使您有时重新启动浏览器以再次快速玩游戏。然而,它们是用 ActionScript 编码的,这是一种具有垃圾收集功能的语言。

理论上垃圾收集应该减少泄漏。在实践中,它通常会消除更便宜且更易于修复和发现的物理泄漏(哎呀,我忘了删除这个字符串),以换取更昂贵且难以隔离的逻辑泄漏(哎呀,逻辑系统会导致大量资源在整个游戏关闭之前徘徊)。

这是因为在 GC 语言中,如果您想创建新资源 R 的共享所有权,您所要做的就是将其句柄/引用存储在另一个对象 A 中。 BC 也可能存储R 的句柄,现在R 拥有三个所有者,并且只有在所有三个所有者都释放引用时才会被释放。用户只能看到和使用A 存储的内容,因此游戏逻辑涉及定期从A 中删除R,但对它的引用在BC 中默默地徘徊,代码忘记发布了。在 C/C++ 中,BC 中的悬空指针实际上可能更可取,因为它会在播放测试期间导致立即可检测和可纠正的问题,运行调试器的开发人员将很快发现并修复问题。在 GC 语言中,检测起来非常困难,虽然程序不会崩溃,但它可能会开始大量泄漏。

所以 GC 肯定会避免悬空指针,但如果某些东西在 C/C++ 中一直悬空,而在 GC 语言中不会悬空,那么它在 GC 语言中是逻辑资源泄漏,在 C/C++ 中是段错误。换句话说,GC 将悬空指针交换为永远存在的悬空资源。它将明显的崩溃转换为无声的泄漏,这可能是调试的噩梦(甚至可能在发布产品后很长时间才被忽视)。因此,对于像游戏这样的游戏来说,它正在创建庞大的动态世界、图形和物理对象等等,并且可能在每一帧中,逻辑资源泄漏都是一件大事。

当资源泄漏不是什么大问题时,垃圾收集是最好的。

不幸的是,前面的场景在使用 GC 的大型团队环境中太常见了,尤其是如果每个程序员都不是很小心垃圾收集的陷阱和对弱引用的强烈需求的话。所以 GC 不一定是制作游戏的优势,除非你只是在谈论最高级别的人类逻辑。必须不断创建、访问和销毁资源的较低级别、精细的系统逻辑通常会运行得更好,即使在避免泄漏方面,如果没有它。

【讨论】:

    【解决方案4】:

    您的问题的答案是艺术品和财务资源。最初 Minecraft 是由一个人用 Java 开发的。而 AC 或 NFS 等头衔是由数千人的团队开发的。比较资源。此外,育碧使用自定义游戏引擎。如果你是唯一的开发者,你应该专注于这个想法,因为缺乏资源。如果你知道垃圾收集器在普通的独立开发者游戏中是不明显的。而作为唯一的开发者,你应该选择最快速的开发技术。

    【讨论】:

      【解决方案5】:

      垃圾收集在游戏行业中未被使用并不完全正确。虚幻引擎 3 为“脚本”类实现了垃圾收集。对他们来说,轻用时性能尚可;繁重的工作由管理自己内存的 C/C++ 代码完成。

      正如 fortran 所说,Java 并没有真正用于游戏行业,因为对速度的担忧(Java 在 VM 上运行代码,而不是本地运行......大多数时候)并且因为已经有大量有才华的游戏用 C 和 C++ 编写了大量常用代码的程序员。这并不是说你不能使用 Java 来制作游戏,因为那里有一些 Java 游戏,但是“主流”游戏行业已经在 C/C++ 后端投入了大量资金。

      【讨论】:

      • 一点更正:现代 JVM 以本机速度运行代码。 JVM 带有一个 JIT 编译器,它跟踪一段代码的运行频率,一旦引用计数达到特定阈值,它就会将该代码编译为本机机器代码。这就是为什么一些 Java 基准测试包括通过强制 JIT 编译代码来“启动”引擎的丢弃运行。
      【解决方案6】:

      fortran 和 James 已经很好地介绍了它,但我想提到的另一件事是,在谈到惯性时,fortran 暗示了这一点,那就是 C++ 中可用的巨大库池。拥有多个 C++ 库来处理几乎所有你能想到的东西是不切换到 Java 的一个重要原因。这并不是说现在没有 Java 库,但 C++ 库已经成熟并且拥有大量经验丰富的开发人员社区。不必重写你以前做过 1000 倍的相同事情,这样可以节省大量时间。

      【讨论】:

      • 我认为说没有成熟的 Java 库可用有点用词不当。虽然 Java 世界中专门针对游戏的库可能较少,但有无数成熟的库可免费用于几乎所有 Java 事物。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多