在Swift中没有正确检测到碰撞

时间:2016-03-30 11:15:34

标签: ios swift sprite-kit

我制作的游戏会从屏幕顶部生成多维数据集,当它们被触摸时会消失。我将对象位置设置为用户触摸的点。它运行函数DidBeginContact,但它似乎没有检测到我的两个视图:

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

        print("didbegincontact")
        if ((firstBody.categoryBitMask == PhysicsCategory.RedSquare) && (secondBody.categoryBitMask == PhysicsCategory.touchlocation)) || ((firstBody.categoryBitMask == PhysicsCategory.touchlocation) && (secondBody.categoryBitMask == PhysicsCategory.RedSquare)) {
            collisionwithredsquare(firstBody.node as! SKSpriteNode)
            print("Done")

        }
    }

它的印刷" didBegincontact"所以我知道函数正在运行,但if语句不是。

以下是所有代码:

import SpriteKit

struct PhysicsCategory {
    static let RedSquare : UInt32 = 1
    static let touchlocation : UInt32 = 2
    static let BlueSquare : UInt32 = 3
}

class GameScene: SKScene, SKPhysicsContactDelegate {

     var animator : UIDynamicAnimator?
     let blueSquare = SKSpriteNode()
     let redSquare = SKSpriteNode()
    var scorenumber = 0
    var ground = SKSpriteNode()
    var touchpoint = SKSpriteNode()

    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        physicsWorld.contactDelegate = self
        physicsWorld.gravity = CGVector(dx: 1.0, dy: -9.0)


       /* let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
        // 2. Set the friction of that physicsBody to 0
        borderBody.friction = 0
        // 3. Set physicsBody of scene to borderBody
        self.physicsBody = borderBody */


        touchpoint = SKSpriteNode(imageNamed:"Spaceship")
        touchpoint.physicsBody?.categoryBitMask = PhysicsCategory.touchlocation
        touchpoint.physicsBody?.contactTestBitMask = PhysicsCategory.RedSquare
        touchpoint.physicsBody?.affectedByGravity = false

        touchpoint.xScale = 0.5
        touchpoint.yScale = 0.5


       self.addChild(touchpoint)

        let width = UInt32(self.frame.size.width)

        let X = arc4random() % width


        ground = SKSpriteNode(imageNamed: "Ground")
        ground.setScale(1.0)
        ground.position = CGPoint(x: self.frame.width / 2, y: 5)
        ground.physicsBody = SKPhysicsBody(rectangleOfSize: ground.size)
        ground.physicsBody?.affectedByGravity = false
        ground.physicsBody?.dynamic = false

        ground.zPosition = 3

        self.addChild(ground)


        //INizialize
        animator = UIDynamicAnimator(referenceView: self.view!)

        //Add Gravity

        //animator?.addBehavior(gravity, sprite)


        var test = arc4random() % 90

        blueSquare.size = CGSize(width: 100, height: 100)
        blueSquare.position = CGPoint(x: CGFloat(X), y: 1000)
                blueSquare.zRotation = 34
        blueSquare.name = "bluecube"
        blueSquare.physicsBody = SKPhysicsBody(circleOfRadius: 20)
        blueSquare.physicsBody?.affectedByGravity = true
        blueSquare.physicsBody?.dynamic = false
        blueSquare.color = SKColor.blueColor()
       // BlueSquare.physicsBody?.velocity = CGVectorMake(0, 0)

        //BlueSquare.physicsBody?.applyImpulse(CGVectorMake(0, -90))
        self.addChild(blueSquare)

        let X2 = arc4random() % width
        redSquare.size = CGSize(width: 100, height: 100)
        redSquare.position = CGPoint(x: CGFloat(X2), y: 1000)
        redSquare.name = "redcube"
        redSquare.physicsBody = SKPhysicsBody(circleOfRadius: 20)
        redSquare.physicsBody?.affectedByGravity = true
        redSquare.physicsBody?.dynamic = true
        redSquare.hidden = false
        redSquare.physicsBody?.categoryBitMask = PhysicsCategory.RedSquare
        redSquare.physicsBody?.contactTestBitMask = PhysicsCategory.touchlocation

        redSquare.color = SKColor.redColor()

        self.addChild(redSquare)




        let timerAction1 = SKAction.waitForDuration(0.5)
        let timerAction2 = SKAction.runBlock(spawning1)
        let timerSequence = SKAction.sequence([timerAction1, timerAction2])
        runAction(SKAction.repeatActionForever(timerSequence))

    }

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

        print("didbegincontact")
        if ((firstBody.categoryBitMask == PhysicsCategory.RedSquare) && (secondBody.categoryBitMask == PhysicsCategory.touchlocation)) || ((firstBody.categoryBitMask == PhysicsCategory.touchlocation) && (secondBody.categoryBitMask == PhysicsCategory.RedSquare)) {
            collisionwithredsquare(firstBody.node as! SKSpriteNode)
            print("Done")

        }
    }


    func collisionwithredsquare(redsquare: SKSpriteNode) {
        print("Hello")
    }


    func spawning1() {


    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
       /* Called when a touch begins */

        for touch in touches {
            let location = touch.locationInNode(self)

            touchpoint.position = location

        }
    }

    func score () {
        scorenumber++
        print(scorenumber)
    }

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
       if CGRectIntersectsRect(redSquare.frame, ground.frame) {
        redSquare.position = CGPoint(x: redSquare.position.x, y: redSquare.position.y + 10)
        }
    }
}

提前致谢,Niall

1 个答案:

答案 0 :(得分:1)

您的碰撞类别是错误的。这应该是因为你正在处理32位整数。

  struct PhysicsCategory {
      static let RedSquare: UInt32 = 0x1 << 1
      static let touchlocation : UInt32 = 0x1 << 2
      static let BlueSquare : UInt32 = 0x1 << 3
  }

如果按照自己的方式使用,就必须像这样写

  struct PhysicsCategory {
      static let RedSquare: UInt32 = 1
      static let touchlocation : UInt32 = 2
      static let BlueSquare : UInt32 = 4
      static let somethingElse : UInt32 = 8
  }

这更令人困惑,因为你不能只将最后一个数字增加1.

将碰撞代码更改为此。这样你就不必在if语句中检查这两个实体。

    /// Did Begin Contact
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.RedSquare) && (secondBody.categoryBitMask == PhysicsCategory.touchlocation) {
        collisionwithredsquare(firstBody.node) // I aim pretty sure you dont need to cast as SKSpriteNod, because the body its already a SKNode.
        print("Done")

    }
  }

同样在touchLocaiton精灵上你忘了给它一个物理身体。

  touchpoint.pysicsBody = SKPhysicsBody(..) // FORGOT THIS LINE
  touchpoint.physicsBody?.categoryBitMask = PhysicsCategory.touchlocation
    touchpoint.physicsBody?.contactTestBitMask = PhysicsCategory.RedSquare
    touchpoint.physicsBody?.affectedByGravity = false

如果您已经获得要调用的联系方法,现在应该可以使用。让我知道它是怎么回事。