簡體   English   中英

在Swift中無法正確檢測碰撞

[英]Not detecting Collisions properly in Swift

我正在制作一個從屏幕頂部生成多維數據集的游戲,當觸摸它們時它們就會消失。 我將對象位置設置為用戶觸摸的點。 它運行功能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

您的碰撞類別是錯誤的。 應該是因為您正在處理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

如果您已經可以調用contact方法,則現在應該可以使用。 讓我知道事情的后續。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM