2017-06-14 19 views
3

我試圖利用init?(coder aDecoder:NSCoder)函數,以便我可以在sks文件中繼承sprites。使用所需的init(nscoder)設置物理主體代碼

我可以在sks文件中設置物理體,但是對於我使用的也有圓角的矩形精靈來說,它效果不佳。由於圓角,在使用init函數之前,我使用代碼設置了物理體,並將寬度設置爲略小於方形寬度(這樣,當我的英雄從方塊滑落時,沒有間隙圓角是..

我知道我可以使用阿爾法面具物理身體得到相同的影響,除了這個,當我的英雄是在塊,似乎有1 px'ish差距,並且它看起來並不好。

奇怪,爲什麼我不能設置物理體這種情況的原因,也是我該怎麼做,或圍繞它得到什麼?

感謝您的幫助!

更新:

required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
    if let p = userData?.value(forKey: "col") as? String { 
     setup(p) 
     print("working") 
    } 
} 
func setup(_ col: String) { 
    setupPhysics() 
    //allSprites.append(self) 

在setupPhysics我:

override func setupPhysics() { 
    physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: frame.width - 4, height: frame.height - 1)) 
...more code... 
} 

這是我對精靈的代碼,我有它正確地安裝在SKS文件...

我將allSprites的附錄註釋掉了,這樣我就可以證明它不起作用。隨着追加註釋掉,精靈被添加到allSprites,然後在場景文件我didMove功能,它遍歷allSprites和運行setupPhysics():

func setup(_ col: String) { 
    //setupPhysics() 
    allSprites.append(self) 

// scene file 
    func setupAllSpritesPhysics() { 
    for sprite in allSprites { sprite.setupPhysics() } 
} 

@ Knight0fDragon:

您提這是一個醜陋的修復。我不同意這個事實,即它不會以'正確'的方式工作。目前我沒有足夠的精靈來引起場景加載的任何滯後。如果情況確實如此,我可以在未來考慮這一點。

我承認我沒有嘗試過你提到的方法,因爲我不想爲每個創建的sprite創建一個子節點,以便即使它能夠正常工作。我欣賞目前爲止的建議。

+0

它會幫助你,如果你顯示一些更多的信息。如果英雄物理是在代碼中設置的,則顯示代碼或顯示圖像,以顯示當精靈進行交互時正在發生的事情。你可以提供的信息越容易找出你的問題。 –

+0

感謝您的評論,我目前沒有將我的電腦放在我面前,但是當我有機會時我會更新這個問題。我可以說,init函數正常工作並且工作,我只有1個init函數。在super.init被調用後調用設置物理的函數。我確實得到它太工作,使用完成關閉的等待skaction ...所以我認爲super.init需要更多的時間完成,但這似乎有點hacky ... – Discoveringmypath

+0

你甚至檢查,看看是否打印線正在發生 – Knight0fDragon

回答

4

爲了與SKS文件這項工作,我想補充一個孩子SKNode你想要的身體的尺寸,然後在自定義類的代碼,做

required init(coder aDecoder:NSCoder){ 
    super.init(coder:aDecoder) 
    if let child = childNode(withName:"child"), let physicsBody = child.physicsBody{ 
     self.physicsBody = physicsBody 
     child.removeFromParent() 
    } 
} 

我們在這裏做的是將物理體從小孩轉移到父母,然後殺死孩子。這使我們的代碼變得更加動態一些,並保持設計與功能的分離。

嗯,來自蘋果的漂亮的小蟲子。

發生的事情是在NSCoder發生的時候物理世界並不存在,而是在它存在的時候將附着在物體上的物理體放入世界中,它決定緩存位於SKS文件中的物體,這就是爲什麼它不起作用。

所以解決這個問題的一個非常方便的方法是實現一個worldNode(無論如何這是一個很好的做法,特別是如果你想創建一個暫停屏幕),只需刪除它,然後將其添加回sceneLoad:

class GameScene: SKScene,SKPhysicsContactDelegate { 
    lazy var worldNode : SKNode = { self.childNode(withName:"//worldNode")!}() 

    override func sceneDidLoad() { 
     worldNode.removeFromParent() 
     addChild(worldNode) 
    } 
} 
+0

感謝您的回覆。我將不得不嘗試這...我的印象是super.init需要更多時間才能完成設置物理主體,如果您閱讀我上面的評論...所以我有點懷疑這會起作用,但是誰知道......我最終確定了一個修補程序。我將所有我感興趣的精靈存儲在一個數組中......所以我在遊戲場景文件中添加了一個函數來循環訪問數組並運行設置物理。我在didmove函數結束時調用了函數,一切都很好......您如何看待這個解決方案? – Discoveringmypath

+0

沒有任何東西在後臺線程上運行,super.init完成後,你的精靈已經準備好了 – Knight0fDragon

+0

這是一個非常難看的解決方案,如果你有很多精靈,你最終會導致你的遊戲暫時凍結。 – Knight0fDragon