spritekit:无法检测到碰撞

时间:2017-07-04 17:05:47

标签: ios swift sprite-kit

所以我尝试使用skphysicscontact但是当“cat”和“spinnynode”碰撞时,即使有物理交互,也没有来自它们的输出

另一方面,为什么定时器功能不起作用?它似乎根本没有召唤出这个功能。

请帮助,我是新手。感谢

import SpriteKit
import GameplayKit
import UIKit
import Foundation

struct physicsCollision {
static let cat: UInt32 = 1
static let spinnyNode: UInt32 = 2
}



class GameScene: SKScene, SKPhysicsContactDelegate {



var entities = [GKEntity]()
var graphs = [String : GKGraph]()
var catTimer = Timer()
var score = 0


private var lastUpdateTime : TimeInterval = 0
private var label : SKLabelNode?
private var spinnyNode : SKShapeNode?




let meow = SKAction.playSoundFileNamed("cat meow", waitForCompletion: false)



required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

//random range 

func randomInRange(lo: Float, hi : Float) -> Float{
    return lo + Float(arc4random_uniform(UInt32(hi - lo + 1)))
}


//spawn cat

func spawnCat(){

    // x coordinate between MinX (left) and MaxX (right):
    let randomX = randomInRange(lo: Float(self.frame.minX + 5), hi: Float(self.frame.maxX + 5))

    let startPoint = CGPoint(x: CGFloat(randomX), y: self.frame.height * 1.2)
    let endPoint = CGPoint(x: CGFloat(randomX), y:self.frame.height * -0.5)
    let cat = SKSpriteNode(imageNamed: "before right")

    cat.name = "cat"
    cat.setScale(0.3)
    cat.position = startPoint
    cat.zPosition = 1
    cat.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: cat.size.width, height: cat.size.height))
    cat.physicsBody?.affectedByGravity = false
    cat.physicsBody?.categoryBitMask = physicsCollision.cat
    cat.physicsBody?.contactTestBitMask = physicsCollision.spinnyNode
    cat.physicsBody?.collisionBitMask = physicsCollision.spinnyNode
    cat.physicsBody?.isDynamic = false
    self.addChild(cat)

    let moveCat = SKAction.move(to: endPoint, duration: 5)
    let deleteCat = SKAction.removeFromParent()
    let catSequence = SKAction.sequence([moveCat, meow, deleteCat])
    cat.run(catSequence)


}

//contact func

func didBeginContact(contact:SKPhysicsContact){

    var firstBody = SKPhysicsBody()
    var secondBody = SKPhysicsBody()

    if contact.bodyA.node?.name == "cat"
    {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    }
    else{
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }
 if firstBody.node?.name == "cat" && (secondBody.node?.name)! == "skinnynode"{
    print("contacted")

    }
}


override func sceneDidLoad() {

    self.physicsWorld.contactDelegate = self

    self.lastUpdateTime = 0

    //spawn cat at intervals,, time interval to decrease when points increase, use if loop


    catTimer = Timer.init(timeInterval: 1 , target: self, selector: Selector(("cat")), userInfo: nil, repeats: true)



    // Create shape node to use during mouse interaction
    let w = (self.size.width + self.size.height) * 0.05
    self.spinnyNode = SKShapeNode.init(rectOf: CGSize.init(width: w, height: w), cornerRadius: w * 0.5)
    spinnyNode?.name = "spinnynode"
    spinnyNode?.physicsBody = SKPhysicsBody(circleOfRadius: 0.5)
    spinnyNode?.physicsBody?.affectedByGravity = false
    spinnyNode?.zPosition = 1
    spinnyNode?.physicsBody?.categoryBitMask = physicsCollision.spinnyNode
    if let spinnyNode = self.spinnyNode{
        spinnyNode.lineWidth = 1.5
        spinnyNode.run(SKAction.repeatForever(SKAction.rotate(byAngle: CGFloat(Double.pi), duration: 1)))
        spinnyNode.run(SKAction.sequence([SKAction.wait(forDuration: 0.5),
                                          SKAction.fadeOut(withDuration: 0.3),
                                          SKAction.removeFromParent()]))
                                        }

    //create score label
    let scoreLabel = UILabel(frame: CGRect(x:((self.frame.height) * 0.5) , y:((self.frame.width) * 0.3), width: (self.frame.size.width)/3, height: 30))
    scoreLabel.center = CGPoint(x: (self.frame.size.width)/1.6 , y: (self.frame.size.height)/2)
    scoreLabel.textColor = UIColor.white
    scoreLabel.text = "\(score)"
    self.view?.addSubview(scoreLabel)



                                }


