1

現在ゲームを作成しており、 Gameplaykitを使用して要素を整理し たいと考えています。

ECS (エンティティ コンポーネント システム) の概念を発見しました。これにより、機能をエンティティに追加してエンティティに追加できる小さなブロック (コンポーネントと呼ばれます) に機能を配置できます。

SpriteKit と組み合わせて使用​​したいのですが、私の最初のアイデアはもちろん SpriteComponent を作成することでしたが、SpriteKit の物理エンジンも使用しているため、PhysicsBodyComponent をどのように作成すればよいか疑問に思っています。 SpriteKit ノードの物理本体に直接アクセスする必要があるため、SpriteComponent に依存しますが、コンポーネントが相互に依存するのは間違っていませんか?
どうすればいいですか?

ありがとうございました。

4

1 に答える 1

2

コンポーネントをどのように構築するかによって異なります。あなたが言ったように、それらを柔軟で再利用可能にし、可能な限り互いに独立させておくのが最善です。

したがって、必要に応じて単純なレンダリング コンポーネントを作成するだけです。これは私がゲームで使用するものです。

 import SpriteKit
 import GameplayKit

 /// GK sprite component
 class SpriteComponent: GKComponent {

     // MARK: - Properties

     /// The rendered node
     let node: SKSpriteNode

     // MARK: GKComponent Life Cycle

     /// Init with image
     init(imageNamed: String) {
         node = SKSpriteNode(imageNamed: imageNamed)
     }

     /// Init with texture
     init(texture: SKTexture) {
         node = SKSpriteNode(texture: texture)
     }
 }

エンティティ クラスでは、通常どおりコンポーネントを追加します

 class Player: GKEntity {

     override init() { // pass in an image name if you need to
        super.init()

        let spriteComponent = SpriteComponent(imageNamed: "Player")
        addComponent(spriteComponent)
     }
 }

エンティティをシーンに追加して配置します。コンポーネントがエンティティに追加されると、 component(ofType: ...) メソッドを使用してそのプロパティ (この場合はノード プロパティ) にアクセスし、それらを操作できます。

 class GameScene: SKScene {

     // code to add entity to scene
     ...

     // position entity 
     if let playerNode = player.component(ofType: SpriteComponent.self)?.node {
        playerNode.position = CGPoint(...)
    }

スプライト コンポーネントを追加した後、エンティティ クラスに戻り、物理ボディを追加します。

 ... 
 addComponent(spriteComponent)

 // Set physics body
 if let sprite = component(ofType: SpriteComponent.self)?.node { // component for class is an optional and nil until component is added to entity.
      sprite.physicsBody = SKPhysicsBody(...
      sprite.physicsBody?.categoryBitMask = ...
      ...
 }

このように、すべてのエンティティが 1 つのレンダー コンポーネントを使用できますが、異なる物理ボディを持ち、異なる位置を使用できます。

物理ボディ コンポーネントを作成し、ビット マスクなどとそれを追加するノードを init メソッドに渡すことができます。しかし、それはかなり厄介だと思うので、私はこの方法を好みます。

コンポーネントを相互に依存させる必要がある場合は、各 GKComponent に使用できるエンティティ プロパティがあることを覚えておいてください。コンポーネントの柔軟性を維持するために、これを可能な限り回避しようとします。

  class SomeComponent: GKComponent {

      func test() {
         entity?.component(ofType: SomeOtherComponent.self)?.someMethod() // only works if this component  is added to entity (entity?) and the other component is also added to entity (...self)?.

       }

  class SomeOtherComponent: GKComponent {

      func someMethod() {

      }
  }

さらに情報が必要な場合は、これらの記事を読む必要があります。非常に優れています。

https://www.raywenderlich.com/119959/gameplaykit-tutorial-entity-component-system-agents-goals-behaviors

http://code.tutsplus.com/tutorials/an-introduction-to-gameplaykit-part-1--cms-24483

お役に立てれば

于 2016-09-07T15:38:41.477 に答える