SpriteKit SKShapeNode 在重力碰撞时过早停止

SpriteKit SKShapeNode stops prematurely when colliding due to gravity

这是设置

    // Create a scene
    scene = SKScene(size: self.view.frame.size)

    let sceneHeight = scene.frame.height
    let sceneWidth = scene.frame.width

    // Create nodes
    // Rectangle
    let shapeWidth: CGFloat = 100
    let shapeHeight = shapeWidth
    let shapeNode = SKShapeNode(rect: CGRectMake(0, 0, shapeWidth, 100))
    shapeNode.position = CGPoint(x: sceneWidth/2 - shapeWidth/2, y: 300)
    shapeNode.fillColor = UIColor.redColor()
    shapeNode.strokeColor = UIColor.redColor()

    // Floor
    let floorWidth: CGFloat = sceneWidth
    let floorHeight: CGFloat = 10
    let floorNode = SKShapeNode(rect: CGRectMake(0, 0, floorWidth, floorHeight))
    floorNode.position = CGPoint(x: 0, y: 100)
    floorNode.fillColor = UIColor.greenColor()
    floorNode.strokeColor = UIColor.greenColor()

    // Create the node tree
    scene.addChild(floorNode)
    scene.addChild(shapeNode)

然后我定义两个物理体并将其添加到我的两个节点。

    // Create physics
    let shapePhysicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: shapeWidth, height: shapeHeight))
    shapePhysicsBody.dynamic = true
    shapePhysicsBody.categoryBitMask = PhysicsCategory.Shape
    shapePhysicsBody.contactTestBitMask = PhysicsCategory.Floor
    shapePhysicsBody.collisionBitMask = PhysicsCategory.None
    shapePhysicsBody.usesPreciseCollisionDetection = true

    let floorPhysicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: floorWidth, height: floorHeight))
    floorPhysicsBody.dynamic = true
    floorPhysicsBody.categoryBitMask = PhysicsCategory.Floor
    floorPhysicsBody.contactTestBitMask = PhysicsCategory.Shape
    floorPhysicsBody.collisionBitMask = PhysicsCategory.None
    floorPhysicsBody.usesPreciseCollisionDetection = true
    floorPhysicsBody.affectedByGravity = false

    // Add physics
    shapeNode.physicsBody = shapePhysicsBody
    floorNode.physicsBody = floorPhysicsBody
    scene.physicsWorld.gravity = CGVector(dx: 0, dy: -1)
    scene.physicsWorld.contactDelegate = self

这种工作方式,即矩形确实从其初始位置落下,并且在发生碰撞时调用碰撞委托。

我的didBeginContact:方法的内容。

func didBeginContact(contact: SKPhysicsContact) {
    var firstBody   : SKPhysicsBody
    var secondBody  : SKPhysicsBody

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody   = contact.bodyA
        secondBody  = contact.bodyB
    } else {
        firstBody   = contact.bodyB
        secondBody  = contact.bodyA
    }

    if ((firstBody.categoryBitMask & PhysicsCategory.Floor != 0) && (secondBody.categoryBitMask & PhysicsCategory.Shape != 0)) {
        secondBody.dynamic = false
        println("collision")
    }
}

但是形状节点在视觉接触之前就停止了。我希望这些图片能给人留下印象。

从这里开始

这是联系发生的地方

为什么他们之间会有这样的差距?我错过了什么?我希望它们在矩形停止移动之前在视觉上相互接触。

SKShapeNode(rect:)SKShapeNodenode.position 绘制为 origin。对于SKPhysicsBodyposition对应于centerrectangle。这会在物理体和实际节点之间创建一个偏移量。你可以看到,如果你启用

scene.view?.showsPhysics = true.

您可以使用以下代码创建 SKShapeNode 来更正偏移量。

let shapeNode = SKShapeNode(rect: CGRectMake(-shapeWidth/2, -50, shapeWidth, 100))
// Other code
let floorNode = SKShapeNode(rect: CGRectMake(-floorWidth/2, -floorHeight/2, floorWidth, floorHeight))