然而,我的球保持平行于墙壁/其他矩形(如同,简单地向上和向下滑动),任何时候它们以陡峭的角度与它们碰撞.这里是相关的代码 – 我把物理属性转移到代码中,使它们更加可见:
import SpriteKit struct PhysicsCategory { static let None: UInt32 = 0 // 0 static let Edge: UInt32 = 0b1 // 1 static let Paddle: UInt32 = 0b10 // 2 static let Ball: UInt32 = 0b100 // 4 } var paddle: SKSpriteNode! var ball: SKSpriteNode! class GameScene: SKScene,SKPhysicsContactDelegate { override func didMoveToView(view: SKView) { physicsWorld.gravity = CGVector.zeroVector let edge = SKNode() edge.physicsBody = SKPhysicsBody(edgeLoopFromRect: frame) edge.physicsBody!.usesPreciseCollisionDetection = true edge.physicsBody!.categoryBitMask = PhysicsCategory.Edge edge.physicsBody!.friction = 0 edge.physicsBody!.restitution = 1 edge.physicsBody!.angularDamping = 0 edge.physicsBody!.linearDamping = 0 edge.physicsBody!.dynamic = false addChild(edge) ball = childNodeWithName("ball") as SKSpriteNode ball.physicsBody = SKPhysicsBody(rectangleOfSize: ball.size)) ball.physicsBody!.usesPreciseCollisionDetection = true ball.physicsBody!.categoryBitMask = PhysicsCategory.Ball ball.physicsBody!.collisionBitMask = PhysicsCategory.Edge | PhysicsCategory.Paddle ball.physicsBody!.allowsRotation = false ball.physicsBody!.friction = 0 ball.physicsBody!.restitution = 1 ball.physicsBody!.angularDamping = 0 ball.physicsBody!.linearDamping = 0 physicsWorld.contactDelegate = self }
忘了提到这个以前,但我添加了一个简单的touchesBegan功能来调试弹跳 – 它只是调整速度来指向球在接触点:
override func touchesBegan(touches: NSSet,withEvent event: UIEvent) { let touch = touches.anyObject() as UITouch let moveToward = touch.locationInNode(self) let targetVector = (moveToward - ball.position).normalized() * 300.0 ball.physicsBody!.velocity = CGVector(point: targetVector) }
normalized()函数只是将球/触摸位置增量减小到单位向量,并且有一个减号运算符的覆盖,允许CGPoint减法.
球/边缘碰撞应该始终以正确相反的角度反射球,但是由于某种原因,球真的似乎有一个直角的东西.我当然可以实现一些解决方法来手动反映球的角度,但重要的是我想使用SpriteKit中的内置物理功能来做到这一点.有没有什么明显的,我失踪了?
I have a fix for the problem with the ball “riding the rail” if it
strikes at a shallow angle (@aziz76 and @colinf). I added another
category,“BorderCategory” and assigned it to the border PhysicsBody
we create in didMoveToView.
和一个类似的SO问题here解释为什么发生.
Even if you do that,though,many physics engines (including
SpriteKit’s) have trouble with situations like this because of
floating point rounding errors. I’ve found that when I want a body to
keep a constant speed after a collision,it’s best to force it to —
use a didEndContact: or didSimulatePhysics handler to reset the moving
body’s velocity so it’s going the same speed it was before the
collision (but in the opposite direction).
另外我注意到,你正在使用一个正方形,而不是一个圆圈,你可能会考虑使用…
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width/2)
所以原来你并不疯狂,总是很好的从别人听到,希望这将帮助您找到一个最适合您的应用程序的解决方案.