【问题标题】:Simple game development with Java and LWJGL [closed]使用 Java 和 LWJGL 进行简单的游戏开发 [关闭]
【发布时间】:2014-06-20 11:27:11
【问题描述】:

当然,我不是第一个开发这种游戏的人。但我想在未来几年内成为专业的游戏开发人员。我想实现一个射击游戏。这不是我的第一个。我在 1998 年在 Turbo Pascal 6.0 中开发了一个。但没有使用 OOP。这场比赛将是我在 Java 中的第二次射击游戏,但也是第一次使用 LWJGL。它将在 2D 中实现。

我想让它保持简单。但是有一些我想实现的功能。我计划制作 10 个关卡。玩家有一艘宇宙飞船,他可以在四个方向(上、下、左、右)移动。这艘船有一个双激光,只能向上射击。船只能移动,我不打算旋转。

一个级别有多个相同种类的敌人。敌人也是宇宙飞船。最简单的船只是向下移动。他们还发射单发或双发激光子弹。有激光有一个分钟。和最大。频率。我想定义一个数学函数,它定义了频率(在最小值和最大值之间)的可能性。

船速在敌人(和等级)内是恒定的。在以后的关卡中,敌人获得双倍或 2.5 倍的速度。更高级别的敌人拥有寻找玩家船只的激光。我计划在游戏后期让一个敌人拥有越来越多的激光子弹。

每个级别都没有其他障碍。每个级别都有一些星星作为背景。首先我要实现一个静态背景,然后我打算制作3种不同速度运动的星星。

玩家飞船的激光会造成单次或双次伤害,具体取决于是一发还是两发子弹击中。敌人有一些生命值,直到他们死去。玩家飞船在死亡前还有一些生命值。

我想要两种爆炸(由一些颜色从黄色到红色的集中分布的椭圆组成)。激光击中的小爆炸。以及船舶毁坏的大爆炸。

我的朋友告诉我,有一个每秒调用 60 次的函数来渲染图形对象。所以我认为在这个函数中我绘制了所有的对象并且什么都不做。但当然,船只和激光的坐标会发生变化。

所以我想我是否应该使用线程。

如果我要使用线程,我会将同时出现的每艘船分配给一个线程,并为每个激光器创建线程,然后为动态背景创建线程。在另一个线程中,我会等待键盘输入。

当然,使用线程与不使用线程之间存在权衡。

使用线程可以实现逼真的并行性,并且可能是流畅游戏所必需的。但是避免线程会导致更简单的编程,而不是并发访问数据。所以我问你们所有有经验的游戏开发者。你会使用线程还是不使用线程?如果你会使用它们,我的概念好不好。为什么?我也很高兴看到其他实用提示。

谢谢!

【问题讨论】:

  • 太宽泛了……还有文字墙,还有很多离题的东西。游戏设计概念讨论可能更适合GameDevSE
  • 确实太宽泛了。就像软件工程世界中的所有事物一样,您不能应用一种模式并始终坚持下去。这完全取决于您正在构建的游戏。为 pong 应用线程几乎毫无意义。在必须管理数千个计算机控制实体的 AI 的游戏中应用线程:一个更好的主意。注意:当然是在多核或多 CPU 系统上。
  • 有两点需要注意:(1)一个游戏可以做成一个线程+监听键盘输入等;这样的游戏看起来与多线程游戏相同(但不会使用所有可用的 CPU 能力)。 (2) 拥有更多线程(正在做大量工作)会显着减慢您的程序。如果您在双核上运行,则最多需要 4 个线程
  • @RichardTingle 虽然除非它是回合制游戏或非常琐碎的游戏,否则我会发现很难制作一个没有单独的专用线程不断更新游戏状态/渲染屏幕的游戏等
  • @CeilingGecko 然而三十多年来,即使在拥有当今移动电话资源 1/1000 的计算机上,程序员也能做到这一点。也许您只需要多看看周围就可以了解如何操作,这将丰富您的知识库并成为更好的游戏程序员。

标签: java opengl game-engine lwjgl


【解决方案1】:

任何游戏都可以使用单线程加上事件监听器来制作。这将使用更新循环每帧更新每个对象。用最简单的术语来说,这可以是一个带有Thread.sleep 的循环,尽管swing timers 是一种更高级的技术

int framesPerSecond=60;
double frameTime=1000.0/framesPerSecond; 

while(running){
    for(Updatable updatable:updatables){
         //should actually measure the frame time since it would actually be 
         //exactly this. System.nanoTime() can be used for this
         updatable.update(frameTime); 

         //depending on your graphics library each updatable object may be given
         //the opportunity to render itself here

    }

    renderFrame(); //render frame as appropriate for your graphics library
    Thread.sleep(frameTime); 
}

您绝对不能拥有的一件事是许多随心所欲的线程,每个线程都在不协调地做自己的事情。这几乎不可能在没有错误的情况下编写(而且效率非常低)。

使用适当数量的线程

在更新循环中,通常可以将更新分解为互不影响的独立部分。在这种情况下,您可以将每个部分分配给一个线程(thread pools 非常适合简化此过程)。线程的另一个很好的用途是准备游戏很快但不是现在需要的东西;比如生成下一层。

但是,多线程的规则是线程数不能多于内核数。每个线程都有不小的开销,但是一旦线程数多于内核数,您(通常)根本不会提高执行速度。因此,例如,决斗核心上的程序最多应该有 4 个线程来完成重要的工作。一个四核最多应该有 8 个等。

【讨论】:

  • 这是一篇很棒的帖子,但我有一个问题:您是否故意遗漏了渲染框架的示例调用(在这种情况下,我建议将其放入以保持完整性),还是您一次更新和渲染?
  • @Gimby 我忽略了它,主要是因为它的精确形式在库中有点不合时宜,我想让它专注于线程问题。我注意到标签包含 LWJGL,但我选择的 3D 库是 JMonkey(我是一个场景图人),所以如果我包含 LWJGL 调用,我几乎肯定会弄错。随意编辑它虽然
  • 我的目标是让它与 API 无关;就像你有一个通用的 updatable.update(),所以可以在示例中使用一个简单的 renderFrame(),而无需进一步指定它是如何做到的。毕竟它只是为了说明。不过,您的代码注释已经足够好了 :)
  • @Gimby 这实际上是一个非常好的主意。已编辑
  • 我想我会首先实现它串行线程。稍后我会将更新部分分解为独立的部分。然后我会比较运行时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
  • 1970-01-01
  • 2012-11-13
  • 1970-01-01
  • 2014-12-19
  • 1970-01-01
相关资源
最近更新 更多