2016-09-20 10 views
4

이것은 제가 스택에 게시 한 첫 번째 질문입니다. Xcode 7.3.1, iOS 9.3 및 Swift 2를 사용하고 있습니다. 시뮬레이터와 iPad에서도 직접 테스트했습니다. 나는 수 많은 검색을 해왔고 Spritekit Physics 2 권을 읽었으며 수많은 비디오 튜토리얼과 글을 보았습니다. 나는 전에 문제없이 신체 물리학을 작성했고, 소규모 프로젝트는 여러 번 시도했지만이 것은 나에게 아무런 피드백도주지 않고있다. 이 질문은 이전에 특정 경우, 즉 동일한 스프라이트 노드로 2 번 충돌하거나 collisionBitMask와 contactTestBitMask 사이에 어떤 차이가 있는지에 대해 제기되었습니다. 나는 그 차이점을 알고 있고 당신이 접촉하기를 원하는 각각의 객체는 categoryBitMask가 필요하다는 것을 알고있다. 첫째, 전역 Physicsbody 구조체 (똑같은 이진 비트 마스크를 시도하고 둘 중 하나에도 성공하지 못하는 상응하는 Int32를 시도했습니다.), 물리 대리자 및 각 SKSpritenode는 쌍을 이루는 연락처/s와 일치합니다. didBeginContact (구조화 방식과 관련하여)를 구현하는 데 여러 가지 방법을 시도했지만 아무 것도 다른 것을 변경하지 않았습니다.
이전에 나는 의견을 언급했다. 내 메인 플레이어, 총알, 신인종 및 적을 제외하고 모두 제거했습니다. 접촉이나 충돌의 결과를 콘솔에 인쇄하려고해도 읽지 않는 것입니다. 나는 아무 활동도 얻지 않는다. 이 스프라이트 노드는 모두 1 클래스 (GameScene) 내에 있으며, 운이없는 각 함수 스프라이트 노드에 대해 별도의 클래스를 시도했습니다. 또한 별도의 클래스를 사용하면 클래스와 하위 클래스 간의 통신을위한 프로토콜을 사용하여 상황을 악화시키는 것으로 보입니다. 별도의 수업을 사용하는 것은 나에게 아직 새로운 것이지만, 그것이 선호되는 방법이라는 것을 알고 있습니다. 나는 내가 볼 필요가 있을지도 모른다고 생각하는 코드만을 보여줄 것이지만, 다른 것이 필요하다는 것을 알려주지 않으면 안된다. 나는 총알이 비행기에 부딪쳐서 거기에서 다른 물건으로 갈 수 있습니다. 내 물리 연락처가 SpriteKit에서 연락하지 않습니다.

import AVFoundation 
import SpriteKit 
import GameKit 

// Binary connections for collision and colliding 
struct PhysicsCategory { 
    static let GroundMask : UInt32 = 1 //0x1 << 0 
    static let BulletMask : UInt32 = 2 //0x1 << 1 
    static let PlayerMask : UInt32 = 4 //0x1 << 2 
    static let EnemyMask : UInt32 = 8 //0x1 << 3 
    static let EnemyFire : UInt32 = 16 //0x1 << 4 
    static let All  : UInt32 = UInt32.max // all nodes 
} 

class GameScene: SKScene, SKPhysicsContactDelegate { 

