spritekit中的接触/冲突问题

时间:2015-06-08 02:46:22

标签: ios swift sprite-kit

我正在开发一个联系人扮演重要角色的应用程序。我是我的游戏,“鞋子”在地上休息。我需要能够知道鞋子何时在地面上,所以它不会多跳。我还需要知道什么时候鞋子遇到了障碍,所以比赛将结束。我的问题是,它认为地面是实际障碍的障碍。

    import SpriteKit

类GameScene:SKScene,SKPhysicsContactDelegate {

var shoeGround = SKSpriteNode()
var hurdleTexture = SKTexture()
var hurdlesMoveAndRemove = SKAction()
var hurdlesStopAndRemove = SKAction()
var jump = false

//collision bitmask
let shoeGroundCategory:UInt32 = 0x1 << 0
let hurdleCategory:UInt32 = 0x1 << 28
let groundSensorCategory: UInt32 = 0x1 << 3

override func didMoveToView(view: SKView) {

    //Physics
    self.physicsWorld.gravity = CGVectorMake(0.0, -8.0)
    self.physicsWorld.contactDelegate = self


    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    //ground

    var groundTexture = SKTexture(imageNamed:"ground")
    var sprite = SKSpriteNode(texture: groundTexture)

    //scale it
    sprite.setScale(2.1)

    //position it
    sprite.position = CGPointMake(self.size.width / 2, sprite.size.height / 2)

    //add it to the scene
    self.addChild(sprite)
    //ground variable for the node
    var ground = SKSpriteNode()

    //set the position of the node
    ground.position = CGPointMake(0, groundTexture.size().height)
    ground.zPosition = 1000

    //set the physics body to equal the size of the image.
    ground.physicsBody = SKPhysicsBody(rectangleOfSize:CGSizeMake(self.frame.size.width, groundTexture.size().height * 1.85))

    //physics bodies
    ground.physicsBody?.dynamic = false
    ground.physicsBody?.restitution = CGFloat(0.0)

    //add the object to the scene
    self.addChild(ground)


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    //ground

    var groundSensorTexture = SKTexture(imageNamed:"ground")
    var spriteSensor = SKSpriteNode(texture: groundSensorTexture)
    //scale it
    spriteSensor.setScale(2.1)
    //position it
    spriteSensor.position = CGPointMake(self.size.width / 2, spriteSensor.size.height / 2)

    //add it to the scene
    self.addChild(sprite)
    //ground variable for the node
    var groundSensor = SKSpriteNode()

    //set the position of the node
    groundSensor.position = CGPointMake(0, groundSensorTexture.size().height)
    groundSensor.zPosition = 1000

    //set the physics body to equal the size of the image.
    groundSensor.physicsBody = SKPhysicsBody(rectangleOfSize:CGSizeMake(self.frame.size.width, groundSensorTexture.size().height * 1.85))

    //physics bodies
    groundSensor.physicsBody?.dynamic = false
    groundSensor.physicsBody?.restitution = CGFloat(0.0)

    groundSensor.physicsBody?.categoryBitMask = groundSensorCategory
    groundSensor.physicsBody?.contactTestBitMask = shoeGroundCategory | hurdleCategory

    //add the object to the scene
    self.addChild(ground)



    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    //shoe
    var shoeGroundTexture = SKTexture(imageNamed:"default_shoe")

    //change texture filtering mode.
    shoeGroundTexture.filteringMode = SKTextureFilteringMode.Nearest


    //Make the object.
    shoeGround = SKSpriteNode(texture: shoeGroundTexture)

    //set scale
    shoeGround.setScale(0.35)


    //position it.
    shoeGround.position = CGPointMake(self.frame.size.width * 0.35, ((groundSensorTexture.size().height * 2.0) + (shoeGround.frame.size.height/2)))
    shoeGround.zPosition = 100


    //give it the collision collider of a circle.
    shoeGround.physicsBody = SKPhysicsBody(circleOfRadius: shoeGround.size.height / 2)
    shoeGround.physicsBody?.dynamic = true
    shoeGround.physicsBody?.allowsRotation = false
    shoeGround.physicsBody?.restitution = CGFloat(0.0)


    shoeGround.physicsBody?.categoryBitMask = shoeGroundCategory
    shoeGround.physicsBody?.contactTestBitMask = groundSensorCategory | hurdleCategory

    //add it to the scene

    self.addChild(shoeGround)



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    //Hurdles

    //Create the Hurdles.
    hurdleTexture = SKTexture(imageNamed:"hurdle")


    //Spawn the Hurdles.


    let spawn = SKAction.runBlock({() in self.spawnHurdles()})

    var time = arc4random() % 3
    time += 2

    let delay = SKAction.waitForDuration(2.0, withRange: 2.0)

    let spawnThenDelay = SKAction.sequence([spawn, delay])
    let spawnThenDelayForever = SKAction.repeatActionForever(spawnThenDelay)

    self.runAction(spawnThenDelayForever)

}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


func didBeginContact(contact: SKPhysicsContact) {

    var firstBody, secondBody, thirdBody: SKPhysicsBody

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

    if ((firstBody.categoryBitMask & shoeGroundCategory) != 0 && (secondBody.categoryBitMask & hurdleCategory != 0)) {
            //secondBody.node?.removeFromParent()
            println("Hurdle")
    }


    if ((firstBody.categoryBitMask & shoeGroundCategory != 0) && (secondBody.categoryBitMask & groundSensorCategory != 0)) {
            //secondBody.node?.removeFromParent()
            jump = true
    }
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



func didEndContact(contact: SKPhysicsContact) {

    var firstBody, 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 & shoeGroundCategory != 0) &&
        (secondBody.categoryBitMask & groundSensorCategory != 0)) {
            //secondBody.node?.removeFromParent()
            jump = false
    }
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


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

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

        if jump == true {
        shoeGround.physicsBody?.velocity = CGVectorMake(0, 0)
        shoeGround.physicsBody?.applyImpulse(CGVectorMake(0, 82))

        }

    }
}



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


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


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


