2014-09-19 6 views
4

이것이 Xcode의 이상한 버그인지 또는 이해가 안되는 SpriteKit 좌표 시스템에 대한 것이 있는지 모르겠습니다.SpriteKit & Swift : didBeginContact를 통해 노드를 만들면 위치가 엉망입니다.

노드의 위치는 항상 부모와 관련이 있다는 전제가 있습니다. 그러나 SKPhysicsContactDelegate의 "didBeginContact"에서 물리 본문을 가진 노드를 생성하고 배치하는 블록을 호출 할 때마다 노드는 항상 부모 노드 대신 장면에 상대적으로 배치됩니다. 이 블록을 호출하면 "didBeginContact"가 아닌 다른 곳으로 트리거 될 때 의도 한대로 작동합니다. 또 다른 한가지는, 노드의 물리 구조를 제거하면 "didBeginContact"에서 호출 된 경우에도 의도 한대로 블록이 작동한다는 것입니다.

저는이 문제로 2 일 동안 고생했습니다. 실제 코드에 대한 다른 세부 정보를 제공하기에는 너무 어려울 것입니다. 그래서 나는이 변칙을 보여주는 아주 간단한 프로젝트를 만들었습니다. Spritekit 템플릿을 사용하여 Xcode 6에 새 프로젝트를 만들고 GameViewController.swift 및 GameSwift.swift를 아래에 게시 된 코드로 대체하십시오. iPad Air에서 실행하면 다른 모든 것은 설명이 필요합니다.

마지막 주 :

  1. 첫 번째 버튼을 누르면 두 번째 버튼에 접촉 할 때, 화면의 왼쪽 하단을 확인합니다. 상자가 "잘못 배치"되어있는 것을 으로 보게됩니다.
  2. "AddBox"에서 물리 구조 상자를 제거해보십시오. 이제 의도 한대로 작동합니다.

    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 :

  3. 이 버그라고 생각하거나 내가

GameViewController.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

저는 물리학 자의 좌표가 월드 공간에 있다는 것을 알고 있지만 여기에는 (?) 관련이 없어야합니다 ... – Emiel

+0

이것이 Xcode의 버그라고 말씀해 주시겠습니까? – Donn

답변

2

Apple Bug Report와 관련하여이 문제에 관한 티켓을 제출했습니다. 나는 이것이 동일한 문제를 겪고있는 누구에게나 도움이되기를 바랍니다. 여기에 자신의 반응이다 :

애플 개발자 Relations24 9 월 2014 오전 4시 40분

엔지니어링이 다음에 따라 를 해결하는에 대한 문제가 있음을 확인했습니다 : 당신이 할 수있는

을 시뮬레이션중인 트리를 수정하면 프로그래밍 가이드에 명시된 입니다.

1

연락처 위임자 (이것은 AndEngine과 같은 다른 엔진과 비슷합니다)에서 물리 기관을 만들 수없는 것 같습니다. 대리인으로 새로운 몸을 똑바로 세우는 대신에 거기에 bool 플래그를 표시하고 didSimulatePhysics 또는 didFinishUpdate에서 작성하십시오 - 나를 위해 일합니다.

관련 문제