SKPhysicsContact正文,无法改变属性

时间:2017-05-26 10:23:06

标签: swift sprite-kit skphysicsbody skphysicscontact

我在didBegin(contact:)中发射了一个SpriteKit物理接触点。我抓住了想要在屏幕外移动的Dot对象实例的物理体,但是当我试图改变它的位置时,没有任何反应:

第一种方法

/* In GameScene.swift */

func didBegin(_ contact: SKPhysicsContact) {
    let dotBody: SKPhysicsBody
    if contact.bodyA.categoryBitMask == 0b1 {
        dotBody = contact.bodyB
    } else {
        dotBody = contact.bodyA
    }

    if let dot = dotBody.node as? Dot {
        dot.position.x = 10000
    }
}

但是,如果我在Dot类中调用一个方法,传入该body,则位置设置正确:

第二种方法

/* In GameScene.swift */

func didBegin(_ contact: SKPhysicsContact) {
    let dotBody: SKPhysicsBody
    if contact.bodyA.categoryBitMask == 0b1 {
        dotBody = contact.bodyB
    } else {
        dotBody = contact.bodyA
    }

    if let dot = dotBody.node as? Dot {
        dot.move()
    }        
}

这是Dot类:

import SpriteKit
class Dot : SKSpriteNode {
    let dotTex = SKTexture(imageNamed: "dot")
    init() {
        super.init(texture: dotTex, color: .clear, size: dotTex.size())
        self.physicsBody = SKPhysicsBody(circleOfRadius: size.width / 2)
        self.physicsBody?.categoryBitMask = 0b1 << 1
        self.physicsBody?.contactTestBitMask = 0b1
    }

    func move() {
        let reset = SKAction.run {
            self.position.x = 10000
        }
        self.run(reset)
    }

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

任何人都可以解释为什么第二种方法中的位置变化有效但是在我的第一种方法中它不起作用吗?

这里是link to the project on Github

2 个答案:

答案 0 :(得分:1)

编辑:

我认为这是因为您正在创建SKSpriteNode的子类而不是创建SKSpriteNode的实例。除非你打算把它专门用于其他事情,否则我没有理由这样做。相反,我使用了这些

import Foundation
import SpriteKit

class Dot {

let dotSprite: SKSpriteNode

init() {
    dotSprite = SKSpriteNode(imageNamed: "Spaceship")
//        dotSprite.physicsBody = SKPhysicsBody(circleOfRadius: dotSprite.size.width/2)
//        dotSprite.physicsBody?.categoryBitMask = 0b1 << 1
//        dotSprite.physicsBody?.contactTestBitMask = 0b1

}

func move() {
    self.dotSprite.position.x = 0
}

func moveAnim(){
    let reset = SKAction.moveTo(x: 0, duration: 3)
    dotSprite.run(reset)
}

}

在我的SKScene中

import SpriteKit
import GameplayKit

class GameScene: SKScene {

let newDot = Dot()


override func didMove(to view: SKView) {

    self.addChild(newDot.dotSprite)
    newDot.dotSprite.setScale(0.5)
    newDot.dotSprite.position = CGPoint(x: frame.midX, y: frame.midY)

}


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

    newDot.dotSprite.position.x = 200
    newDot.moveAnim()

}

}

请注意,我已禁用物理身体因为我没有创建另一个身体让它着陆(所以它会继续下降)。我还用太空船作为精灵。

所以现在你可以在dot类中拥有任何自定义方法。你也可以直接操作点SpriteNode的属性。还可以创建多个实例。现在,您可以在联系发生时直接更改它,或者调用点类中的方法来移动。 希望这有用。 :)

答案 1 :(得分:1)

func didBegin(_ contact: SKPhysicsContact) {
  let hitDot = contact.bodyB.node! as! SKSpriteNode
  let hitDot1 = contact.bodyA.node! as! SKSpriteNode
    if hitDot.name? == "dot" || hitDot1.name? == "dot" {
       reset = true
    }        
}

   override func update(_ currentTime: TimeInterval) {
    if reset {
        newDot.position.x = 0
        reset = false
    }
}

我刚刚编辑的代码中可能存在小错误。但希望这能给你带来这个想法。这应该没有错误。