【发布时间】:2016-08-07 15:46:05
【问题描述】:
我有一个简单的SpriteKit 应用程序,带有墙壁和球。两者都使用SKPhysicsBody 设置。
当我在一个方向上施加力时,我希望球在碰撞时以相同的角度在墙壁上反射,但方向相反。
但有时我看到的角度很奇怪。我玩了很多 physicsBody 属性,但无法修复它。有时第一次反射看起来不错,但第三次或第六次,有时第一次反射的角度不对。
我从不同的帖子中读到,人们有点自我计算“正确的方向”。但我无法想象SpriteKits 物理引擎无法做到这一点。
查看我附上的图片以了解我的意思。有人可以帮忙吗?我不想开始使用 Box2d for Swift,因为这看起来对我来说太难集成到 Swift 中了。
这是我的 GameScene.swift 文件中的 physicsWorld init,我的所有元素都添加到该文件中:
self.physicsWorld.gravity = CGVectorMake(0, 0)
添加我所有的代码太多了,所以我添加了重要的部分。希望它足以进行分析。球、墙等所有元素都是SKSpriteNode的
这是球的physicsBody 代码:
self.physicsBody = SKPhysicsBody(circleOfRadius: Constants.Config.playersize+self.node.lineWidth)
self.physicsBody?.restitution = 1
self.physicsBody?.friction = 0
self.physicsBody?.linearDamping = 1
self.physicsBody?.allowsRotation = false
self.physicsBody?.categoryBitMask = Constants.Config.PhysicsCategory.Player
self.physicsBody?.collisionBitMask = Constants.Config.PhysicsCategory.Wall | Constants.Config.PhysicsCategory.Enemy
self.physicsBody?.contactTestBitMask = Constants.Config.PhysicsCategory.Wall | Constants.Config.PhysicsCategory.Enemy
这是墙壁的物理体:
el = SKSpriteNode(color: UIColor.blueColor(), size: CGSize(width: Constants.Config.wallsize, height: Constants.Config.wallsize))
el.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: Constants.Config.wallsize, height: Constants.Config.wallsize))
el.physicsBody?.dynamic = false
el.physicsBody?.categoryBitMask = Constants.Config.PhysicsCategory.Wall
el.physicsBody?.collisionBitMask = Constants.Config.PhysicsCategory.Player
el.physicsBody?.contactTestBitMask = Constants.Config.PhysicsCategory.Player
最后我只是在球 physicsBody 上调用 applyImpulse 函数,让它在物理模拟中移动。
还请检查我附加的第二张图片/gif。它显示了一个简单的 skphysics 应用程序的边缘碰撞问题,没有任何特殊的参数化。只是一个带有球的矩形和一个作为脉冲应用的向量。
这是我使用 appzYourLife 解决方案的完整非工作代码。
class GameScene: SKScene {
private var ball:SKShapeNode!
override func didMoveToView(view: SKView) {
let screen = UIScreen.mainScreen().bounds
let p = UIBezierPath()
p.moveToPoint(CGPointMake(0,0))
p.addLineToPoint(CGPointMake(screen.width,0))
p.addLineToPoint(CGPointMake(screen.width, screen.height))
p.addLineToPoint(CGPointMake(0,screen.height))
p.closePath()
let shape = SKShapeNode(path: p.CGPath)
shape.physicsBody = SKPhysicsBody(edgeLoopFromPath: p.CGPath)
shape.physicsBody?.affectedByGravity = false
shape.physicsBody?.dynamic = false
shape.strokeColor = UIColor.blackColor()
self.addChild(shape)
ball = SKShapeNode(circleOfRadius: 17)
ball.name = "player"
ball.position = CGPoint(x: 20, y: 20)
ball.fillColor = UIColor.yellowColor()
ball.physicsBody = SKPhysicsBody(circleOfRadius: 17)
ball.physicsBody?.angularDamping = 0
ball.physicsBody?.linearDamping = 0
ball.physicsBody?.restitution = 1
ball.physicsBody?.friction = 0
ball.physicsBody?.allowsRotation = false
self.addChild(ball)
self.ball.physicsBody?.applyImpulse(CGVector(dx: 2.4, dy: 9.7))
}
我刚刚意识到我的球精灵的质量和密度为零。为什么?即使设置它也保持为零。
【问题讨论】:
-
你能提供任何代码吗?
-
只是添加了一些代码,添加所有代码会太多,所有其他部分都是我的游戏和关卡层处理(作为 SKNode 的),我将元素放在其中,最后放在 GameScene 上。
-
我想知道是否没有对矩形墙的外侧进行碰撞,因为墙是体积矩形。也许使用
bodyWithEdgeLoopFromRect而不是rectangleOfSize? -
Ok 将墙壁的 rectangleOfSize 更改为 edgeLoopFromRect。球的行为仍然相同。这不应该影响计算方式,因为这两种类型都是碰撞应该使用的实体。
标签: ios swift sprite-kit physics