【问题标题】:How to do i set up proper collision detection in SpriteKit, Swift 3如何在 SpriteKit、Swift 3 中设置正确的碰撞检测
【发布时间】:2017-10-07 02:19:48
【问题描述】:

我最近刚刚在我的游戏中设置了碰撞检测,但它似乎不起作用。我对 spritekit 很陌生,我想知道发生了什么。下面我将为您提供游戏场景类,didMoveToView,一个在视图中生成球的函数,以及我的 Did begin 联系函数。请注意,我现在只使用红球和红块,所以它们是唯一发生碰撞的两个。请告诉我项目中是否还有其他您需要查看且未在下面提供的内容。

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)



}

// 顶级产卵器

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






}

UPDATE::: 我找到了哪里出错了,但我的问题还没有从技术上解决。我在 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!


}

这就是我让它工作的方式,但问题是我想根据它是绿色还是红色将单个类别位掩码应用于球。

【问题讨论】:

  • 如果您将代码/问题简化为您遇到的问题,您更有可能获得有用的答案。

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


【解决方案1】:

使用临时变量将适当的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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多