Cocos2d v3 SpriteBuilderで作ったオブジェクトをシミュレータに表示する


# 前回まで
* [SpriteBuilderの導入](http://qiita.com/syou007/items/9e6202a88495757dda5f)
* [SpriteBuilderでできたものの確認](http://qiita.com/syou007/items/1cd8b0d2deeb5acd38f1)
* [CocoaPodsのインストール](http://qiita.com/syou007/items/957dd2d9c3ff1b2a7c6d)
* [SpriteBuilderとXCodeで画面遷移する](http://qiita.com/syou007/items/9bebb01aff70dec0e3f3)
* [SpriteBuilderとSwiftのコンポーネント接続、様々なアニメーションについて](http://qiita.com/syou007/items/1c1a2b450cc93098495c)
* [SpriteBuilderでアニメーションを作る](http://qiita.com/syou007/items/bdcd3921a033ed967016)

これらを行いました。

# 今回のゴール
気球を画面上部から降らせます。

## 今回作るゲーム
今回はバルーンショットというゲームを作成する予定です。
もともと僕が作っている

![id995207358.png](https://qiita-image-store.s3.amazonaws.com/0/79216/c0a0da78-4bac-2257-9a1d-0594e953ba1e.png)
[Space Debris](https://itunes.apple.com/jp/app/id995207358)
というゲームの続編になります。

これをやっていただければどんなゲームを作ろうとしているか想像がつくかと思います。

# 気球を表示させてみます。
前回作成したものをXCodeへPublishします。
実際の気球を表示します。
GameSceneのコードを以下のようにします。

```swift:GameScene.swift
    func didLoadFromCCB() {
        let balloonNode = CCBReader.load("Parts/BalloonNode")
        balloonNode.position.x = self.contentSizeInPoints.width / 2
        balloonNode.position.y = self.contentSizeInPoints.height / 2
        
        self.addChild(balloonNode)
    }
```

画面中央に表示させたいので`self.contentSizeInPoints`から計算して表示させたかったのですが、、、


## 実際はこうなる
![1.png](https://qiita-image-store.s3.amazonaws.com/0/79216/1bcec2e1-dc6e-875c-cbe2-80bedaf01cc1.png "1.png")


なぜか左下の方に表示されてしまいました。

かろうじてアニメーションができている事は分かりますが、気球は予想外の場所に表示されてています。
これは`didLoadFromCCB時`には自分自身のサイズが決まっていないためこのような事が起こっているのです。

## self.contentSizeとself.contentSizeInPoints
self.contentSizeは「%」か「Point」の単位に合わせた値が取得できるので座標計算には向いてません。
現在の座標を取得するためにCocos2dは`***InPoints`というメソッドを用意してくれているので座標計算をしたい場合は`***InPoints`を使う方がいいでしょう。

# 気球を中央に表示させます。
では、どうすれば良いのでしょうか？
今回の例では、付与するCCNodeと画面サイズが同じです。
これを利用して座標計算をします。

Cocos2dはOpenGLを使用しているので、おそらく内部的には`CAEAGLLayer`をCocoaの`UIView`に付与して`EAGLContext`にDrawしていると思います。（未調査）
なので、大元のUIViewとレンダリングしている`CAEAGLLayer`のサイズは同じはずです。
大元のUIViewの取得は

```swift
CCDirector.sharedDirector().view
```

で取得できます。

なので、上記のコードを以下のようにします。

```swift:GameScene.swift
    func didLoadFromCCB() {
        let balloonNode = CCBReader.load("Parts/BalloonNode")
        balloonNode.position.x = CCDirector.sharedDirector().view.frame.size.width / 2
        balloonNode.position.y = CCDirector.sharedDirector().view.frame.size.height / 2
        balloonNode.scale = 0.5
        
        self.addChild(balloonNode)
    }
```
表示される場所を画面の中央にして、大きさを半分にします。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/79216/f0473844-5a98-d6ee-3ea5-ba982db51319.png "2.png")

背景が黒くて分かりませんね。
背景の色を青に変えて、もう不要となった[SpriteBuilderとSwiftのコンポーネント接続、様々なアニメーションについて](http://qiita.com/syou007/items/1c1a2b450cc93098495c)で追加したLabelTTFを削除します。

その結果以下のようになります。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/79216/9050736e-cd18-70cf-139e-52732ac2c336.png "3.png")
背景をただの青にするとつまらないからグラデーションを入れました。

中央に配置しているはずなのに、若干下に表示されています。
それは`Anchor point`が(0.5, 0.7)になっているからです。
[前回](http://qiita.com/syou007/items/bdcd3921a033ed967016#anchor-point%E3%81%A3%E3%81%A6%E3%81%AA%E3%81%AB)書いたように`Position`の指定は`Anchor point`に依存します。
ここでは、そのままとしておいてください。

# 物理エンジンを追加します。
さて`SpriteBuilder`に戻ります。
このままでは画面中央やや下あたりで気球が揺れているだけで面白くありません。
せっかくなので、気球を落としてみましょう！

物理エンジンを使うためには`CCPhysicsNode`を使用します。
この`CCPhysicsNode`の配下に配置したノードは物理エンジンの恩恵に授かれるようになります。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/79216/b1a5c14c-ae7d-33c5-eb3f-3a686444f3af.png "4.png")
まずは、画面のようにGameSceneに`CCPhysicsNode`を配置します。
その後、画面サイズ全体をカバーするように右上の画面を見て、`Position`と`Content Size`を合わせます。

![5.png](https://qiita-image-store.s3.amazonaws.com/0/79216/69d6a3a6-71b5-049b-c033-9b463865600b.png "5.png")
次に重力の方向と強さを設定します。
ここではXはそのままにして`Y`を`-10.0`くらいに変更します。

配置した`CCPhysicsNode`にアクセスできるように名前をつけておきます。

![6.png](https://qiita-image-store.s3.amazonaws.com/0/79216/aef1b566-aec8-55e2-d7ad-6c0e6a80d943.png "6.png")

これでGameSceneの設定は終了です。
次は気球が重力を受けるように変更します。

## balloonNodeを変更
![7.png](https://qiita-image-store.s3.amazonaws.com/0/79216/9e34bcad-21c6-9fdb-670f-3d66c41dd639.png "7.png")
上記の画面のように一番上の`CCNode`に対して、右上の`Enable Physics`にチェックを入れます。

これで気球が物理エンジンの効果を受けれるようになります。

![8.png](https://qiita-image-store.s3.amazonaws.com/0/79216/ce1e41da-9e71-536a-ca77-392b39a7e433.png "8.png")
チェックを入れた直後の状態はこうなってます。
`CCPhysicsNode`について詳しく知りたい方は[こちらのリファレンス](http://cocos2d.spritebuilder.com/docs/api/Classes/CCPhysicsBody.html)を参照ください。

# Swiftの世界に戻ります。
先ほど変更をしたものをPublishしてください。
そして、先ほどのプログラムを下記のように書き換えます。

```swift:GameScene.swift
class GameScene: CCNode {
    // 物理ノード
    weak var _physicsNode:CCPhysicsNode!
    
    // 画面が生成後に同期で呼び出される。
    func didLoadFromCCB() {
        // バルーンを呼び出す
        let balloonNode = CCBReader.load("Parts/BalloonNode")
        balloonNode.position.x = CCDirector.sharedDirector().view.frame.size.width / 2
        balloonNode.position.y = CCDirector.sharedDirector().view.frame.size.height
        balloonNode.scale = 0.3
        
        // 物理ノードにバルーンを設置
        _physicsNode.addChild(balloonNode)
    }
}
```

今まではGameSceneに気球を配置してましたが、今度は`_physicsNode`に配置します。
これで気球が重力の影響を受ける事ができるようになります。

実際に起動してみて気球が落ちていく様子をみてください。
また、重力を変更してみて気球の落ちる様子を色々変えてみましょう！

# 次回は
気球をランダムに落としていきます。
だんだんゲームっぽくなっていきますよ！
[気球をランダムに落とす](http://qiita.com/syou007/items/9b7e98afa6afd602f7f7)

# このゲームもよろしくお願いいたします。
![id995207358.png](https://qiita-image-store.s3.amazonaws.com/0/79216/c0a0da78-4bac-2257-9a1d-0594e953ba1e.png)
[Space Debris](https://itunes.apple.com/jp/app/id995207358)
気軽に楽しめると思うので、ぜひよろしくお願いいたします！