    // Starting scene, passed to didMoveToView 
    func startScene() { 

     // Sets the physics delegate and physics body 
     view?.showsPhysics = true 
     self.physicsWorld.gravity = CGVectorMake(0, 0) 
     self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame) 
     self.physicsWorld.contactDelegate = self // Physics delegate set 
    } 

    func setupPlayer() { 

     player = SKScene(fileNamed: "Player")!.childNodeWithName("player")! as! SKSpriteNode 

     // Body physics for player's planes 
     player.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "MyFokker2.png"), size: player.size) 
     player.physicsBody?.dynamic = false 
     player.physicsBody?.usesPreciseCollisionDetection = true 
     player.physicsBody?.categoryBitMask = PhysicsCategory.PlayerMask 
     player.physicsBody?.contactTestBitMask = PhysicsCategory.EnemyFire 
     player.physicsBody?.collisionBitMask = 0 

     player.removeFromParent() 
     self.addChild(player) // Add our player to the scene 
    } 

    // Create the ammo for our plane to fire 
    func fireBullets() { 

     bullet = SKSpriteNode(imageNamed: "fireBullet") 

     // Body physics for plane's bulets 
     bullet.physicsBody = SKPhysicsBody(rectangleOfSize: bullet.size) 
     bullet.physicsBody?.dynamic = false 
     bullet.physicsBody?.usesPreciseCollisionDetection = true 
     bullet.physicsBody?.categoryBitMask = PhysicsCategory.BulletMask 
     bullet.physicsBody?.contactTestBitMask = PhysicsCategory.EnemyMask 
     bullet.physicsBody?.collisionBitMask = 0 

     self.addChild(bullet) // Add bullet to the scene 
    } 

    func spawnEnemyPlanes() { 
     let enemy1 = SKScene(fileNamed: "Enemy1")!.childNodeWithName("enemy1")! as! SKSpriteNode 
     let enemy2 = SKScene(fileNamed: "Enemy2")!.childNodeWithName("enemy2")! as! SKSpriteNode 
     let enemy3 = SKScene(fileNamed: "Enemy3")!.childNodeWithName("enemy3")! as! SKSpriteNode 
     let enemy4 = SKScene(fileNamed: "Enemy4")!.childNodeWithName("enemy4")! as! SKSpriteNode 

     enemyPlanes = [enemy1, enemy2, enemy3, enemy4] 

     // Generate a random index 
     let randomIndex = Int(arc4random_uniform(UInt32(enemyPlanes.count))) 

     // Get a random enemy 
     newEnemy = (enemyPlanes[randomIndex]) 

     // Added randomEnemy's physics 
     newEnemy.physicsBody = SKPhysicsBody(rectangleOfSize: newEnemy.size) 
     newEnemy.physicsBody?.dynamic = false 
     newEnemy.physicsBody?.usesPreciseCollisionDetection = true 
     newEnemy.physicsBody?.categoryBitMask = PhysicsCategory.EnemyMask 
     newEnemy.physicsBody?.contactTestBitMask = PhysicsCategory.BulletMask 
     newEnemy.physicsBody?.collisionBitMask = 0 

     newEnemy.removeFromParent() 
     self.addChild(newEnemy) 
    } 

    func spawnEnemyFire() { 

     enemyFire = SKScene(fileNamed: "EnemyFire")!.childNodeWithName("bullet")! as! SKSpriteNode 

     enemyFire.removeFromParent() 
     self.addChild(enemyFire) // Generate enemy fire 

     // Added enemy's fire physics 
     enemyFire.physicsBody = SKPhysicsBody(rectangleOfSize: enemyFire.size) 
     enemyFire.physicsBody?.dynamic = false 
     enemyFire.physicsBody?.usesPreciseCollisionDetection = true 
     enemyFire.physicsBody?.categoryBitMask = PhysicsCategory.EnemyFire 
     enemyFire.physicsBody?.contactTestBitMask = PhysicsCategory.PlayerMask 
     enemyFire.physicsBody?.collisionBitMask = 0 
    } 

    func didBeginContact(contact: SKPhysicsContact) { 

     if !self.gamePaused && !self.gameOver { 

      // beginContact constants 
      firstBody = contact.bodyA 
      secondBody = contact.bodyB 

      if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) {  
       firstBody = contact.bodyA 
       secondBody = contact.bodyB 
      } else { 
       firstBody = contact.bodyB 
       secondBody = contact.bodyA 
      } 

      // Contact statements 
      if ((firstBody.categoryBitMask & PhysicsCategory.BulletMask != 0) && (secondBody.categoryBitMask & PhysicsCategory.EnemyMask != 0)) { 
       print("Bullet hit Enemy") 
      } 
      else if ((firstBody.categoryBitMask & PhysicsCategory.PlayerMask != 0) && (secondBody.categoryBitMask & PhysicsCategory.EnemyFire != 0)) { 
       print("EnemyFire hit our Player") 
      } 
     } 
    } 
} 

