ios - 未调用 Swift func didBeginContact

标签 ios swift game-physics

当物体在两个事物之间通过时,我试图增加我的分数 但是我的函数 didBeginContact 没有被调用我试图添加一个断点但是调试但它仍然没有被调用。

游戏场景代码

import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {

    let birdGroup: UInt32 = 0x1 << 0
    let enemeyObjectsGroup: UInt32 = 0x1 << 1
    let openingGroup: UInt32 = 0x1 << 2

    enum objectsZPositions: CGFloat {

        case backgorund = 0
        case ground = 1
        case pipes = 2
        case bird = 3
        case score = 4
        case gameOver = 5
    }
    var movingGameObjects = SKNode()
    var backgorund = SKSpriteNode()
    var bird = SKSpriteNode()
    var pipeSpeed: NSTimeInterval = 10  // pipe speed
    var pipeSpawned: Int = 0
    var gameOver: Bool = false
    var scoreLabelNode = SKLabelNode()
    var score: Int = 0

    var gameOverLabelNode = SKLabelNode()
    var gameOverStatusNode = SKLabelNode()

    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        /*
        let myLabel = SKLabelNode(fontNamed:"Chalkduster")
        myLabel.text = "Hello, World!";
        myLabel.fontSize = 45;
        myLabel.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame));

        self.addChild(myLabel)
        */
        self.addChild(movingGameObjects)

        // Creating Background
        createBackgorund()
        // Physics

        self.physicsWorld.contactDelegate = self
        self.physicsWorld.gravity = CGVectorMake(0,  -12) // gravity of the bird

         // Adding the bird

         let birdTexture1 = SKTexture(imageNamed: "bird1.png")
         let birdTexture2 = SKTexture(imageNamed: "bird2.png")
         let birdTexture3 = SKTexture(imageNamed: "bird3.png")
         let birdTexture4 = SKTexture(imageNamed: "bird4.png")
         let birdTexture5 = SKTexture(imageNamed: "bird5.png")
         let birdTexture6 = SKTexture(imageNamed: "bird6.png")
         let birdTexture7 = SKTexture(imageNamed: "bird7.png")
         let birdTexture8 = SKTexture(imageNamed: "bird8.png")

        let flyAnimation = SKAction.animateWithTextures([birdTexture1,birdTexture2,birdTexture3,birdTexture4,birdTexture5,birdTexture6,birdTexture7,birdTexture8], timePerFrame: 0.1)

        let flyForever = SKAction.repeatActionForever(flyAnimation)

        bird = SKSpriteNode(texture: birdTexture1)

        bird.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        bird.zPosition = objectsZPositions.bird.rawValue
        bird.runAction(flyForever, withKey: "birdFly")

        bird.physicsBody = SKPhysicsBody(circleOfRadius: bird.size.height/2)
        bird.physicsBody?.categoryBitMask = birdGroup
        bird.physicsBody?.categoryBitMask = openingGroup | enemeyObjectsGroup
        bird.physicsBody?.collisionBitMask = enemeyObjectsGroup
        bird.physicsBody?.allowsRotation = false

        self.addChild(bird)

        // Adding ground
        let ground = SKNode()
        ground.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.width, 1))
        ground.physicsBody?.dynamic = false // dynamic property we dont want the ground to be affected by the gravity
        ground.position = CGPoint(x: CGRectGetMidY(self.frame), y: 0) // ground on the border fo the screen
        ground.zPosition = objectsZPositions.ground.rawValue
        ground.physicsBody?.categoryBitMask = enemeyObjectsGroup
        ground.physicsBody?.collisionBitMask = birdGroup
        ground.physicsBody?.contactTestBitMask = birdGroup

        self.addChild(ground)

       let pipesTimer = NSTimer.scheduledTimerWithTimeInterval(2.5, target: self, selector: "loadPipes", userInfo: nil, repeats: true)

        // Score Label Node

        scoreLabelNode = SKLabelNode(fontNamed: "ChalkboardSE-Bold")
        scoreLabelNode.fontSize = 50
        scoreLabelNode.fontColor = SKColor.whiteColor()
        scoreLabelNode.position = CGPoint(x: CGRectGetMidX(self.frame), y: self.frame.height - 50) // position of the Score Label
        scoreLabelNode.text = "0"
        scoreLabelNode.zPosition = objectsZPositions.score.rawValue
        self.addChild(scoreLabelNode)
    }

    func didBeginContact(contact: SKPhysicsContact) {
        if contact.bodyA.categoryBitMask == openingGroup || contact.bodyB.categoryBitMask == openingGroup {
            score += 1
            scoreLabelNode.text = "\(score)"
            }
    }

    func loadPipes() {

        pipeSpawned += 2

        if pipeSpawned % 10 == 0 {
            pipeSpeed -= 0.5  // making the game thougher
        }

        let gap: CGFloat = bird.size.height * 2.1 // the gap between 2 pipes
        let pipe1Texture = SKTexture(imageNamed: "pipe1.png")
        let pipe2Texture = SKTexture(imageNamed: "pipe2.png")

        let pipe1 = SKSpriteNode(texture: pipe1Texture)
        let pipe2 = SKSpriteNode(texture: pipe2Texture)

        let randomY: CGFloat = CGFloat(arc4random_uniform(UInt32(self.frame.height * 0.7)))
        pipe1.position = CGPoint(x: self.frame.width + pipe1.size.width, y: pipe1.size.height/2 + 170 + randomY + gap/2)

        pipe1.physicsBody = SKPhysicsBody(rectangleOfSize: pipe1.size)
        pipe1.physicsBody?.dynamic = false
        pipe1.physicsBody?.categoryBitMask = enemeyObjectsGroup
        pipe1.physicsBody?.collisionBitMask = birdGroup
        pipe1.physicsBody?.contactTestBitMask = birdGroup

        pipe1.zPosition = objectsZPositions.pipes.rawValue
        movingGameObjects.addChild(pipe1)

       let movePipe = SKAction.moveToX(-pipe1.size.width, duration: pipeSpeed)
        let removePipe = SKAction.removeFromParent()
        pipe1.runAction(SKAction.sequence([movePipe,removePipe]))


        pipe2.position = CGPoint(x: self.frame.width + pipe2.size.width, y: -pipe2.size.height/2 + 100  + randomY - gap/2)
        pipe2.physicsBody = SKPhysicsBody(rectangleOfSize: pipe2.size)
        pipe2.physicsBody?.dynamic = false
        pipe2.physicsBody?.categoryBitMask = enemeyObjectsGroup
        pipe2.physicsBody?.collisionBitMask = birdGroup
        pipe2.physicsBody?.contactTestBitMask = birdGroup
        pipe2.zPosition = objectsZPositions.pipes.rawValue
        movingGameObjects.addChild(pipe2)

        pipe2.runAction(SKAction.sequence([movePipe,removePipe]))

        // crossing between pipes

        let crossing = SKNode()
        crossing.position = CGPoint(x: pipe1.position.x + pipe1.size.width/2, y: CGRectGetMidY(self.frame))
        crossing.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(1, self.frame.height))
        crossing.physicsBody?.dynamic = false
        crossing.physicsBody?.categoryBitMask = openingGroup
        crossing.physicsBody?.contactTestBitMask = birdGroup
        movingGameObjects.addChild(crossing)
        crossing.runAction(SKAction.sequence([movePipe, removePipe]))
    }

    func createBackgorund() {

        let backgorundTexture = SKTexture(imageNamed: "background")
        let moveBakground = SKAction.moveByX(-backgorundTexture.size().width, y: 0, duration: 25) // background speed
        let replaceBackground = SKAction.moveByX(backgorundTexture.size().width, y: 0, duration: 0)
        let backgorundSequence = SKAction.sequence([moveBakground, replaceBackground])
        let moveBackgroundForever = SKAction.repeatActionForever(backgorundSequence)

        for var i: CGFloat = 0; i < 2; i++ {
            backgorund = SKSpriteNode(texture: backgorundTexture)
            backgorund.position = CGPoint(x: backgorundTexture.size().width/2 + i * backgorundTexture.size().width, y:CGRectGetMidY(self.frame))
            backgorund.size.height = self.frame.height
            backgorund.zPosition = objectsZPositions.backgorund.rawValue
            backgorund.runAction(moveBackgroundForever)
            movingGameObjects.addChild(backgorund)
        }
    }

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

        if gameOver == false {
            bird.physicsBody?.velocity = CGVectorMake(0, 0)
            bird.physicsBody?.applyImpulse(CGVectorMake(0, 60))


            // making the bird face up and down when tapped

            let rotateUp = SKAction.rotateToAngle(0.3, duration: 0)
            bird.runAction(rotateUp)

        } else {

            if let scene = GameScene(fileNamed:"GameScene") {
                // Configure the view.
                let skView = self.view as SKView!
                skView.showsFPS = true
                skView.showsNodeCount = true
                skView.showsPhysics = false

                /* Sprite Kit applies additional optimizations to improve rendering performance */
                skView.ignoresSiblingOrder = true

                /* Set the scale mode to scale to fit the window */
                scene.scaleMode = .AspectFill

                skView.presentScene(scene)
            }
        }
           }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if gameOver == false {

            let rotateDown = SKAction.rotateToAngle(-0.2, duration: 0)
            bird.runAction(rotateDown)
        }
    }

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
    }
}