func touchDown(atPoint pos : CGPoint) {
    if let n = self.spinnyNode?.copy() as! SKShapeNode? {
        n.position = pos
        n.strokeColor = SKColor.green
        self.addChild(n)
    }
}

func touchMoved(toPoint pos : CGPoint) {
    if let n = self.spinnyNode?.copy() as! SKShapeNode? {
        n.position = pos
        n.strokeColor = SKColor.purple
        self.addChild(n)

    }
}

func touchUp(atPoint pos : CGPoint) {
    if let n = self.spinnyNode?.copy() as! SKShapeNode? {
        n.position = pos
        n.strokeColor = SKColor.red
        self.addChild(n)
    }
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

            spawnCat()
            if let label = self.label {
            label.run(SKAction.init(named: "Pulse")!, withKey: "fadeInOut")

    }

    for t in touches { self.touchDown(atPoint: t.location(in: self)) }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches { self.touchMoved(toPoint: t.location(in: self)) }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}


override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered

    // Initialize _lastUpdateTime if it has not already been
    if (self.lastUpdateTime == 0) {
        self.lastUpdateTime = currentTime
    }

    // Calculate time since last update
    let dt = currentTime - self.lastUpdateTime

    // Update entities
    for entity in self.entities {
        entity.update(deltaTime: dt)
    }

    self.lastUpdateTime = currentTime
}

}

2 个答案:

答案 0 :(得分:2)

你拼错了这个功能。永远不会被召唤。这是正确的协议功能名称:

func didBegin(_ contact: SKPhysicsContact) {
  // Your stuff here..
}

您可以使用自动填充功能来避免此问题。开始输入&#34; didbegin&#34;你将让Xcode填写正确的函数:

enter image description here

暂且不说:

此外,您正在使用硬编码字符串,以后可能会导致问题。也许您可以尝试使用常量值或结构来避免字符串中可能出现的拼写错误:

let names = (cat: "cat", spinnynode: "spinnynode")

// cat.name = names.cat, etc...

func didBeginContact(contact:SKPhysicsContact){
  // ...
  if contact.bodyA.node?.name == names.cat
  {
    firstBody = contact.bodyA
    secondBody = contact.bodyB
  }
  else{
    firstBody = contact.bodyB
    secondBody = contact.bodyA
  }

  if firstBody.node?.name == names.cat && secondBody.node!.name == names.spinnynode {
    print("contacted")
  }
}

答案 1 :(得分:0)

您是否尝试过使用SKPhysicsContactDelegate的categoryBitMask方法?您可以通过进入GameScene.sks文件并将Category Mask分配给默认值以外的数字来解决您的问题。为您的两个实体执行此操作,但为每个实体指定不同的值。 example blocks showing category mask identification number other than default

然后,在你的GameScene.swift中,你的didBegin联系人函数可能如下所示:

class GameScene: SKScene, SKPhysicsContactDelegate {

//set these values to the same number in your GameScene.sks file
let catCategory = 2
let skinnyNodeCategory = 3

func didBegin(_ contact: SKPhysicsContact) {

    let bodyA = contact.bodyA
    let bodyB = contact.bodyB

    //check to see if the bodies in contact match
    //the category mask numbers you defined
    //here the conditional is set to say that either of the bodies
    //in contact match the categoryBitMask number set in the GameScene.sks file

    //using && may not work depending on how the categoryBitMask identifiers 
    //are assigned by the physicsContactDelegate

    if bodyA.categoryBitMask == catCategory || bodyB.categoryBitMask == catCategory {

        print("contacted")

        }
    }
}


override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
}
}

enter image description here