碰撞检测代码应该在哪里?
我正在编写一个乒乓球游戏,我有一个球类,它具有速度 x、y、位置以及每帧通过调用 @ball.update 更新的所有内容,这会将球向前移动 x_vel 和 Y_vel 等。问题是我的碰撞代码应该在循环中还是在球类的更新方法中?还是应该全部都在循环中并且球不应该对其位置进行任何控制?
I'm writing a pong game and I have a ball class that has velocity x, y, positions and all that stuff that every frame is updated by calling @ball.update, this moves the ball forward by its x_vel and Y_vel etc. My question is Should my collision code be in the loop or in the update method of the ball class? Or should it all be in the loop and the ball should not have any control of its position?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
碰撞检测不应在球类中完成,因为它需要了解游戏中的所有其他对象。
想象一个有许多物体的射击者,并考虑如果每个物体都尝试自己计算碰撞会发生什么。
应该有一个专门的类来关心碰撞检测。如果该类的任何受监督对象更改了其位置,则会通知该类。然后它检查碰撞并通知所有发生碰撞的对象(不仅仅是 2:)。
玩得开心... :)
The collision detection should not be done in you ball class because it would require the knowledge of all other objects in your game.
Imagine a shooter with many objects and think about what happens if each object would try to calculate the collision on it's own.
There should be a dedicated class that cares about collision detection. This class is notified if any of its supervised objects changed its position. Then it checks for collision and notifies all abjects (not only 2 :) that have a collsion.
Have fun... :)
像你描述的 Ball 类确实是一个好主意。这样,如果您想生成两个或更多球,就像在某些“突破”游戏中一样,或者您想在另一个游戏中重复使用该代码,您就可以复制它。您还可以拥有一个具有相似 X、Y 坐标的 Paddle 类(或者从“ScreenObject”类派生 Ball 和 Paddle,如果它们共享许多此类相似的成员)。 Paddle 可以读取由接收用户输入的线程/事件更新的共享变量。
简单的碰撞(例如与墙壁的碰撞)可以在 Ball 类中基于全局可访问的值(例如屏幕尺寸范围)来完成。当特定的墙壁被击中时,您的更新例程可以简单地反转一个速度分量。您可以在 Ball 类中定义和设置委托/回调,以在球弹起时播放声音。同样,Paddle 的更新可以检查屏幕尺寸,因此您无法将 paddle 移出屏幕。
正如 TottiW 建议的那样,对象之间的碰撞最好在拥有所有对象或有权访问其 X、Y 成员或边界框的父“管理器”类中完成。这是很好的面向对象设计。球和桨不应该访问彼此的 X、Y 位置! ...但是经理确实如此。它还可以消除冗余的碰撞检查。如果对象 A 检查与对象 B 发生碰撞,则 B 不必随后检查与 A 的碰撞。因此,您的管理器类实际上需要做的就是,对于每个 Paddle,检查每个 Ball 的位置。这可以进一步简化,因为桨可能仅在一个方向(例如水平方向)在固定的 Y 位置移动。因此,您的第一次检查可以立即消除任何 Ball.Y < Paddle.Y,简单示例(取决于 Y 的方向)。
对于具有大量对象的游戏,您不想碰撞检测每个对象,而只想检测最近的对象。在这种情况下,“管理器”更像是一个“场景管理器”,它在 X 和 Y 方向上保存对象的链接列表。当对象移过其他对象时,它们会交换列表中的指针,因此列表始终保持排序状态。这样,对于任何给定的对象,我们都知道左侧/右侧/上方/下方的对象,因此我们只需要对这些对象进行碰撞检查...节省大量时间并使您的游戏以最大速度运行。但也许你还没到这一步!
祝你好运,就像其他人所说的那样,玩得开心!
A Ball class like you described is indeed a good idea. That way you can replicate it if, like in some "breakout" games, you ever want to spawn two or more balls -- or if you want to re-use that code in another game. You can also have a Paddle class with similar X,Y coordinates (or derive both Ball and Paddle from a "ScreenObject" class if they turn out to share many such similar members). Paddle can read a shared variable that gets updated by a thread/event receiving user input.
Simple collisions, such as against walls, can be done in your Ball class based on globally accessible values like the screen dimension extents. Your Update routine can simply reverse one velocity component when that particular wall is hit. You can define and set a delegate/callback in the Ball class to play a sound when the ball bounces. Similarly, Paddle's Update can check the screen size so you can't move the paddle off-screen.
Like TottiW recommended, collision between objects is best done in a parent "manager" class that owns all the objects or has access to their X,Y members or bounding boxes. This is good object-oriented design. Ball and Paddle shouldn't have access to each other's X,Y positions! ...but the manager does. It can also eliminate redundant collision checks. If object A checks to collide with object B, B shouldn't have to subsequently check for collision with A. So really all your manager class needs to do is, for each Paddle, check each Ball's position. This can be further simplified since a Paddle might only move in one direction, say horizontally, at a fixed Y position. Thus your first check can immediately eliminate any Ball.Y < Paddle.Y, for simplistic example (depending on Y's direction).
For games with lots of objects, you don't want to collison-detect every one, just the nearest ones. In that case, the "manager" becomes more of a "scene manager" which keeps linked lists of objects in both X and Y directions. As objects move past other objects, they exchange pointers in the lists, so the lists always stay sorted. That way, for any given object, we know the objects immediately to the left/right/above/below, so we need only do collision checks against those... saving lots of time and making your game run with maximum speed. Maybe you're not to this point, though!
Good luck and like the others have said, have fun with it!
对于 pong 来说,简单的矩阵运算就足够了。如果只有一个球类并且您仅使用它来保存元组,则不需要球类。
For pong simple matrix operations should be sufficient. A ball class is not needed if there is only one and you use it only for holding a tuple.