如何在SwriteKit中设置正确的碰撞检测,Swift 3

时间:2017-05-08 22:59:04

标签: ios swift3 sprite-kit game-physics skspritenode

我刚刚在我的游戏中设置了碰撞检测它似乎没有起作用。我是spritekit的新手,我想知道发生了什么。下面我将为您提供gamscene类,didMoveToView,一个在视图中产生球的函数,以及我的Did开始联系功能。请注意,我现在只使用红色球和红色块,所以它们是唯一的两个碰撞。请告诉我项目中是否还有其他需要查看的内容,下面没有提供。

import SpriteKit
import GameplayKit

class GameScene: SKScene, SKPhysicsContactDelegate {



var greenBlock = SKSpriteNode ()
var redBlock = SKSpriteNode()
var yellowBlock = SKSpriteNode()
var blueBlock = SKSpriteNode()

var greenBall = SKSpriteNode()
var redBall = SKSpriteNode()
var yellowBall = SKSpriteNode()
var blueBall = SKSpriteNode()
var ball = SKSpriteNode()

var ballSpeedTop = CGVector(dx: 0, dy: 5)
var ballSpeedBottom = CGVector(dx: 0, dy: -5)

这是我定义categoryBitMask

的数字的地方
let redBallCategory: UInt32 = 0x1 << 0
let greenBallCategory: UInt32 = 0x1 << 1
let blueBallCategory: UInt32 = 0x1 << 2
let yellowBallCategory: UInt32 = 0x1 << 3

let redBlockCategory: UInt32 = 0x1 << 4
let yellowBlockCategory: UInt32 = 0x1 << 5
let greenBlockCategory: UInt32 = 0x1 << 6
let blueBlockCategory: UInt32 = 0x1 << 7


override func didMove(to view: SKView) {

    physicsWorld.contactDelegate = self

我将物理机构应用到块中。

    redBlock = self.childNode(withName: "redBlock") as! SKSpriteNode
    redBlock.physicsBody?.categoryBitMask = redBlockCategory
    redBlock.physicsBody?.collisionBitMask = redBallCategory
    redBlock.physicsBody?.contactTestBitMask = redBallCategory


    yellowBlock = self.childNode(withName: "yellowBlock") as! SKSpriteNode
    greenBlock = self.childNode(withName: "greenBlock") as! SKSpriteNode
    blueBlock = self.childNode(withName: "blueBlock") as! SKSpriteNode

    redBlock.physicsBody?.affectedByGravity = false
    redBlock.physicsBody?.isDynamic = true

    greenBlock.physicsBody?.affectedByGravity = false
    greenBlock.physicsBody?.isDynamic = true

    blueBlock.physicsBody?.affectedByGravity = false
    blueBlock.physicsBody?.isDynamic = false

    yellowBlock.physicsBody?.affectedByGravity = false
    yellowBlock.physicsBody?.isDynamic = false

    initializeGame()

    print("hello")





}