func spawnHurdles() {


    let hurdle = SKSpriteNode(texture: hurdleTexture)

    hurdle.setScale(2.0)
    hurdle.position = CGPointMake(0, 175)

    hurdle.physicsBody = SKPhysicsBody(rectangleOfSize:hurdle.size)
    hurdle.physicsBody?.dynamic = false

    hurdle.physicsBody?.categoryBitMask = hurdleCategory
    hurdle.physicsBody?.contactTestBitMask = shoeGroundCategory | groundSensorCategory


    hurdle.runAction(hurdlesMoveAndRemove)

    self.addChild(hurdle)
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//movement of Hurdles.
func moveHurdles() {

    let distanceToMove = CGFloat(self.frame.size.width + 10.0 * hurdleTexture.size().width)
    let moveHurdles = SKAction.moveByX(-distanceToMove, y: 0, duration: NSTimeInterval(0.00185 * distanceToMove))

    let removeHurdles = SKAction.removeFromParent()

    hurdlesMoveAndRemove = SKAction.sequence([moveHurdles, removeHurdles])
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


func stopHurdles() {

    let distanceToMove = CGFloat(self.frame.size.width + 10.0 * hurdleTexture.size().width)
    let stopHurdles = SKAction.moveByX(0, y: 0, duration: NSTimeInterval(0.00185 * distanceToMove))

    let removeHurdles = SKAction.removeFromParent()

    hurdlesStopAndRemove = SKAction.sequence([stopHurdles, removeHurdles])
}



///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

}

1 个答案:

答案 0 :(得分:0)

检查鞋子是否在地上的一种方法是在Update功能上实施条件。

根据您的障碍和地面,条件是检查鞋子的y坐标以及是否低于某个阈值。

第二种方法是检查精灵的速度是否接近于零。