sprite-kit - 展开可选值 : PhysicsBody - Swift SpriteKit

标签 sprite-kit swift2 skspritenode

因此,我对游戏中的球进行了一些调整,为了避免展开可选值错误,我注释了以下内容

//didMoveToView
    self.physicsWorld.gravity = CGVectorMake(0, 0)
    self.physicsWorld.contactDelegate = self
    let fieldBody = SKPhysicsBody.init(edgeLoopFromRect: self.frame)
    self.physicsBody = fieldBody
    self.physicsBody!.affectedByGravity = false
    self.physicsBody!.usesPreciseCollisionDetection = true
    self.physicsBody!.dynamic = true
    self.physicsBody!.mass = 0
    self.physicsBody!.friction = 0
    self.physicsBody!.linearDamping = 0
    self.physicsBody!.angularDamping = 0
    self.physicsBody!.restitution = 1
    self.physicsBody!.categoryBitMask = CollisionTypes.Floor.rawValue
    self.physicsBody!.contactTestBitMask = CollisionTypes.Ball.rawValue

    // Prepare the ball - physics engine.
    ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.width/2)
    ball.physicsBody!.affectedByGravity = true
    ball.physicsBody!.restitution = 0.8
    ball.physicsBody!.linearDamping = 0
    ball.physicsBody!.friction = 0.3
    ball.physicsBody!.dynamic = true
    ball.physicsBody!.mass = 0.5
    ball.physicsBody!.allowsRotation = true
    ball.physicsBody!.categoryBitMask = CollisionTypes.Ball.rawValue
    ball.physicsBody!.contactTestBitMask = CollisionTypes.Floor.rawValue
    ball.physicsBody!.collisionBitMask = CollisionTypes.Floor.rawValue
}

我这样做了,我的游戏启动了,但是一旦 toucheBegan,就会弹出同样的错误。我不知道如何解决所有这些解包错误。我是 Swift 新手,不知道应该如何调整这些物理。我的 contactBegin 看起来像这样:

func didBeginContact(contact: SKPhysicsContact) {
    let bitMaskAAndB = contact.bodyA.categoryBitMask == CollisionTypes.Floor.rawValue &&
                contact.bodyB.categoryBitMask == CollisionTypes.Ball.rawValue
    let ballAndBoardMask = CollideType.Ball.toMask() | boards.usedCollideMasks

    // ball and board, handle it by board delegate
    if bitMaskAAndB | ballAndBoardMask == ballAndBoardMask {

        let boardNode: SKNode! = contact.bodyA.categoryBitMask == CollideType.Ball.toMask() ? contact.bodyB.node : contact.bodyA.node
        let board = boardNode.bind as! BoardDelegate
        board.didBeginContact(boardNode, ball: ball, contact: contact, game: self)
    }

    // ball and ceil => stop game
    else if bitMaskAAndB == CollideType.toMask([.Ball, .Ceil]) {
        stopGame()
    }

    // ball and floor => stop game add explosion or fall off screen
    else if bitMaskAAndB == CollideType.toMask([.Ball, .Floor]) {
        stopGame()
    }
}
func didEndContact(contact: SKPhysicsContact) {

    let ballAndBoardMask = CollideType.Ball.toMask() | boards.usedCollideMasks

    // ball and board, handle it by board delegate
    if contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask | ballAndBoardMask == ballAndBoardMask {

        let boardNode: SKNode! = contact.bodyA.categoryBitMask == CollideType.Ball.toMask() ? contact.bodyB.node : contact.bodyA.node
        let board = boardNode.bind as! BoardDelegate
        board.didEndContact(boardNode, ball: ball, contact: contact, game: self)
    }

}

编辑:我根据您提出的建议设置了我的物理世界,并调整了我的 didBeginContact 乐趣,但是使用以下代码,我收到多个错误:无法将 bool 类型的值转换为 UInt32。

PS。感谢您的帮助和耐心,这些都是新术语,我正在尽力理解。 :)

最佳答案

我不知道您的 CollideType 类或声明,因此下面的代码向您解释如何构建正确的 physicalsWorldphysicalsBody以免在碰撞过程中出现问题。