    func initializeGame (){


    Timer.scheduledTimer(timeInterval: TimeInterval(randomBetweenNumbers(firstNum: 2, secondNum: 4)), target: self, selector: #selector(topBall), userInfo: nil, repeats: true)

    Timer.scheduledTimer(timeInterval: TimeInterval(randomBetweenNumbers(firstNum: 2, secondNum: 4)), target: self, selector: #selector(bottomBall), userInfo: nil, repeats: true)



}

// top ball spawner

func topBall () -> SKSpriteNode {

    let ball: SKSpriteNode?;


    if Int(randomBetweenNumbers(firstNum: 0, secondNum: 2)) == 0 {


        ball = SKSpriteNode(imageNamed: "redBall")
        ball?.name = "redBall"
        ball!.physicsBody?.categoryBitMask = redBallCategory
        ball!.physicsBody?.collisionBitMask = redBlockCategory
        ball!.physicsBody?.contactTestBitMask = redBlockCategory


    } else {


        ball = SKSpriteNode(imageNamed: "greenBall")
        ball?.name = "greenBall"




    }




    ball!.size = CGSize(width: 30, height: 30)
    ball!.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    ball!.position = CGPoint(x: 0, y: 0)

    ball!.physicsBody = SKPhysicsBody(circleOfRadius: ball!.size.height / 2)
    ball!.physicsBody?.affectedByGravity = false
    ball!.physicsBody?.isDynamic = true

    ball!.zPosition = 2


    self.addChild(ball!)

    ball!.physicsBody?.applyImpulse(ballSpeedTop)

    return ball!


}

联系功能

    func didBegin(_ contact: SKPhysicsContact) {


    if (contact.bodyA.categoryBitMask == redBallCategory && contact.bodyB.categoryBitMask == redBlockCategory){

        print("touched red block")

    } else if (contact.bodyB.categoryBitMask == redBallCategory && contact.bodyA.categoryBitMask == redBlockCategory){

        print("touched a red block")
    }






}

更新:::我发现我哪里出错但我的问题在技术上尚未解决。我已经在if语句之外应用了redBall的属性,这意味着redballs类别位掩码等应用于两个球,我需要一种方法将redBall类别位掩码应用于redBall,当它生成时和不同的categorybitmask它产生时的绿球。

    func topBall () -> SKSpriteNode {

    let ball: SKSpriteNode?;


    if Int(randomBetweenNumbers(firstNum: 0, secondNum: 2)) == 0 {


        ball = SKSpriteNode(imageNamed: "redBall")
        ball?.name = "redBall"


    } else {


        ball = SKSpriteNode(imageNamed: "greenBall")
        ball?.name = "greenBall"




    }




    ball!.size = CGSize(width: 30, height: 30)
    ball!.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    ball!.position = CGPoint(x: 0, y: 0)

    ball!.physicsBody = SKPhysicsBody(circleOfRadius: ball!.size.height / 2)
    ball!.physicsBody?.affectedByGravity = false
    ball!.physicsBody?.isDynamic = true
    ball!.physicsBody?.categoryBitMask = redBallCategory
    ball!.physicsBody?.collisionBitMask = redBlockCategory
    ball!.physicsBody?.contactTestBitMask = redBlockCategory


    ball!.zPosition = 2


    self.addChild(ball!)

    ball!.physicsBody?.applyImpulse(ballSpeedTop)

    return ball!


}

这就是我如何使用它,但问题是我想将单个类别的比特掩模应用于球,这取决于它是绿色还是红色。

1 个答案:

答案 0 :(得分:0)

使用临时变量将相应的categorycollisioncontactTest位掩码存储在您设置衍生球的图像和名称的同一代码块中,然后使用这些临时变量在物理实体中设置实际值:

  var categoryBitMask: UInt32
  var collisonBitMask: UInt32
  var contactTestBitMask: Uint32

  if Int(randomBetweenNumbers(firstNum: 0, secondNum: 2)) == 0 {
        ball = SKSpriteNode(imageNamed: "redBall")
        ball?.name = "redBall"
        categoryBitMask = redBallCategory
        collisionBitMask = redBlockCategory
        contactTestBitMask = redBlockCategory

    } else {
        ball = SKSpriteNode(imageNamed: "greenBall")
        ball?.name = "greenBall"
        categoryBitMask = greenBallCategory
        collisionBitMask = greenBlockCategory
        contactTestBitMask = greenBlockCategory
    }

    ball!.size = CGSize(width: 30, height: 30)
    ball!.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    ball!.position = CGPoint(x: 0, y: 0)

    ball!.physicsBody = SKPhysicsBody(circleOfRadius: ball!.size.height / 2)
    ball!.physicsBody?.affectedByGravity = false
    ball!.physicsBody?.isDynamic = true
    ball!.physicsBody?.categoryBitMask = categoryBitMask
    ball!.physicsBody?.collisionBitMask = collisionBitMask
    ball!.physicsBody?.contactTestBitMask = contactTestBitMask