2017-04-21 3 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 
} 

또한 플레이어와 앵커 포인트의 높이에 대한 처리도해야합니다. 그렇지 않으면 앵커 포인트가 (0,0)이고 플레이어가 플랫폼 중간에있는 경우 물리가 적용되고 바람직하지 않은 결과가 발생합니다.

SpriteKit - 스위프트 3 코드 :

+0

매번 물리 치료사를 만드는 대신 collisionBitMask 만 사용하면 어떨까요? – BadgerBadger

+0

전에도 해봤지만 전 몸 전체를 더 잘 보았습니다. 또한 이와 같은 시나리오에는 대개 contactTest, collision, mass 등의 여러 값을 변경해야합니다. 이렇게하면이 모든 것을 해결할 수 있습니다. – TheValyreanGroup

+0

그런 일을하면 다른 것에 대한 충돌을 망칠 것입니다. 적군이 거기를 걷는다면 어떨까요? 플레이어의 통과로 떨어질 것입니다. 그것을하는 더 간단한 방법이 있어야합니다. 함수에 값 변경을 동봉하십시오. 그것은 또한 cpu 능률적 일 것이다. – BadgerBadger

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

관련 문제