2017-04-21 201 views
0

我試圖解決一個問題,一個精靈節點可以跳過一個平臺,但不能跳回來。我嘗試使用這個代碼:打開和關閉物理

override func didMove(to view: SKView) { 
    if (thePlayer.position.y > stonePlatform1.position.y) == true { 
     stonePlatform1.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: stonePlatform.size.width * 0.9, height: stonePlatform.size.height * 0.75)) 
     stonePlatform1.physicsBody!.isDynamic = false 
     stonePlatform1.physicsBody!.affectedByGravity = false 
     stonePlatform1.physicsBody!.categoryBitMask = BodyType.object.rawValue 
     stonePlatform1.physicsBody!.contactTestBitMask = BodyType.object.rawValue 
     stonePlatform1.physicsBody!.restitution = 0.4 
    } 
} 

這個想法是當玩家在平臺上方時打開平臺的物理體。然而,當我使用這個代碼時,物理學根本不起作用。事實上,我嘗試使用此代碼:

override func didMove(to view: SKView) { 
    if (thePlayer.position.y < stonePlatform1.position.y) == true { 
     stonePlatform1.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: stonePlatform.size.width * 0.9, height: stonePlatform.size.height * 0.75)) 
     stonePlatform1.physicsBody!.isDynamic = false 
     stonePlatform1.physicsBody!.affectedByGravity = false 
     stonePlatform1.physicsBody!.categoryBitMask = BodyType.object.rawValue 
     stonePlatform1.physicsBody!.contactTestBitMask = BodyType.object.rawValue 
     stonePlatform1.physicsBody!.restitution = 0.4 
    } 
} 

並且物理無法打開。如果IF語句不存在,那麼物理學一直都在工作。

回答

0

你可以嘗試從物理體開始,如nil,然後在玩家高於它之後設置物理值。此外,這種代碼應該在更新功能。讓它在didMove中只讓它調用一次。

override func update(_ currentTime: TimeInterval){ 
if (thePlayer.position.y < stonePlatform1.position.y) && stonePlatform1.physicsBody != nil { 
     stonePlatform1.physicsBody = nil 
}else if (thePlayer.position.y > stonePlatform1.position.y) && stonePlatform1.physicsBody == nil{ 
    setPhysicsOnPlatform(stonePlatform1) 
} 
} 

func setPhysicsOnPlatform(_ platform: SKSpriteNode){ 
    platform.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: stonePlatform.size.width * 0.9, height: stonePlatform.size.height * 0.75)) 
    ... 
    //the rest of your physics settings 
} 

你也應該做一些處理玩家的高度和你的anchorPoint。否則,如果您的anchorPoint是(0,0)並且玩家在平臺的中途,物理將會被應用並且會出現不希望的結果。

+0

爲什麼不簡單地使用collisionBitMask而不是每次重新創建物理體呢? – BadgerBadger

+0

我之前也做過這個,但我總是最好看看整個身體。此外,像這樣的場景通常需要改變多個值,例如contactTest,碰撞,質量等。這樣做解決了所有這些問題。 – TheValyreanGroup

+0

這樣做會破壞別的東西的碰撞。如果敵人在那裏行走會怎樣?它會隨着玩家的傳球而下降。必須有一個更簡單的方法來做到這一點。只需將函數中的值更改即可。這也會更有效率。 – BadgerBadger

3

您可以使用節點速度這個平臺,就像這樣:

SpriteKit - 斯威夫特3碼:https://github.com/Maetschl/SpriteKitExamples/tree/master/PlatformTest

的例子表明這一點:與這裏的例子

private var up1 : SKSpriteNode! 
private var down1 : SKSpriteNode! 
private var down2 : SKSpriteNode! 
private var player : SKSpriteNode! 

override func didMove(to view: SKView) { 
    up1 = self.childNode(withName: "up1") as! SKSpriteNode 
    down1 = self.childNode(withName: "down1") as! SKSpriteNode 
    down2 = self.childNode(withName: "down2") as! SKSpriteNode 
    player = self.childNode(withName: "player") as! SKSpriteNode 
    up1.physicsBody?.categoryBitMask = 0b0001 // Mask for UoPlatforms 
    down1.physicsBody?.categoryBitMask = 0b0010 // Mask for downPlatforms 
    down2.physicsBody?.categoryBitMask = 0b0010 // Same mask 
} 

override func update(_ currentTime: TimeInterval) { 
    player.physicsBody?.collisionBitMask = 0b0000 // Reset the mask 

    // For UP only Platform 
    if (player.physicsBody?.velocity.dy)! < CGFloat(0.0) { 
     player.physicsBody?.collisionBitMask |= 0b0001 // The pipe | operator adds the mask by binary operations 
    } 

    // For Down only platforms 
    if (player.physicsBody?.velocity.dy)! > CGFloat(0.0) { 
     player.physicsBody?.collisionBitMask |= 0b0010 // The pipe | operator adds the mask by binary operations 
    } 

} 

源代碼如下: 綠色平臺 - >僅羽絨服 紅色平臺 - >只供參考

enter image description here

+0

不是一個錯誤的解決方案,但它不能解決當塊停止在另一個塊內移動時會發生什麼問題 –

+1

加1僅適用於'| | ='。太棒了。 – TheValyreanGroup

+0

@PierreCourpron帶有這個實現,它被平臺外的引擎推送。你在尋找什麼行爲? – Maetschl