2015-01-15 7 views
5
func didBeginContact(contact: SKPhysicsContact) { 
    if (contact.bodyA.categoryBitMask & BodyType.shield.rawValue) == BodyType.shield.rawValue { 
     contact.bodyB.node?.removeFromParent() 
     counter++ 
     println(counter) 


    } else if (contact.bodyB.categoryBitMask & BodyType.shield.rawValue) == BodyType.shield.rawValue { 
     contact.bodyA.node?.removeFromParent() 
     counter++ 
     println(counter) 
    } 
} 

한 물리학 몸 텍스처에서입니다 같은 SKPhysicsBody에 대한 여러 번 호출되는 shield.physicsBody = SKPhysicsBody(texture: shieldTexture, size: shieldTexture.size()) 다른 하나는 원 sand.physicsBody = SKPhysicsBody(circleOfRadius: sand.size.width/2) didBeginContact는

견인 때때로 sand.physicsBody = SKPhysicsBody(circleOfRadius: sand.size.width/2) 가 호출되는 서로 접촉을 객체에서입니다

여러 번. 접촉하는 즉시 부모로부터 제거하더라도 각 객체에 대해 한 번만 호출되도록하는 방법은 무엇입니까?

+2

텍스처의 본문이 내부적으로 여러 모양을 생성 할 수 있으므로 각각이 연락처 이벤트를 유발할 수 있으므로 의도 한대로 작동한다고 생각합니다. 노드를 제거해도 물리 시뮬레이션 단계가 끝날 때까지는 본문이 제거되지 않습니다. 노드 또는 본문을이 연락처 이벤트에서 처리 된 것으로 수동으로 "표시"하여 동일한 본문의 후속 연락처 이벤트를 건너 뛸 수 있도록해야합니다. – LearnCocos2D

+0

SKPhysicsBody가 텍스처를 통해 매개 변수를 통해 설정할 수있는 옵션이 있었기를 바랍니다. circleOfRadius의 SKPhysicsBody는 하나의 히트/접촉 만 계산합니다. 아래의 답변을 포함하여 추가 논리를 만드는 것보다 훨씬 많은 경우가 있습니다. 또한 필요하지 않은 경우 더 많은 연락처를 검색하지 못하도록 리소스를 절약 할 수 있습니다. –

답변

2

나는 한 번만 func didBeginContact(contact: SKPhysicsContact)을 얻는 방법을 알아 냈습니다. 이렇게하면 실제 텍스처 몸체의 본질 때문에이 함수가 여러 번 호출 되더라도 텍스처가있는 물리 구조체 SKPhysicsBody(texture: size:)이 충돌을 한 번 계산할 수 있습니다.

1 단계 :

가 SKSpriteNode의 이름 속성을 작성합니다 (이 예를 들어 공을 사용합니다) 을 고유 이름이 동일하게 설정.

var number = 0 

ball.name = "ball \(number)" 

이렇게하면 개체가 만들어지는 고유 한 이름이 허용됩니다.

2 단계 :

수를 증가, 배열에 공을 추가, 다음을 보유하는 배열을 생성

var array: [String] = [] 
    var number = 0 

ball.name = "ball \(number)" 
array.append(ball.name!) 
number ++ 

3 단계 : 이름이있는 경우 지금 func didBeginContact(contact: SKPhysicsContact)에서 찾을 수 정렬. 점수를 증가 시키려면 노드를 제거하고 배열에서 이름을 제거하십시오. 이름이 배열에 없으면 아무 것도하지 않습니다.

배열에서 이름을 제거하면 함수 호출을 한 번만 계산할 수 있습니다. 우리가 SKPhysicsBody(texture:xxx, size:xx)에서 허용되는 형태는 다양한 형태와 모양에 올 수 있기 때문에 LearnCocos2D이 옳다

func didBeginContact(contact: SKPhysicsContact) { 
    if (contact.bodyA.categoryBitMask & BodyType.shield.rawValue) == BodyType.shield.rawValue { 
     var name = contact.bodyB.node?.name! 
     let index = find(array, name!) 

     if contains(array, name!) { 
      score++ 
      contact.bodyB.node?.removeFromParent() 
      array.removeAtIndex(index!) 
     } 
    } 
} 
+1

SKSpriteNode를 배열에 추가 할 수 없습니까? 우리는 그들을 비교할 수 있도록 참조로 전달 되었기 때문에 왜 고유 한 이름을 할당해야하는지 알지 못합니다. – 3366784

0

, SKPhysicsbody didBeginContact는 두 개체의 SKphysicsbody으로 연속 한 호출이 접촉하고있다.

한 번만 탐지해야하는 사람들에게 탐지가 완료되었는지 확인하기 위해 플래그로 부울을 사용해야합니다.

  1. var 부울 선언 : 여기

    내가 그것을 어떻게

    var contactDone = Bool() 
    
  2. 프로그램의 시작을 초기화를 (예를 들어,

    contactDone = false 
    
  3. ) didMoveToView 아래 didBeginContact에서 검사를 수행

    func didBeginContact(contact:SKPhysicsBody){ 
    
    if((contact.bodyA.categoryBitMask) == scoreCategory ||  (contact.bodyB.categoryBitMask) == scoreCategory){ 
    
         if (contactDone == false){ 
    
         // Increment score   
         score++ 
    
         // Set flag to disable multiple calls by checking in didEndContact 
         contactDone = true 
    
         } 
    } 
    } 
    
  4. 지우기 플래그를이 didEndContact 다시 확인할 수 있도록 :

    func didEndContact(contact: SKPhysicsContact) { 
    
    if((contact.bodyA.categoryBitMask) == scoreCategory || (contact.bodyB.categoryBitMask) == scoreCategory){ 
    
          if(contactDone == true){ 
    
           contactDone = false 
    
          } 
    
    } 
    
    } 
    

그것은 단지처럼 일 내가 SKPhysicBody(circleOfRadius: object.size.height/2)을 사용했을 때 그랬습니다.

+0

'SKPhysicsBody (texture : ghostTexture, size : Obj.size)'를 사용할 때 작동하지 않습니다. – Danny182

0

이 경우 배열없이 작동시킬 수 있습니다. 대신이의이 같은

contact.bodyA.node?.removeFromParent() 
counter++ 

사용 무언가 :

if let node = contact.bodyA.node as? SKSpriteNode { 
    if node.parent != nil { 
     node.removeFromParent() 
     counter++ 
    } 
} 

첫 번째 연락처에 당신은 생략 될 경우 문에서 후속 호출에, 부모의 코드를 노드를 제거합니다.

1

contactbitmask을 사용하여 캡처 할 충돌을 결정하는 경우 매우 간단한 해결책이 있습니다.

반복적으로 감지하지 않으려는 객체의 categoryBitMask을 사용되지 않는 새 값으로 업데이트하면 더 이상 관련된 후속 함수 호출을 더 이상 고려하지 않습니다.