我不知道这是否是Xcode中的一个奇怪的错误,或者有些关于SpriteKit的坐标系我不明白。
前提是节点的位置始终相对于其父节点。但是,每当我调用一个块来创建和定位一个带有来自SKPhysicsContactDelegate的“didBeginContact”的物理体的节点时,该节点总是相对于场景(而不是它的父节点)定位。请注意,除了“didBeginContact”之外,在触发任何地方时调用此相同的块都可以正常工作。另一件事是,如果我删除所述节点的物理主体,即使从“didBeginContact”调用,该块现在也可以正常工作。
我已经坚持这个问题两天了,如果提供有关我实际代码的其他详细信息,那就太过于拖延了。所以我做了一个非常简单的项目来证明这种异常现象。只需使用Spritekit模板在Xcode 6中创建一个新项目,并将GameViewController.swift和GameSwift.swift替换为下面发布的代码。只需在iPad Air中运行,其他一切都应该是自我解释的。
最后的笔记:
GameViewController.swift:
import SpriteKit
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let scene = GameScene()
scene.size = view.frame.size
let skView = self.view as SKView
scene.scaleMode = .AspectFill
skView.presentScene(scene)
}
}
GameScene.swift:
import SpriteKit
let kButtonSize = CGSize(width: 500, height: 100)
let kContainerSize = CGSize(width: 500, height: 300)
let kBoxSize = CGSize(width: 25, height: 25)
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMoveToView(view: SKView) {
physicsWorld.contactDelegate = self
addFirstButton()
addSecondButton()
addContainer()
}
func addFirstButton() {
let button = SKSpriteNode(color: SKColor.blueColor(), size: kButtonSize)
let label = SKLabelNode(text: "Call 'addBox' from didBeginContact")
button.name = "firstButton"
label.name = "firstLabel"
button.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))
button.physicsBody = SKPhysicsBody(rectangleOfSize: button.size)
button.physicsBody.allowsRotation = false
button.physicsBody.affectedByGravity = false
button.physicsBody.categoryBitMask = 0x1
button.physicsBody.contactTestBitMask = 0x1
button.addChild(label)
addChild(button)
}
func addSecondButton() {
let button = SKSpriteNode(color: SKColor.blueColor(), size: kButtonSize)
let label = SKLabelNode(text: "Call 'addBox' from touchesBegan")
button.name = "secondButton"
label.name = "secondLabel"
button.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame)-200)
button.physicsBody = SKPhysicsBody(rectangleOfSize: button.size)
button.physicsBody.dynamic = false
button.physicsBody.categoryBitMask = 0x1
button.physicsBody.contactTestBitMask = 0x1
button.addChild(label)
addChild(button)
}
func addContainer() {
let container = SKSpriteNode(color: SKColor.greenColor(), size:kContainerSize)
let label = SKLabelNode(text: "Created node should fall here")
label.fontColor = SKColor.blackColor()
container.name = "container"
container.physicsBody = SKPhysicsBody(edgeLoopFromRect: container.frame)
container.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame)+300)
container.addChild(label)
addChild(container)
}
func addBox() {
let container = childNodeWithName("container")
let box = SKSpriteNode(color: SKColor.blueColor(), size: kBoxSize)
box.physicsBody = SKPhysicsBody(rectangleOfSize: box.size)
box.position = CGPointMake(0, 100)
container.addChild(box)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let touch = touches.anyObject() as UITouch
let point = touch.locationInNode(self)
let node = nodeAtPoint(point)
if node.name == nil {return}
switch node.name! {
case "firstButton", "firstLabel":
let button = childNodeWithName("firstButton") as SKSpriteNode
button.physicsBody.applyImpulse(CGVectorMake(0, -500))
case "secondButton", "secondLabel":
addBox()
default:
break
}
}
func didBeginContact(contact: SKPhysicsContact!) {
addBox()
}
}
答案 0 :(得分:2)
我已经向Apple Bug Report报告了这个问题。我希望这可以帮助任何遇到同样问题的人。以下是他们的回复:
Apple Developer Relations 24-Sep-2014 04:40 AM
工程已确定这是您需要解决的问题 基于以下内容:
您无法修改正在模拟的树,这是 在编程指南中明确说明。
答案 1 :(得分:1)
您似乎无法在联系人委托中创建物理主体(这类似于其他引擎,例如AndEngine)。不要将新身体直接写入代表,在那里标记一些bool标志并在didSimulatePhysics或didFinishUpdate中进行创建 - 对我有效。