最佳答案

你在这一行中有一个错误:

bird.physicsBody?.categoryBitMask = openingGroup | enemeyObjectsGroup

应该是这样的:

bird.physicsBody?.categoryBitMask = birdGroup

也尝试像这样使用 didBeginContact:

- (void)didBeginContact:(SKPhysicsContact *)contact
{
    SKPhysicsBody *firstBody, *secondBody;

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

   //Handle contacts here
}

How you can handle contacts 已经在这里评论了很多次,所以我将跳过那个:

https://stackoverflow.com/a/20604762/3402095

https://stackoverflow.com/a/26723392/3402095

提示:

请注意,不会检测到两个静态物体之间的接触 (node.physicsBody.dynamic = false)。我不确定您对哪些接触感兴趣(可能在鸟和交叉/管道之间),但即使您当前的设置很好(鸟是动态的,交叉和管道是静态的),您也应该意识到这一点。

关于ios - 未调用 Swift func didBeginContact,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32240121/

相关文章:

ios - UIAlertController 状态栏没有变暗和色调问题

swift - 无法将 Xcode7 中类型 'String' 的值分配给类型 'String' 的值

c# - ML-Agents 代理未重置?

ios - 为什么关闭 UIAlertController 会调用 UINavigationController 上的关闭?

javascript - 与 Phaser Arcade 物理引擎的碰撞

javascript - AABB 碰撞解决滑边

ios - Xcode NSManagedObject 子类在标记为非可选时包含可选

ios - 我的View是透明的,如何让组件不透明

ios - 由于 ios 中未捕获的异常 'NSUnknownKeyException' 而终止应用程序

iOS:在扩展中从 NSNotificationCenter 返回值(swift)