简体   繁体   中英

How may i detect contact and collision correctly? Swift iOS SKScene

The problem is i can't detect the collision //or contact in any way i have found on the internet

This is my code:

The declaration of my masks:

private let ballCategory : UInt32 = 0x1 << 0
private let holeCategory : UInt32 = 0x1 << 1

The adding of both the hole and the ball:

func addHole(#size : CGSize) {

    let actionMoveDown = SKAction.moveToY(CGRectGetMidY(self.frame)-500, duration: 4.7)
    let hole = shapedHoles()
    let UT = UTIL()
    var position:CGFloat


    let randomPosition = UT.randomNumberWith(Min: 1, Max: 3)

    switch randomPosition{
    case 1:
        position = CGRectGetMidX(self.frame)
    case 2:
        position = CGRectGetMidX(self.frame)+size.width

    default:
        position = CGRectGetMidX(self.frame)-(size.width)

    }



    var createdHole = hole.createHoleAtPosition(position: CGPointMake(position ,CGRectGetMaxY(self.frame) + (size.height/2)),size: size )//CGSizeMake(CGRectGetMaxX(self.frame)/3 - 10, 70)

    createdHole.physicsBody = SKPhysicsBody(rectangleOfSize: createdHole.frame.size)
    createdHole.physicsBody?.categoryBitMask = holeCategory
    createdHole.physicsBody?.collisionBitMask = 0
    createdHole.physicsBody?.contactTestBitMask = ballCategory
    createdHole.physicsBody?.affectedByGravity = false
    createdHole.physicsBody?.dynamic = false


    lastHolePosition = randomPosition

    createdHole .runAction(actionMoveDown)

    self.addChild(createdHole)



}

func addSphere(){
    let mainCharacterController = circle()
    let character: (SKNode) = mainCharacterController.createCircleAtPosition(position: CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame)+100))


    character.physicsBody = SKPhysicsBody(circleOfRadius: character.frame.size.height/2)
    character.physicsBody?.categoryBitMask = ballCategory
    character.physicsBody?.collisionBitMask = 0
    character.physicsBody?.contactTestBitMask = holeCategory
    character.physicsBody?.affectedByGravity = false
    character.physicsBody?.dynamic = false


    self.addChild(character)


}    func addHole(#size : CGSize) {

    let actionMoveDown = SKAction.moveToY(CGRectGetMidY(self.frame)-500, duration: 4.7)
    let hole = shapedHoles()
    let UT = UTIL()
    var position:CGFloat


    let randomPosition = UT.randomNumberWith(Min: 1, Max: 3)

    switch randomPosition{
    case 1:
        position = CGRectGetMidX(self.frame)
    case 2:
        position = CGRectGetMidX(self.frame)+size.width

    default:
        position = CGRectGetMidX(self.frame)-(size.width)

    }



    var createdHole = hole.createHoleAtPosition(position: CGPointMake(position ,CGRectGetMaxY(self.frame) + (size.height/2)),size: size )//CGSizeMake(CGRectGetMaxX(self.frame)/3 - 10, 70)

    createdHole.physicsBody = SKPhysicsBody(rectangleOfSize: createdHole.frame.size)
    createdHole.physicsBody?.categoryBitMask = holeCategory
    createdHole.physicsBody?.collisionBitMask = 0
    createdHole.physicsBody?.contactTestBitMask = ballCategory
    createdHole.physicsBody?.affectedByGravity = false
    createdHole.physicsBody?.dynamic = false


    lastHolePosition = randomPosition

    createdHole .runAction(actionMoveDown)

    self.addChild(createdHole)



}

func addSphere(){
    let mainCharacterController = circle()
    let character: (SKNode) = mainCharacterController.createCircleAtPosition(position: CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame)+100))


    character.physicsBody = SKPhysicsBody(circleOfRadius: character.frame.size.height/2)
    character.physicsBody?.categoryBitMask = ballCategory
    character.physicsBody?.collisionBitMask = 0
    character.physicsBody?.contactTestBitMask = holeCategory
    character.physicsBody?.affectedByGravity = false
    character.physicsBody?.dynamic = false


    self.addChild(character)


}

And last but not least the didBeginContactMethod

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 & holeCategory) != 0 &&
        (secondBody.categoryBitMask & ballCategory) != 0 {
        println("HO")
    }
}

Thank you and hope you know what is happening, and if you need any extra code just comment it

You have to make sure that the SKScene subclass you are using also implements the SKPhysicsContactDelegate protocol. For example, it would look like this.

class MyScene : SKScene, SKPhysicsContactDelegate

Then you have to set your physics worlds contact delegate to yourself.

override init() {
    self.physicsWorld.contactDelegate = self;
}

Tell me how this works out, but it should solve the problem and successfully allow you to listen in on collisions.

There is a couple things it might be. First you can try using an enum for the contact categories.

enum collisionBodies:UInt32 {
    case ballCategory = 1
    case holeCategory = 2
}

func Collisions() {
   character.physicsBody.categoryBitMask = collisionBodies.ballCategory.rawValue
   character.physicsBody.contactTestBitMask = collisionBodies.holeCategory.rawValue
   character.physicsBody.collisionBitMask = 0

   createdHole.physicsBody.categoryBitMask = collisionBodies.holeCategory.rawValue
   createdHole.physicsBody.contactTestBitMask = collisionBodies.ballCategory.rawValue
   createdHole.physicsBody.collisionBitMask = 0
}

Also try setting one of your physics bodies to dynamic = true or collisions will likely not work.

A better way to test for collisions in the didBeginContact function is to use a switch statement.

func didBeginContact(contact: SKPhysicsContact) {
   let categoryMask = contact.BodyA.categoryBitMask | contact.BodyB.categoryBitMask

   switch (categoryMask) {
   case collisionBodies.holeCategory.rawValue | collisionBodies.ballCategory.rawValue:
        //code to run when contact is detected
   default:
     return
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM