swift中的接触和碰撞检测

时间:2015-07-15 06:15:18

标签: ios swift

我正在制作一个落下物体的游戏和一个避开这些物体的球,

let ballCatogary:UInt32 = 0x1 << 0
let objectsCatogary:UInt32 = 0x1 << 1
let bottomWallCatogary:UInt32 = 0x1 << 3

1)ballcatogary用于用户控制的球节点 2)对象类别用于右侧和左侧墙壁,以及当用户与之交互时下降的对象,游戏停止 3)bottomcatogary是一个sknode,对象不与之交互,但当它通过它时,得分值增加

我已将每个节点分配到其categoryBitMask,但现在我不知道在didBeginContact中要写什么,我只需要帮助使用do begin collision方法,而不是如何增加得分或结束比赛,我得到了覆盖。

我的代码:

//
//  PlayScene.swift
//  WalkRun
//
//  Created by naeim on 7/10/15.
//  Copyright (c) 2015 naeim. All rights reserved.
//

import Foundation
import SpriteKit

class PlayScene: SKScene, SKPhysicsContactDelegate{

    var ball = SKSpriteNode(imageNamed: "ball")
    var wall = SKNode()
    var wallRight = SKNode()
    var ballSpeed = CGFloat()

    let ballCatogary:UInt32 = 0x1 << 0
    let objectsCatogary:UInt32 = 0x1 << 1
    let bottomWallCatogary:UInt32 = 0x1 << 3

    var endOfScreenRight = CGFloat()

    var gameOver = 0

    var movingObjects = SKNode()

    var score = 0
    var scoreLabel = SKLabelNode()

    var bigWall = SKSpriteNode()
    var tallWall = SKSpriteNode()



    override func didMoveToView(view: SKView) {

        endOfScreenRight = 100

        self.physicsWorld.contactDelegate = self

        backgroundColor = UIColor(hex: 0x80d9ff)
        self.physicsWorld.gravity = CGVectorMake(-9,0)

        self.addChild(movingObjects)

        //creating the ball
        ball.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame) + self.ball.size.height * 2)
        ball.physicsBody = SKPhysicsBody(circleOfRadius: self.ball.size.width / 2)
        ball.zPosition = 10
        ball.physicsBody?.categoryBitMask = ballCatogary
        ball.physicsBody?.collisionBitMask =  objectsCatogary
        ball.physicsBody?.contactTestBitMask =  objectsCatogary


        self.addChild(ball)

        //creating the wall of the left
        wall.position = CGPointMake(CGRectGetMinX(self.frame),CGRectGetMinY(self.frame))
        wall.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(2, self.frame.size.height * 2.0))
        wall.physicsBody?.dynamic = false
        wall.physicsBody?.categoryBitMask = objectsCatogary

        self.addChild(wall)

        //creating the wall of the right
        wallRight.position = CGPointMake(CGRectGetMaxX(self.frame), CGRectGetMinY(self.frame))
        wallRight.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(2, self.frame.size.height * 2.0))
        wallRight.physicsBody?.dynamic = false
        wallRight.physicsBody?.categoryBitMask = objectsCatogary


        self.addChild(wallRight)


        //creating the label
        scoreLabel.fontName = "Helvetica"
        scoreLabel.fontSize = 60
        scoreLabel.text = "0"
        scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)  )
        self.addChild(scoreLabel)

        //bottom wall
        var bottomWall = SKNode()
        bottomWall.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame) + ball.position.y / 1.4)
        bottomWall.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width , 1))
        bottomWall.physicsBody?.dynamic = false
        bottomWall.physicsBody?.affectedByGravity = false
        bottomWall.physicsBody?.categoryBitMask = bottomWallCatogary


        self.addChild(bottomWall)




        var timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("randObject"), userInfo: nil, repeats: true)



    }



    //function to randomly choose which object

    func randObject(){
        if gameOver == 0{


        var rand = arc4random_uniform(6)+1


        switch(rand){

        case 1:
            leftObject()

        case 2:
            middleObject()

        case 3:
            rightObject()

        case 4:
            LeftAndMiddleObject()

        case 5:
            rightAndLeftObject()

        case 6:
            rightAndMiddleObject()

        default:
            println("error !! non a number other than 0, 1, 2 has been choosen .")

            }


        }
    }

    //function that creates a Bigwall
    func createBigWall(PositionX:CGFloat , PositionY:CGFloat){
        bigWall = SKSpriteNode(imageNamed: "shortwall")
        bigWall.position = CGPointMake(PositionX, PositionY)
        bigWall.physicsBody = SKPhysicsBody(rectangleOfSize: self.bigWall.size)
        bigWall.physicsBody?.dynamic = false
        bigWall.physicsBody?.affectedByGravity = false
        bigWall.physicsBody?.categoryBitMask = objectsCatogary
        bigWall.physicsBody?.collisionBitMask = ballCatogary
        bigWall.physicsBody?.contactTestBitMask = ballCatogary

        var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height / 100))
        var removeObjects = SKAction.removeFromParent()
        var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects])
        bigWall.runAction(moveAndRemoveObjects)
        movingObjects.addChild(bigWall)

    }
    //function that creates a Tallwall
    func createTallWall(PositionX:CGFloat , PositionY:CGFloat ){
        tallWall = SKSpriteNode(imageNamed: "tallwall")
        tallWall.position = CGPointMake(PositionX, PositionY)
        tallWall.physicsBody = SKPhysicsBody(rectangleOfSize: self.tallWall.size)
        tallWall.physicsBody?.dynamic = false
        tallWall.physicsBody?.affectedByGravity = false
        tallWall.physicsBody?.categoryBitMask = objectsCatogary
        tallWall.physicsBody?.collisionBitMask = ballCatogary
        tallWall.physicsBody?.contactTestBitMask = ballCatogary
        var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height / 100))
        var removeObjects = SKAction.removeFromParent()
        var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects])
        tallWall.runAction(moveAndRemoveObjects)
        movingObjects.addChild(tallWall)

    }

    //function to create the left objects

    func leftObject(){
        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {


           createBigWall(CGRectGetMinX(self.frame) + 30, PositionY: CGRectGetMaxY(self.frame))

        }

        else
        {
            createTallWall(CGRectGetMinX(self.frame) - 60, PositionY: CGRectGetMaxY(self.frame))




        }


    }

    //function to create the middle objects

    func middleObject(){

        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {
            createBigWall(CGRectGetMidX(self.frame) , PositionY: CGRectGetMaxY(self.frame))

        }
        else
        {

            createTallWall(CGRectGetMidX(self.frame), PositionY: CGRectGetMaxY(self.frame))

        }

    }

    //function to create the right objects

    func rightObject(){
        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {
            createBigWall(CGRectGetMaxX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))



        }
        else
        {
      createTallWall(CGRectGetMaxX(self.frame) - 60, PositionY: CGRectGetMaxY(self.frame))

        }


    }

    //function to create a right and left object

    func rightAndLeftObject(){

        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {
            createBigWall(CGRectGetMaxX(self.frame) - 30 , PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMinX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))
        }
        else
        {

            createBigWall(CGRectGetMinX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMaxX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))

                    }


    }

    func rightAndMiddleObject(){

        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {
            createBigWall(CGRectGetMidX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMaxX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))
        }
        else
        {
            createBigWall(CGRectGetMaxX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMinX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))
        }


    }

    func LeftAndMiddleObject(){

        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {
            createBigWall(CGRectGetMinX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMidX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))
        }
        else
        {
            createBigWall(CGRectGetMidX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMinX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))
        }


    }




    func didBeginContact(contact: SKPhysicsContact) {


        // 1. Create local variables for two physics bodies
        var firstBody: SKPhysicsBody
        var secondBody: SKPhysicsBody

        // 2. Assign the two physics bodies so that the one with the lower category is always stored in firstBody
        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
            firstBody = contact.bodyA
            secondBody = contact.bodyB
        } else {
            firstBody = contact.bodyB
            secondBody = contact.bodyA
        }

        // 3. react to the contact between ball and bottom
        if firstBody.categoryBitMask == ballCatogary && secondBody.categoryBitMask == objectsCatogary {

            gameOver = 1
            movingObjects.speed = 0


        }
        else
        {
            println("score ++")
        }
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        if gameOver == 0 {

        ball.physicsBody?.velocity = CGVectorMake(0, 0)
        ball.physicsBody?.applyImpulse(CGVectorMake(70,0))

        }

    }

    override func update(currentTime: NSTimeInterval) {

         if gameOver == 0 {

        }


    }
}

1 个答案:

答案 0 :(得分:1)

我不确定你在问什么,但请查看这个示例代码:

    //This delegate function will call when two body collide with each other
    func didBeginContact(contact: SKPhysicsContact) {


        // 1. Create local variables for two physics bodies
        var firstBody: SKPhysicsBody
        var secondBody: SKPhysicsBody

        // 2. Assign the two physics bodies so that the one with the lower category is always stored in firstBody
        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
            firstBody = contact.bodyA
            secondBody = contact.bodyB
        } else {
            firstBody = contact.bodyB
            secondBody = contact.bodyA
        }

        // 3. react to the contact between ball and bottom
        if firstBody.categoryBitMask == ballCatogary && secondBody.categoryBitMask == bottomWallCatogary {
            //TODO: Replace the log statement with display of Game Over Scene
            //add your code here.

        }
    }

并且不要忘记在课堂声明中添加SKPhysicsContactDelegate,它将如下所示:

class playScene : SKScene, SKPhysicsContactDelegate {

    //your code
}

如果你想检测另一次碰撞,可以这样做:

if firstBody.categoryBitMask == ballCatogary && secondBody.categoryBitMask == objectsCatogary {

        gameOver = 1
        movingObjects.speed = 0


    }
    else if firstBody.categoryBitMask == objectsCatogary && secondBody.categoryBitMask == bottomWallCatogary{
         score++
         println(score)
    }

希望这会有所帮助。