나는 아직이 긴 미안 경우 ... 알고있을 필요가 코드를 떠나 명백한 코드를 떠나야했습니다. 나는 checkPhysics 함수도 시도해 보았고 내 객체를 인식 할 수도 없다. 모든 SpriteNodes가 didMoveToView 함수에 전달됩니다. 누구나 무엇이 잘못되었는지를 볼 수 있습니까? 아니면 아무런 연락도받지 못하는 이유가 있습니까?

+0

어디에서 startScene() 메서드를 호출합니까? 나는 didMoveToView에서 추측한다. didBeginContact가 전혀 트리거됩니까? 해당 메서드의 맨 처음에 중단 점이나 인쇄 문을 넣어 실행 여부를 확인합니다. – Whirlwind

+0

내 startScene 함수가 didMoveToView 함수에서 호출됩니다. 게임을 다시 시작하는 데 사용했습니다. 마치 전혀 작동하지 않는 것처럼 보입니다. 내 didBeginContact 함수의 첫 번째 행으로 print 문을 시도 할 것이다. –

+0

didBeginContact가 실행되지 않는다고 믿었습니다. 물리학은 제자리에 있고 대의원은 제자리에 있습니다. 연락처를 설정하지 않아도 계속 트리거되어야합니다. 코드 내의 함수 배치가 중요합니까?그것은 나를 위해 결코 전에있다. 뷰? .showsPhysics = true를 사용해도 내 시뮬레이터에서 어떤 오브젝트에 물리가 있는지 확인할 수 있습니다. –

답변

6

당신이 가진 문제는 모든 물리 구조가 비 동적이기 때문입니다. 동적 속성이 false으로 설정되어 있음을 의미합니다. didBeginContact 메서드는 적어도 하나의 본문이 동적 인 경우에만 호출됩니다. docs 가입일

:

동적 속성은 본체가 물리 서브 시스템 시뮬레이션의 여부를 판정

.

그래서 동적이지 않은 바디는 시뮬레이션에서 제외됩니다. 이것이 연락처에 적용된다고 문서화되어있는 것을 발견 할 수는 없지만, 내 경험에 비추어 볼 때, 두 개의 정적 인 몸 사이에서 접촉이 이루어지지 않을 것이라는 점은 매우 긍정적입니다.

희망이 도움이됩니다.

+0

그것은 일했다! 모든 동적 속성을 TRUE로 변경했으며 콘솔에 대한 모든 인쇄물이 산불처럼 떨어졌습니다 !! 나는 이전에 그것을 시도했지만 다른 spritenode에 있었음에 틀림 없다고 생각했습니다. 내 연락처에 몇 가지 코드를 구현하고 반응을 볼 것입니다. 너는 얼마나 오래 내가 이걸로 머리를 쥐고 있었는지 모른다. 고마워, 고마워, 고마워! –

+0

@ABoynton 아무 문제 없어, 듣기 좋게 :) 그 사이에 도움 섹션으로 들어 와서 [누군가 당신의 질문에 대답 할 때 무엇을해야하는지 알아보십시오] (http://stackoverflow.com/help/someone- 답변)이 사이트의 작동 방식에 대해 자세히 알아보십시오. 그리고 StackOverflow에 오신 것을 환영합니다 :) – Whirlwind

+1

@Whirlwind 당신이 옳았는지, Box2D 소스를 볼 때, 충돌과 접촉은 동일한 함수를 통해, 연락처가 먼저 일어나고, 플래그가 몇 개 설정되고, 충돌 코드를 처리 한 후에 올바르게 기억됩니다. 이것은 얼마 전에 나는 이것을 보았습니다. 그래서 그것이 바뀌 었는지, 또는 어떤 버전의 Box2D 사과가 사용하고 있는지 확실하지 않았습니다. – Knight0fDragon