SpriteKit 节点粘在场景边缘/不反弹
Posted
技术标签:
【中文标题】SpriteKit 节点粘在场景边缘/不反弹【英文标题】:SpriteKit Nodes Sticking to Edges of Scene / Not Bouncing 【发布时间】:2014-08-21 10:59:08 【问题描述】:我已经搜索过这个,我认为必须有一些参数来解决这个问题,但我没有找到它。
我在 SpriteKit 中有一个场景,我希望一些圆圈/球在其中反弹并无限期地保持它们的任何速度。它们应该从场景的边缘反弹。
如果他们移动得足够快,或者以相当尖锐的角度击球,这是有效的,但如果他们跑得慢并且靠近边缘平面,他们会继续移动(这很好)但他们“坚持“到边缘。这种粘连是我不想要的。即使速度很慢,它们也应该会反弹。
为了设置边缘,我使用了:
SKPhysicsBody *borderBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
self.physicsBody = borderBody;
self.physicsBody.friction = 0.0;
self.physicsBody.restitution = 1.0;
self.physicsBody.linerDamping = 0.0;
self.physicsBody.angularDamping = 0.0;
self.physicsBody.affectedByGravity = NO;
在圆节点上,我有类似的设置,比如:
ball.usesPresciseCollisionDetection = YES;
ball.dynamic = YES;
ball.restitution = 1.0;
ball.linearDamping = 0.0;
ball.angularDamping = 0.0;
ball.friction = 0.0;
我的场景中的重力为零。我向节点添加了一个脉冲,它们开始弹跳——它看起来非常接近,因为物体会四处弹跳,但是如果有任何缓慢移动并以浅角度进入,它们会“拥抱”边缘。我将尝试在下面添加一个插图以帮助进行可视化。
http://i.imgur.com/Rpr7luY.png
我尝试了很多 PhysicsBody 设置,但无法停止粘连。
谢谢!
【问题讨论】:
物理模拟不准确的可能副作用。尝试关闭 allowRotation。如果这没有帮助,您可能不得不忍受这种行为。 将摩擦力设置为零摩擦力,防止它们在边缘弹跳,或者您可以在 didBeginContact 函数上获得 contact.collisionImpulse 并在每次边缘碰撞时施加很小的力或脉冲 我相信这是***.com/questions/27671391/…的副本 是的,没错。当赏金用完时,我会将其标记为重复。该死的 - 这真的是一个错误。 @Jurik 是的,这令人沮丧,我希望苹果能解决这个问题。 【参考方案1】:这个问题是多方面的,它与物理引擎本身的缺陷有关,但是,我设法在不需要任何第三方软件的情况下提出了一个解决方案,并且产生了一致的结果。
在这里查看我的解决方案:Accounting for Low Impact Angles/Velocities that Don't Register as Collisions
【讨论】:
【参考方案2】:正如大家所提到的,this answer 可以直观地被视为朝着正确方向迈出的一步,但问题在于整个 SpriteKit 物理引擎。它是不确定的,分数会在计算中丢失,导致模拟不精确。
简短的回答是改用 Box2D。骇人听闻的答案是向相反的方向施加冲动。
All details are highlighted in my other answer.
@Jurik 很高兴我能帮上忙 :)
【讨论】:
有没有办法让 Box2D 与 Spritekit 而不是 SpriteKit 物理引擎一起工作? @AlexShuraits 没有魔法,你必须实现自己的物理循环来替换 SpriteKit 的【参考方案3】:错误的初始化程序。有两种SKPhysicsBody
- 基于体积和基于边缘。您使用的是完全错误的类型,它不会参与运动。
请查看SKPhysicsBody Documentation.
【讨论】:
我认为这不能解决原始问题。我已经多次注意到,如果物体的速度太低,它们就不会反弹。 即使我的边缘恢复 = 1,在慢速球不会从边缘弹起并继续滑动,SpriteKit 有什么解决方案吗?以上是关于SpriteKit 节点粘在场景边缘/不反弹的主要内容,如果未能解决你的问题,请参考以下文章
Swift:Spritekit 中的多个场景,从第二个和第一个场景的不同 Sprite 节点类型调用 touchesBegan