Как обнаружить пересечение SCNPhysics между двумя GKEntities (узлами SCN) в GKComponent для в SceneKit - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь обнаружить пересечение двух узлов в SceneKit.Они зарегистрированы как GKEntities.Я хочу связать компонент с обоими объектами, которые будут обнаруживать пересечение их физических тел, используя SCNPhysicsContactDelegate, но я не хочу делать это в контроллере представления, поскольку я знаю, что это не лучшая практика, и это затруднит регистрациюэто как компонент.Буду признателен за любую помощь.

Спасибо за помощь,

Montreaux

import Foundation
import SpriteKit
import GameplayKit
import SceneKit

class MeleeComponent: GKComponent, SCNPhysicsContactDelegate {

 let damage: CGFloat
 let destroySelf: Bool
 let damageRate: CGFloat
 var lastDamageTime: TimeInterval
 let aoe: Bool
 //  let sound: SKAction
   let entityManager: EntityManager
   init(damage: CGFloat, destroySelf: Bool, damageRate: CGFloat, aoe:      Bool, entityManager: EntityManager) {
 self.damage = damage
self.destroySelf = destroySelf
self.damageRate = damageRate
self.aoe = aoe
 //    self.sound = sound
self.lastDamageTime = 0
self.entityManager = entityManager
super.init()
 }

 required init?(coder aDecoder: NSCoder) {
     fatalError("init(coder:) has not been implemented")
}


 override func update(deltaTime seconds: TimeInterval) {

super.update(deltaTime: seconds)

// Get required components
guard let teamComponent = entity?.component(ofType: TeamComponent.self),
          let spriteComponent = entity?.component(ofType: SpriteComponent.self) else {
  return
}

// Loop through enemy entities
var aoeDamageCaused = false
let enemyEntities = entityManager.entitiesForTeam(teamComponent.team.oppositeTeam())
for enemyEntity in enemyEntities {

  // Get required components
  guard let enemySpriteComponent = enemyEntity.component(ofType: SpriteComponent.self),
        let enemyHealthComponent = enemyEntity.component(ofType: HealthComponent.self) else {
    continue
  }

  // Check for intersection

  if       (spriteComponent.node.frame.intersects(enemySpriteComponent.node.frame)) {

    // Check damage rate
    if (CGFloat(CACurrentMediaTime() - lastDamageTime) > damageRate) {

      // Cause damage
//          spriteComponent.node.parent?.run(sound)
      if (aoe) {
        aoeDamageCaused = true
      } else {
        lastDamageTime = CACurrentMediaTime()
      }

      // Subtract health
      enemyHealthComponent.takeDamage(damage)

      // Destroy self
      if destroySelf {
        entityManager.remove(entity!)
      }
    }
  }
}

if (aoeDamageCaused) {
  lastDamageTime = CACurrentMediaTime()
}

}}

1 Ответ

0 голосов
/ 03 февраля 2019

В SCNPhysicsWorld есть несколько API, которые могут вам помочь.

, например

 func contactTestBetween(_ bodyA: SCNPhysicsBody, _ bodyB: SCNPhysicsBody, options: [SCNPhysicsWorld.TestOption : Any]? = nil) -> [SCNPhysicsContact]

Это похоже на код в вашем примере:

if  (spriteComponent.node.frame.intersects(enemySpriteComponent.node.frame))

Но он есть в SceneKit и даст вам больше информации о контакте.

...