2016-09-20 4 views
4

Это первый вопрос, который я написал в стеке. Я использую Xcode 7.3.1, iOS 9.3 и Swift 2. Также тестировал непосредственно на симуляторе и моем iPad. Я провел многочисленные поиски, прочитал 2 книги по физике Spritekit и просмотрел многочисленные видеоуроки, а также написанные. Я уже писал физику тела без проблем, и много раз с меньшими проектами, но этот просто не дает мне обратной связи. Этот вопрос задавался здесь раньше в конкретных случаях, т. Е. 2 ​​столкновения с одним и тем же спритоном или какая разница между collisionBitMask и contactTestBitMask. Я знаю о различиях и также знаю, что каждому объекту, с которым вы хотите связаться, нужна категорияBitMask. Во-первых, я назначил глобальную структуру Physicalbody (попробовал прямое бинарное битовое маска и соответствующий Int32, соответствующий каждому без успеха ни с одним), физический делегат и каждый SKSpritenode соответствует его парным контактам/s. Я пробовал множество способов реализовать didBeginContact (относительно того, как он структурирован), ни одна из них не изменила другой.
Раньше я упомянул отзыв. Я уничтожил всех, кроме моего основного игрока, пули, newEnemy и врага. Когда я пытаюсь даже распечатать результат контакта или столкновения с консолью, это похоже на то, что он даже не читается. У меня нет активности. Эти spritenodes находятся в пределах 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. –

+0

Это так, как я полагал, что didBeginContact даже не срабатывает. Физика работает, делегат находится на своем месте. Даже если у меня не было контактов, он все равно должен срабатывать. Имеет ли место размещение функции в коде?Для меня это никогда не было. Даже используя view? .showsPhysics = true, я могу видеть в своем симуляторе, какие объекты имеют физику. –

ответ

6

Проблема, с которой вы сталкиваетесь, заключается в том, что все ваши физические тела нединамичны. Для их динамического свойства установлено значение false. Метод didBeginContact будет вызываться только в том случае, если хотя бы одно из тел является динамическим.

От docs:

Динамическое свойство определяет, является ли тело моделируется подсистемой физики.

Так что нединамические тела, конечно, исключены из моделирования. Я не могу найти, если есть где-то документально, что это относится к контактам, но, по моему опыту, я довольно уверен, что контакты не будут работать между двумя статическими телами.

Надеюсь, это поможет.

+0

Это сработало! Я изменил все динамические свойства на TRUE, и вся моя печать на консолях исчезла, как лесной пожар! Я думал, что раньше пытался это сделать, но, должно быть, был на другом спринтоде. Я реализую код для своих контактов и вижу реакции. Ты понятия не имеешь, как долго я ломаю голову над этим ... Спасибо, спасибо, спасибо! –

+0

@ABoynton Нет проблем, рад слышать, что это сработало :) Между тем, загляните в раздел справки, чтобы узнать [что вы должны делать, когда кто-то отвечает на ваш вопрос] (http://stackoverflow.com/help/someone- ответы) и узнать больше о том, как работает этот сайт. И добро пожаловать в StackOverflow :) – Whirlwind

+1

@Whirlwind вы правы, если я правильно помню, глядя на источник Box2D, столкновение и контакт запускаются через одни и те же функции, сначала происходит контакт, установка некоторого флага и обработка кода столкновения. Это было некоторое время назад, я смотрел на это, хотя и не уверен, изменился ли он, или какая версия Box2D используется. – Knight0fDragon

Смежные вопросы