SpriteKit,像在Cocos2d中一样平滑地解决冲突

时间:2013-12-09 22:10:04

标签: box2d collision game-physics box2d-iphone sprite-kit

我对SpriteKit解决两个物体之间碰撞的方式有疑问。我正在开发一种游戏,其中精灵节点在随机位置动态添加到屏幕上。所有这些精灵都有物理机构相互碰撞。在较高的游戏关卡中,有很多精灵,有时会在另一个精灵之上添加新的精灵(只要碰撞得到顺利解决,这是正确的行为)。在Cocos2d + Box2d这种情况下,碰撞得以顺利解决。两个精灵都以相反的方向轻轻移动,直到它们不再碰撞为止。看起来相当不错,即使有很多这样的碰撞,运动动画也很流畅,FTP也很高。然而,在SpireKit上,事情看起来有点不同。当新的身体被添加到另一个身体之上时,从用户的角度来看,它不会被移动以解决碰撞 - 而是“远程移植”而不是。尖顶没有平滑的移动,它们只是被重新定位,它们不会再碰撞。它对于玩家来说看起来非常糟糕,即使游戏每秒运行60帧。我在Apple文档中读到:

  

碰撞用于防止两个物体相互穿透。当一个物体撞击另一个物体时,Sprite Kit会自动计算碰撞的结果并对碰撞中的物体施加冲动。

但它看起来并不像所描述的那样发生。 Apple告诉我,当发生碰撞时,会有相互碰撞的身体产生冲动,但在现实生活中看起来身体被“传送”(立即移动到不再触发碰撞的地方)。也许施加在身体上的力量是如此强大,以至于你无法看到物体运动。我想知道是否有办法在SpriteKit中改进这种行为,所以看起来更像是在Cocos2d + Box2d中。 Apple的SpriteKit毕竟基于Box2d。

2 个答案:

答案 0 :(得分:1)

实际上,重叠体并不是物理引擎试图建模或将其作为特征整合到其设计中的行为 - 观察到的行为仅仅是一种副作用,并且可能受到身体参数的严重影响(绝对是“子弹”或“连续”碰撞检测,Sprite Kit术语中的usesPreciseCollisionDetection

在Box2D这样的刚体物理引擎中,物理引擎努力避免使用两个重叠体。它的速度 - 迭代地超过几帧或(接近)瞬时 - 可能是物理引擎的特定属性,它可以是内部初始化的设置。

您描述的“软”方式对于常规碰撞解决实际上可能非常有问题。特别是如果身体设计为刚性的,即球员身体即使只是一点点也不能穿透墙壁或地板。 Sprite Kit尝试完全避免这种行为是有道理的,它通常比有用或可取的更有问题。

所以答案是:尝试不同的参数变化,看看你是否能得到理想的行为。但是如果在Sprite Kit中实际上无法实现两个缓慢移动的重叠体,我不会感到惊讶。除非尸体没有足够的空间完全分开。

答案 1 :(得分:1)

I found a solution in my case. Unfortunately my situation might be different.

For me, my problem was that when there were more than one Physical Body contacting the players physical body, it would teleport the player. In my game, when the player grabbed a collectible item right at the moment an attack hits the player and is overlapping him (so both the collectible and attack physical bodies are overlapping the players physical body) it would teleport the player. This was even with collisionBitMask = 0 for all of them.

I was able to organize the contactBitMasks in such a way that 2 contacts were not being registered for 2 things at once from the same Sprite. That's hard to explain without an example:

Note: collisionBitMask = 0 for all of them (the player only collided with the ground)

What I had before:

Player

contactBitMask = Attack | Collectible

Attack

contactBitMask = 0

Collectible

contactBitMask = 0

What fixed it:

Player

contactBitMask = Attack

Attack

contactBitMask = 0

Collectible

contactBitMask = Player

After changing it to the above, nothing teleports and the physical bodies can overlap with nothing going wrong.