但首先:我们将在此项目中充分使用 categoryBitMaskcontactTestBitMaskcollisionBitMask 属性,因为我们有非常精确的规则来使项目正常运行:

  • categoryBitMask 是定义其对象类型的数字 考虑到碰撞。

  • collisionBitMask 是一个数字,定义了该对象的类别 节点应该发生碰撞。

  • contactTestBitMask 是一个数字,定义我们想要的碰撞 收到通知。

SpriteKit 希望使用 UInt32 来描述这三个位掩码。您的位掩码应从 1 开始,然后每次加倍。

代码:

class GameScene: SKScene, SKPhysicsContactDelegate {
    var ball: Ball!
    let ballSpeedX = CGFloat(500)
    enum CollisionTypes: UInt32 {
        case Field = 1
        case Ball = 2
    }
    override func didMoveToView(view: SKView) {
        // ball
        ball = Ball(imageNamed:"colorBall.png")
        ball.position = CGPointMake(self.ball.frame.size.width,self.ball.frame.size.height)

        // Prepare the world - physics engine.
        self.physicsWorld.gravity = CGVectorMake(0, -6)
        self.physicsWorld.contactDelegate = self
        let fieldBody = SKPhysicsBody.init(edgeLoopFromRect: self.frame)
        self.physicsBody = fieldBody
        self.physicsBody!.affectedByGravity = false
        self.physicsBody!.usesPreciseCollisionDetection = true
        self.physicsBody!.dynamic = true
        self.physicsBody!.mass = 0
        self.physicsBody!.friction = 0
        self.physicsBody!.linearDamping = 0
        self.physicsBody!.angularDamping = 0
        self.physicsBody!.restitution = 1
        self.physicsBody!.categoryBitMask = CollisionTypes.Field.rawValue
        self.physicsBody!.contactTestBitMask = CollisionTypes.Ball.rawValue

        // Prepare the ball - physics engine.
        ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.width/2)
        ball.physicsBody!.affectedByGravity = true
        ball.physicsBody!.restitution = 0.8
        ball.physicsBody!.linearDamping = 0
        ball.physicsBody!.friction = 0.3
        ball.physicsBody!.dynamic = true
        ball.physicsBody!.mass = 0.5
        ball.physicsBody!.allowsRotation = true
        ball.physicsBody!.categoryBitMask = CollisionTypes.Ball.rawValue
        ball.physicsBody!.contactTestBitMask = CollisionTypes.Field.rawValue
        ball.physicsBody!.collisionBitMask = CollisionTypes.Field.rawValue

        //ball.physicsBody!.categoryBitMask = CollideType.Ball.toMask()
        //ball.physicsBody!.collisionBitMask = CollideType.toMask([.Scene, .Ceil, .Floor]) | boards.usedCollideMasks
        //ball.physicsBody!.contactTestBitMask = CollideType.toMask([.Scene, .Ceil, .Floor]) | boards.usedCollideMasks
        ball.hidden = false
        self.addChild(ball)
    }
    func didBeginContact(contact: SKPhysicsContact) {
        if (contact.bodyA.categoryBitMask == CollisionTypes.Field.rawValue &&
            contact.bodyB.categoryBitMask == CollisionTypes.Ball.rawValue) {
            print("contact between field and ball")
        }
    }
}

正如您所看到的,第一件重要的事情是准备物理世界(跟踪物理必须工作的边界),为其分配一个类别以及与其他对象交互所需的所有其他参数。然后构建对象的物理主体,在本例中是球。

关于sprite-kit - 展开可选值 : PhysicsBody - Swift SpriteKit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38280426/

相关文章:

arrays - 如何更改此数组以将物理体赋予每个单独的节点(位掩码)?

ios - 我如何在显示一次后删除我的 GameScene?

swift - Swift 中的对象 : Value of 'Object' has no member

swift - 从特定点缩放 SpriteNode

ios - swift:将 SKShapeNode 转换为 SKSpriteNode -> 无纹理

swift - 在 Swift 中混合 UIColors

ios - SpriteView 不会在状态更改时暂停场景

ios - 雪碧包 : how to make newly spawned enemy ships shoot bullets at player?

Swift,spritekit : How to restart GameScene after game over? 停止滞后?

swift - 在 Swift 中使用 Cell Tags 和 objectForKey