获取游戏中物体的位置
Posted
技术标签:
【中文标题】获取游戏中物体的位置【英文标题】:Getting the position of an object in a game 【发布时间】:2010-09-11 11:38:07 【问题描述】:我最近开始制作简单的 2D 游戏,遇到了一个难题 - 使用或不使用 getter 和 setter 方法来获取对象的 x 和 y 位置。如果我不使用方法,而是直接访问变量,它看起来会更清晰,而且,对对象的许多方法调用会损害性能。获取和设置位置也很简单,所以这里真的不需要封装吗?还是我们应该始终遵守 getter 和 setter 方法的约定?
【问题讨论】:
这个问题实际上是关于使用 getter 和 setter 的,关于这个话题已经有很多问题了。见:***.com/questions/565095/…***.com/questions/2977007/…***.com/questions/1568091/why-use-getters-and-setters***.com/questions/2747721/… 【参考方案1】:遵守约定总是更好。此外,JIT 将简化操作,以便直接访问字段,而不是遍历所有方法堆栈。
称为方法内联。
Java VM 的 Java 2 版本会在运行时自动内联简单方法。在未优化的 Java VM 中,每次调用新方法时,都会创建一个新的堆栈帧。创建一个新的堆栈帧需要额外的资源以及一些堆栈的重新映射,最终结果是创建新的堆栈帧会产生很小的开销。
方法内联通过减少程序调用的方法次数来提高性能。 Java VM 内联代码内联方法返回常量或仅访问内部字段。
资源:
sun.com - Performance Features and Tools关于同一主题:
Java language convention; getters/setters【讨论】:
+1:在 Java 和 C# 中,调用(简单)方法非常非常便宜。【参考方案2】:你不应该有 getter 和 setter,也不应该公开属性。
相反,您可以使用 .updatePosition()、.draw()、.moveTo()、.collideWith() 等方法,因此您无需直接从外部获取或设置值。
在极少数情况下,您确实想直接从外部获取/设置值,但这些情况很少见,而且往往表明设计不佳(尽管有 有效用途) .
【讨论】:
我会说业务对象不应该自己绘制。因此,为坐标使用 getter 总是好的,但我同意使用方法来移动对象而不是 setter 会更好。 @Colin:嗯,这取决于程序的架构。在更简单的情况下,如果对象可以将自己绘制到全局绘图缓冲区,那就没问题了。在稍微复杂一点的情况下,draw() 可能需要绘制缓冲区的一个参数来绘制。在更复杂的情况下,对象可能会返回一个绘图缓冲区,绘图管理器会将其组合到更大的设置中。在最复杂的情况下,draw() 可能只返回一个绘图委托来协助外部抽屉。这完全取决于设置的复杂程度。 我希望我能 +N 这个。设置和获取对象状态的各个组件总是 表明在该组件之外发生了组件逻辑。只需将需要直接访问的逻辑移入类本身即可。完成!【参考方案3】:我会使用 getter/setter。为什么?
-
封装是键。也许您稍后会更改存储位置的方式(例如,将笛卡尔坐标转换为极坐标?)。 Getter/setter 将允许您执行适当的转换。
Setter 将允许您的对象强制执行条件(例如 x > 0 和
另一个原因(尽管目前可能不适合您的需求)是许多 Java 框架使用反射和内省类来设置传统的setX
/getX
格式的设置器/获取器。通过实现这些方法,您的类可以立即在各种框架中重用。
在已知问题之前不要担心性能。过早的优化会让你头疼。
【讨论】:
同意#1,并且使用 Vector 类也很有用,而不是管理 18 个不同的 float/int。【参考方案4】:在Stendhal 中,我们确实使用了getter/setter。我们每回合处理大约 60,000 个可移动对象。根据我在 Stendhal 方面的经验,简单的方法根本没有任何可衡量的性能影响。我们进行了一些分析以发现各种问题,并在过去几个月中大大提高了性能。
我们遇到的主要瓶颈是寻路(尤其是与其他可移动物体的碰撞检测)。存在这样的问题,例如在每次可能的碰撞检查时创建一个新的 Pair 对象,或者在询问实体的位置和大小时创建一个新的 Rectangle 对象。
这些东西很容易在 Profiler 中发现(请参阅 gamedev 上的 Profiling server side game loop in java)。
游戏循环逻辑部分之外的其他常见延迟原因是客户端/服务器通信和数据库访问。
【讨论】:
以上是关于获取游戏中物体的位置的主要内容,如果未能解决你的问题,请参考以下文章
Unity3D视图中心 ( 视图中心概念 | 围绕游戏物体旋转 | 添加游戏物体到游戏场景的位置 )
Unity学习实现screen space模式下UI跟踪游戏物体(在 UI 中跟踪和显示任何 Gameobject 位置)