ios - spritekit 中的接触/碰撞问题

标签 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])
}



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

}

最佳答案

检查鞋子是否着地的一种方法是在 Update 函数中实现一个条件。

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

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

关于ios - spritekit 中的接触/碰撞问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30700619/

相关文章:

swift - 发布图像对象 Clarifai Rest api swift

ios - Sprite Kit 停止播放音乐文件并从头开始播放

ios - 是否可以在 Sprite Kit 中将一个场景推到另一个场景之上?

ios - Sprite Kit - 在滑动手势的情况下为 SKSpriteNode 创建拱形路径

ios - 如何在iOS(swift)项目中集成Paytm支付网关?无法创建 PGMerchantConfiguration 对象

swift - iOS 13.2 从 MapKit 中删除叠加层导致 map 闪烁

swift - 是否可以将输入的文本保存到 SwiftUI 的警报文本字段中,并像这样在应用程序中显示它 -> Text ("alert text input here")?

objective-c - 选项卡栏 Controller 未正确显示

objective-c - 如何在 iOS 上创建具有更高 dpi 的 PDF?

ios - 具有 2 个独立设计的 UICollectionView