Collide type source error - spritekit swift game

给你一囗甜甜゛ 提交于 2019-12-22 10:59:01

问题


So I have adjusted my games ball type from a shape to an image which forced me to redo the physics of my game. I am new to swift and have struggled with fixing my collisions in my swift game.

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)
 }

That is the scene and physics I attempted to set up and was directed with. Below is the collide errors which cause the app to crash upon touch.

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 definition as below:

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
}

回答1:


So the issue now is that you have two definition for your masks:

Remove this one:

enum CollisionTypes: UInt32 {
        case Floor = 1
        case Ball = 2
    }

Use only this one:

    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
        }

Correct all code to match with CollideType definitions.

Correct this line in didBeginContact:

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

with:

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

If you have correct all you will don't have yet this error:

// ball and ceil => ERROR


来源:https://stackoverflow.com/questions/38289783/collide-type-source-error-spritekit-swift-game

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!