碰撞类型源代码错误 - SpriteKit Swift 游戏

3

所以我已经将我的游戏球类型从形状调整为图像,这迫使我重新设计了游戏的物理效果。我是新手,对于在Swift游戏中修复碰撞问题感到困难。

class GameScene: SKScene, GameDelegate, SKPhysicsContactDelegate {
    var ball: Ball!
    let ballSpeedX = CGFloat(500)
    //ball = Ball(imageNamed:"colorBall.png")
    enum CollisionTypes: UInt32 {
        case Floor = 1
        case Ball = 2
    }
    // board
    let boards = Boards.make(CollideType.BoardStart.rawValue)
    var lastBoard: SKNode?
    var boardSpeedY: CGFloat { get { return CGFloat(160) * accelerate }}
    let boardDistanceY = CGFloat(300)
    let boardYDistanceHide = CGFloat(30)

    override func didMoveToView(view: SKView) {
        self.physicsWorld.gravity = CGVectorMake(0, 0)
        self.physicsWorld.contactDelegate = self
        let flooeBody = SKPhysicsBody.init(edgeLoopFromRect: self.frame)
        self.physicsBody = floorBody
        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
       ball.hidden = false
       self.addChild(ball)

       // scene
       self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
       self.physicsBody!.categoryBitMask = CollideType.Scene.toMask()
       self.physicsBody!.dynamic = false
       self.physicsBody!.friction = 0

       // ceil
       let ceil = SKShapeNode(rectOfSize: CGSize(width: self.frame.width, height: 2))
       ceil.position.x = CGRectGetMidX(self.frame)
       ceil.position.y = self.frame.height - CGRectGetMidY(ceil.frame)
       ceil.physicsBody = SKPhysicsBody(rectangleOfSize: ceil.frame.size)
       ceil.physicsBody!.categoryBitMask = CollideType.Ceil.toMask()
       ceil.physicsBody!.dynamic = false
       ceil.alpha = 0
       self.addChild(ceil)

       // floor
       let floor = SKShapeNode(rectOfSize: CGSize(width: self.frame.width, height: 2))
       floor.position.x = CGRectGetMidX(self.frame)
       floor.position.y = CGRectGetMidY(floor.frame)
       floor.physicsBody = SKPhysicsBody(rectangleOfSize: floor.frame.size)
       //floor.physicsBody!.categoryBitMask = CollideType.Floor.toMask() two
       floor.physicsBody!.dynamic = false
       floor.alpha = 0
       self.addChild(floor)
 }

那是我尝试设置并进行指导的场景和物理效果。以下是碰撞错误,这些错误会在触摸时导致应用程序崩溃。
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 error: CANNOT CONVERT VALUE OF TYPE BOOL TO EXPCTD ARG TYPE UIINT32

    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 => ERROR
    else if bitMaskAAndB == CollideType.toMask([.Ball, .Ceil]) {
        stopGame()
    }

    // ball and floor => stop game 
        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)
    }   
 }

以下是 CollideType 的定义:
enum CollideType: Int {

case Scene = 0
case Ceil = 1
case Floor = 2
case Ball = 3
case BoardStart = 4

func toMask()-> UInt32 {
    return UInt32(1 << self.rawValue)
}
static func toMask(masks: [CollideType])-> UInt32 {
    var toMask = UInt32(0)
    for type in masks {
        toMask |= type.toMask()
    }
    return toMask
}

是的,我做了 - 对此很抱歉。 - N. Howey
没问题,现在我们也有CollideType的定义,太好了! - Alessandro Ornano
1个回答

1
现在的问题是,您有两个口罩定义:
删除这个:
enum CollisionTypes: UInt32 {
        case Floor = 1
        case Ball = 2
    }

仅使用这一个:
    enum CollideType: Int {

        case Scene = 0
        case Ceil = 1
        case Floor = 2
        case Ball = 3
        case BoardStart = 4

        func toMask()-> UInt32 {
            return UInt32(1 << self.rawValue)
        }
        static func toMask(masks: [CollideType])-> UInt32 {
            var toMask = UInt32(0)
            for type in masks {
                toMask |= type.toMask()
            }
            return toMask
        }

将所有代码更正以与CollideType定义相匹配。

didBeginContact中更正此行:

let bitMaskAAndB = contact.bodyA.categoryBitMask == CollisionTypes.Floor.rawValue && contact.bodyB.categoryBitMask == CollisionTypes.Ball.rawValue

使用:

let bitMaskAAndB = contact.bodyA.categoryBitMask == CollideType.Floor.toMask() ? contact.bodyB.categoryBitMask : CollideType.Ball.toMask()

如果您已经纠正了所有错误,那么您将不会再遇到这个错误:
// ball and ceil => ERROR

谢谢,我提出了这些建议,并且在启动应用程序时没有错误,但是在启动时应用程序崩溃并显示:unexpectedly found nil while unwrapping an Optional value。不确定这是什么意思,您能解释一下吗?请将所有代码更正以与CollideType定义相匹配。谢谢! - N. Howey
当您尝试使用/分配属性给未初始化的对象时,会出现此错误。我的意思是“将所有CollisionTypes替换为正确的CollideType形式(CollideType.<Object>.toMask())”。 - Alessandro Ornano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接