3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-06-02

前回まで

これらを行いました。

今回のゴール

気球を画面上部から降らせます。

今回作るゲーム

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

id995207358.png
Space Debris
というゲームの続編になります。

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

気球を表示させてみます。

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

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

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

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

self.contentSizeとself.contentSizeInPoints

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

気球を中央に表示させます。

では、どうすれば良いのでしょうか?
今回の例では、付与するCCNodeと画面サイズが同じです。
これを利用して座標計算をします。

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

CCDirector.sharedDirector().view

で取得できます。

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

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

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

その結果以下のようになります。
3.png
背景をただの青にするとつまらないからグラデーションを入れました。

中央に配置しているはずなのに、若干下に表示されています。
それはAnchor pointが(0.5, 0.7)になっているからです。
前回書いたようにPositionの指定はAnchor pointに依存します。
ここでは、そのままとしておいてください。

物理エンジンを追加します。

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

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

4.png
まずは、画面のようにGameSceneにCCPhysicsNodeを配置します。
その後、画面サイズ全体をカバーするように右上の画面を見て、PositionContent Sizeを合わせます。

5.png
次に重力の方向と強さを設定します。
ここではXはそのままにしてY-10.0くらいに変更します。

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

6.png

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

balloonNodeを変更

7.png
上記の画面のように一番上のCCNodeに対して、右上のEnable Physicsにチェックを入れます。

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

8.png
チェックを入れた直後の状態はこうなってます。
CCPhysicsNodeについて詳しく知りたい方はこちらのリファレンスを参照ください。

Swiftの世界に戻ります。

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

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に配置します。
これで気球が重力の影響を受ける事ができるようになります。

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

次回は

気球をランダムに落としていきます。
だんだんゲームっぽくなっていきますよ!
気球をランダムに落とす

このゲームもよろしくお願いいたします。

id995207358.png
Space Debris
気軽に楽しめると思うので、ぜひよろしくお願いいたします!

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?