【问题标题】:Collision tests not working in SpriteKit Swift 2碰撞测试在 SpriteKit Swift 2 中不起作用
【发布时间】:2016-10-22 21:38:46
【问题描述】:

我一直在试图弄清楚为什么我的 didBeginContact 方法不起作用。我有一个三角形从屏幕顶部落到底部,底部有一条线,如果它与它发生碰撞。我的分数应该增加。 这是负责此操作的代码。

func createScene(){

    physicsWorld.contactDelegate = self

    slider = SKSpriteNode(imageNamed: "Slider")
    slider.setScale(0.20)
    slider.position = CGPoint(x: self.frame.width / 2, y: 0 + slider.frame.height / 2)


    slider.physicsBody = SKPhysicsBody(rectangleOfSize: slider.size)
    slider.physicsBody?.categoryBitMask = PhysicsCatergory.slider
    slider.physicsBody?.collisionBitMask = PhysicsCatergory.coin | PhysicsCatergory.greenTriangle | PhysicsCatergory.orangeHexagon | PhysicsCatergory.purpleOctagon | PhysicsCatergory.redSquare
    slider.physicsBody?.contactTestBitMask = PhysicsCatergory.coin | PhysicsCatergory.greenTriangle | PhysicsCatergory.orangeHexagon | PhysicsCatergory.purpleOctagon | PhysicsCatergory.redSquare
    slider.physicsBody?.affectedByGravity = false
    slider.physicsBody?.dynamic = false

    var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("SpawnShapes"), userInfo: nil, repeats: true)
    self.addChild(slider)


}

func didBeginContact(contact: SKPhysicsContact) {
    let firstBody = contact.bodyA
    let secondBody = contact.bodyB

    if firstBody.categoryBitMask == PhysicsCatergory.greenTriangle && secondBody.categoryBitMask == PhysicsCatergory.Score{
        score++
        print(score)

    }
    else if firstBody.categoryBitMask == PhysicsCatergory.Score && secondBody.categoryBitMask == PhysicsCatergory.greenTriangle{
        score++
        print(score)
    }



}

override func didMoveToView(view: SKView) {

        createScene()
    invisibleBounderies()


}

func invisibleBounderies(){

    let scoreNode = SKSpriteNode()
    scoreNode.size = CGSize(width: 5, height: 600)
    scoreNode.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 10)
    scoreNode.physicsBody = SKPhysicsBody(rectangleOfSize: scoreNode.size)
    scoreNode.physicsBody?.affectedByGravity = false
    scoreNode.physicsBody?.dynamic = false
    scoreNode.physicsBody?.categoryBitMask = PhysicsCatergory.Score
    scoreNode.physicsBody?.collisionBitMask = PhysicsCatergory.greenTriangle
    scoreNode.physicsBody?.contactTestBitMask = PhysicsCatergory.greenTriangle
    scoreNode.zRotation = CGFloat(M_PI/2.0)
    scoreNode.color = SKColor.blueColor()


    self.addChild(scoreNode)



}



func SpawnShapes(){

    greenTriangle = SKSpriteNode(imageNamed:"greenTriangle")
    purpleOctagon = SKSpriteNode(imageNamed: "purpleOctagon")
    redSquare = SKSpriteNode(imageNamed: "redSquare")
    coin = SKSpriteNode(imageNamed: "coin")

    greenTriangle.physicsBody = SKPhysicsBody(rectangleOfSize: greenTriangle.size)
    greenTriangle.physicsBody?.categoryBitMask = 0
    greenTriangle.physicsBody?.collisionBitMask = PhysicsCatergory.Score
    greenTriangle.physicsBody?.contactTestBitMask = PhysicsCatergory.Score
    greenTriangle.physicsBody?.affectedByGravity = false
    greenTriangle.physicsBody?.dynamic = false

    var MinValue = self.size.width / 8
    var MaxValue = self.size.width - 150
    var SpawnPoint = UInt32(MaxValue - MinValue)

    let action = SKAction.moveToY(-30, duration: 2.0)


    slider.zPosition = 1
    coin.zPosition = 2
    greenTriangle.zPosition = 3
    orangeHexagon.zPosition = 4
    purpleOctagon.zPosition = 5
    redSquare.zPosition = 6



    greenTriangle.position = CGPoint(x: CGFloat(arc4random_uniform(SpawnPoint)), y: self.size.height)
    self.addChild(greenTriangle)
    greenTriangle.runAction(SKAction.repeatActionForever(action))



}

【问题讨论】:

    标签: sprite-kit swift2 collision-detection


    【解决方案1】:
    • 您只需将greenTriangle dynamic 属性设置为true
    • 你设置了greenTriangle.physicsBody?.categoryBitMask = 0,这就是你没有检测到接触的原因。 greenTriangle.physicsBody?.categoryBitMask = PhysicsCatergory.greenTriangle 可能会成功。

    如果您在进行这些更改后仍未检测到联系人,请检查您的 physicsCatergory 是否正常。如果您愿意,最好实现 UInt32 类型的 enum,其中值都是单个位,或者像这样:

    enum PhysicsCatergory : UInt32{
        case slider = 1
        case coin = 2
        case greenTriangle = 4
        case purpleOctagon = 8
        case redSquare = 16
        case orangeHexagon = 32
        case Score = 64
    }
    

    这样做需要在对这些枚举之一的每个引用中添加.rawValue。示例:greenTriangle.physicsBody?.categoryBitMask = PhysicsCatergory.greenTriangle.rawValue

    我知道这与问题无关,但我建议您不要在这种情况下使用 SKAction 进行移动,因为它会忽略物理碰撞,因为您正在“强制”它的位置。请改用physicsBody.velocity 属性来让物理工作。您会注意到,当使用后者时,该块将与得分线发生碰撞,因为您还设置了它的collisionBitMask。这样你就可以正确控制它的碰撞。如果不希望方块在行进时失去速度(空气摩擦),请将physicsBody.linearDamping 设置为零。

    【讨论】:

    • 感谢您的回答,我的意思是将categoryBitMask 分配给它的PhysicsCatergory,但我犯了一个我无意的错误。我是游戏开发的新手,所以我不太了解,谢谢您提供的额外提示,我会将您建议的更改添加到程序中:) @Pietro Pepe
    • 对于我这样做的对象struct PhysicsCatergory { static let slider : UInt32 = 0x1 << 1 static let coin : UInt32 = 0x1 << 2 static let greenTriangle : UInt32 = 0x1 << 3 static let orangeHexagon : UInt32 = 0x1 << 4 static let purpleOctagon : UInt32 = 0x1 << 5 static let redSquare : UInt32 = 0x1 << 6 static let Wall : UInt32 = 0x1 << 7 static let Score : UInt32 = 0x1 << 8 }
    • 不客气,如果您遇到任何其他问题,请随时与我联系。你实现的这个结构没问题。祝你好运!
    • 谢谢,我会告诉你非常感谢@Pietro Pepe
    【解决方案2】:

    具有dynamic 属性false 的physicsBody 不能参与碰撞;将dynamic 设置为 true.

    【讨论】:

    • 所有与碰撞有关的事情?
    • 我确实将greenTrianglescoreNode 的动态属性更改为true,并且分数没有增加。当 greenTriangle 击中 scoreNode 线时,它会滞后于它。
    • @SteveIves,非动态项目可以对它们进行物理测试,它们只是不能调用物理调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多