简单的效率问题C++ (内存分配)..也许一些碰撞检测有帮助?
我正在用 C++ 编写一个类似街机的小游戏(多向 2d 空间射击游戏),并且正在完成碰撞检测部分。
以下是我的组织方式(我只是编造出来的,所以它可能是一个糟糕的系统):
每艘船都由圆形组件组成 - 每艘船中的组件数量是任意的(更多组件,更多 CPU 周期)。 我有一个 maxComponent 距离,是在创建船舶时计算的,这基本上是我可以从船舶中心到最远组件边缘绘制的最长线。 我跟踪屏幕上的内容,并使用 maxComponentDistance 来查看它们是否足够接近以发生碰撞。
如果它们非常接近,我就会开始检查不同船舶的组件是否相交。 这就是我的效率问题出现的地方。
我有组件相对于船舶中心的 (x,y) 位置,但它没有考虑船舶当前如何旋转。 我保持它们是相对的,因为我不想每次船舶移动时都重新计算组件。 因此,我有一个用于旋转计算的小公式,并返回一个对应于相对于船舶中心的旋转考虑位置的二维向量。
碰撞检测位于 GameEngine 中,并且使用 2d 向量。 我的问题是关于返回类型。 我是否应该在每次调用该函数时创建并返回一个 2d 向量对象 或者 我应该给该组件对象一个额外的私有二维向量变量,在调用函数时编辑私有变量,并返回指向该对象的指针吗?
我不确定内存分配的效率与拥有永久、可编辑、私有变量的效率。 我知道还必须为私有变量分配内存,但不是每次检查冲突时都分配内存,只有在创建新组件时才分配内存。 在我的环境中,组件并不是恒定的,因为它们会在飞船被摧毁时被删除。
这是我的主要困境。 我也非常感谢任何有关我的实际碰撞检测系统设计的指示。 这是我第一次对此进行破解(也许应该阅读一下)
提前致谢。
I'm writing a little arcade-like game in C++ (a multidirectional 2d space shooter) and I'm finishing up the collision detection part.
Here's how I organized it (I just made it up so it might be a shitty system):
Every ship is composed of circular components - the amount of components in each ship is sort of arbitrary (more components, more CPU cycles). I have a maxComponent distance which I calculate upon creation of the ship which is basically the longest line I can draw from the center of the ship to the edge of the furthest component. I keep track of stuff onscreen and use this maxComponentDistance to see if they're even close enough to be colliding.
If they are in close proximity I start checking to see if the components of different ships intersect. Here is where my efficiency question comes in.
I have a (x,y) locations of the component relative to the ship's center, but it doesn't account for how the ship is currently rotated. I keep them relative because I don't want to have to recalculate components every single time the ship moves. So I have a little formula for the rotation calculation and I return a 2d-vector corresponding to rotation-considerate position relative to the ships center.
The collision detection is in the GameEngine and it uses the 2d-vector. My question is about the return types. Should I just create and return a 2d-vector object everytime that function is called
or
should I give that component object an additional private 2d-vector variable, edit the private variable when the function is called, and return a pointer to that object?
I'm not sure about the efficiency of memory allocation vs having a permanent, editable, private variable. I know that memory would also have to be allocated for the private variable, but not every time it was checked for collisions, only when a new component was created. Components are not constant in my environment as they are deleted when the ship is destroyed.
That's my main dilemma. I would also appreciate any pointers with the design of my actual collision detection system. It's my first time giving a hack at it (maybe should have read up a bit)
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您绝对应该尽量避免在每次调用 getter 函数时为组件向量分配内存。 相反,尽可能少地进行分配。 例如,您可以在船舶的组件组成发生变化时执行此操作,甚至很少发生(通过过度分配)。
当然,您也可以研究内存池,在内存池中预先分配大量此类组件并将其放入池中,以便您可以在恒定时间内分配新组件。
作为进行这种碰撞检测时的一般要点(如果太明显的话,我们深表歉意):计算距离的平方,而不是计算平方根。 :)
You should absolutely try to avoid doing memory allocations for your component-vector on each call to the getter-function. Do the allocation as seldom as possible, instead. For instance, you could do it when the component composition of the ship changes, or even more seldom (by over-allocating).
You could of course also investigate memory pools, where you pre-allocate lots of such components and put in a pool, so you can allocate a new component in constant time.
As a general (and apologies if it's too obvious) point when doing this kind of collision-detection: square the distances, rather than computing the square roots. :)
如果你的 2D 向量只是:
那么一定要返回它! 例如:
或者通过引用传递:
不惜一切代价避免:
Vector 类固有的常量堆分配/释放是一个错误!
从计算角度来说,复制您自己的 Vector2D 类非常便宜。 与 Vector<> 不同,您自己的 Vector2D 类可以合并您喜欢的任何方法。
我过去曾使用此功能来合并distanceToOtherPointSquared()、scanfFromCommandLineArguments()、printfNicelyFormatted() 和operator[](int) 等方法。
或者我应该给该组件对象一个额外的私有二维向量变量,在调用函数时编辑私有变量,并返回指向该对象的指针?
多个函数调用使先前的数据无效。 这是灾难的根源!
If your 2D vector is just:
Then by all means return it! E.g:
Or pass by reference:
Avoid at all costs:
The constant heap allocation/deallocation inherent to the Vector class is a mistake!
Copying your own Vector2D class is very cheap, computationally speaking. Unlike Vector<>, your own Vector2D class can incorporate whatever methods you like.
I've used this feature in the past to incorporate methods such as distanceToOtherPointSquared(), scanfFromCommandLineArguments(), printfNicelyFormatted(), and operator[](int).
or should I give that component object an additional private 2d-vector variable, edit the private variable when the function is called, and return a pointer to that object?
Watch out for multiple function calls invalidating previous data. That's a recipe for disaster!
不要使用 2D 矢量。 相反,使用
点
的向量
。 对于碰撞检测也是如此。 这里使用二维向量是错误的数据结构。根据函数的内容,编译器将能够执行 NRVO(即 命名返回值优化)这意味着在最佳情况下,返回向量没有开销,即它永远不会被复制。 但是,只有当您使用函数的返回值来初始化新实例,并且编译器能够跟踪函数内部的执行路径并查看每个返回路径返回相同的对象时,才会发生这种情况。 请考虑以下两点:
编译器可以对
f
的调用执行 NRVO,但不能对g
的调用执行 NRVO。Do not use a 2D vector. Rather, use a
vector
ofpoint
s. Likewise for your collision detection. Using a 2D vector here is just the wrong data structure.Depending on the content of the function, the compiler will be able to perform NRVO (that is, named return value optimization) which means that in the optimal case, returning a vector has no overhead, i.e. it's never copied. However, this only happens when you use the return value of your function to initialize a new instance, and when the compiler is able to trace the execution paths inside the function and see that for each return path, the same object is returned. Consider the following two:
The compiler can perform NRVO for calls to
f
, but not forg
.在堆上分配内存和在堆栈上分配内存有很大区别。 在堆上分配,例如使用 new/delete 或 malloc/free 非常慢。 在堆栈上分配确实非常快。 对于堆栈,通常最慢的部分是复制对象。 因此,请注意向量等,但返回简单的结构可能是可以的。
There's a big difference between allocating memory on the heap and on the stack. Allocating on the heap, e.g., using new/delete or malloc/free is very slow. Allocating on the stack is really quite fast. With the stack, usually the slow part is copying your object. So watch out for vector and such, but returning simple structures is probably OK.