前回まで
今回のゴール
今回は少し横道に逸れます。
SpriteBuilderで配置したコンポーネントの扱いについて記載します。
今回の内容は本編とは関係がなく、SpriteBuilderで配置したコンポーネントを扱いたいという内容をピンポイントで知りたい方のために書いております。
また、余った時間でCCAction
を使った簡単なアニメーションをしてみます。
今回作るゲーム
今回はバルーンショットというゲームを作成する予定です。
もともと僕が作っている
Space Debris
というゲームの続編になります。
これをやっていただければどんなゲームを作ろうとしているか想像がつくかと思います。
GameSceneのクラス名をつけます
前回を参考にして、GameScene.ccb
のCCNodeにGameScene
というCustom class
の名前をつけてください。
コンポーネントに名前をつけます
設定するのはcustom class
ではなくDoc root var
に付与してください。
今回SpriteBuilderで行うのはこれだけになります。
Sceneを格納するグループを作成します
強制することでは無いのですがグループを作る際には上記の図のようにフォルダを先に作ってドラッグすると
このようなダイアログボックスが表示されるのでCreate Groups
を選択してグループを作成する。
そうすると、このグループにクラスファイル等を追加するとデフォルトでドラッグしたフォルダに作制してれるようになります。
XCodeのグループは便利?
XCodeのグループは便利ですが、実際のフォルダと格納場所が違うため実ファイルを探す時に苦労します。
そういう時に困らないようにグループとフォルダをある程度合わせておくことをお勧めします。
クラスファイルはまだ良いのですが、大量のリソースファイル(画像とか)を管理する時はCreate folder references
で作成した方がプログラムコードからリソースを探しやすいです。
話が脱線してしまいますのでここでやめますが、XCodeのグループとはうまく付き合っていか無いと後々の保守性に関わってきます。(リクエストがあれば僕が遭遇したとんでもないプロジェクトについて書きます。)
GameSceneを作ります。
先ほど作成したグループにクラスを作成します。
継承元はCCNode
にしてください。
Cocos2dではCCNode
が全ての基底となってます。CocoaでいうUIView
と同じポジションにあります。
ちなみにCocoaでいうUIViewController
に相当するものはCocos2dにはありません。CCNode
が両方の役割を担ってます。
SpriteBuilderで作成するファイルのScene
もLayer
もCCNode
も全てSwiftではCCNode
として扱います。
CCLayer
などは存在しません。(CCScene
は存在しますが使う必要はないでしょう。SpriteBuilderが作成したMainSceneもCCNode
を継承して作成されてます。)
文字を変えてみます。
GameSceneの中身を書き換えます。(import文は不要なので決して問題ありません。)
class GameScene: CCNode {
// この変数にSpriteBuilderで作成したコンポーネントが差し込まれる。
weak var _testLabel:CCLabelTTF!
// 画面が生成後に同期で呼び出される。
func didLoadFromCCB() {
_testLabel.string = "置きかわる!"
}
}
実行してみると、SpriteBuilderで作成したLabelの中身が置き換わっている事がわかると思います。
_testLabel
は冒頭にSpriteBuilder
で接続をした変数名で繋がってます。(weakキーワードがついている理由はこの記事を読んでください。weakを知らない方は必読です!)
didLoadFromCCB
はSpriteBulderで設定したコンポーネント全てが挿入された後に呼び出します。
GameSceneを作成する際に
CCBReader.loadAsScene("GameScene")
このようなコードを書いた事を覚えてますか?
これを誤って以下のように書いてしまうと何もないCCNodeが生成されてします
GameScene()
つまりloadAsScene
がGameScene
を生成してSpriteBuilderで設定したコンポーネントを挿入している事がわかると思います。
おまけ
せっかくなので色々な事をしてみましょう。
傾ける
func didLoadFromCCB() {
_testLabel.rotation = 30.0 // 30度傾ける。
}
大きくする。
func didLoadFromCCB() {
_testLabel.scale = 2.0 // 2倍
}
2秒かけて傾ける
func didLoadFromCCB() {
_testLabel.runAction(CCActionRotateTo(duration: 2.0, angle: 30.0))
}
Cocos2dのアニメーションは秀逸です。
CCActionを継承しているクラスを対象のCCNodeのrunAction
に引き渡すだけでアニメーションが発生します。
(CCActionクラスは使いまわせないので、各CCNodeに同じ動作をさせたい場合はその分CCActionのインスタンスを作成する必要があります。)
2秒かけて2倍の大きさにする。
func didLoadFromCCB() {
let action = CCActionScaleBy(duration: 2.0, scale: 2.0)
_testLabel.runAction(action)
}
actionを別の変数に入れて生成した例です。
CCActionの最後にTo
やBy
が付いているものがありますが、これは英語の意味そのままで
-
To
・・・現在の状態に関わらず、その状態に変化する。 -
By
・・・現在の状態からその状態に変化する。
よくわからない人は以下のコードを実行すればすぐに意味がわかると思います。
func didLoadFromCCB() {
_testLabel.scale = 2.0
let action = CCActionScaleBy(duration: 2.0, scale: 2.0)
_testLabel.runAction(action)
}
func didLoadFromCCB() {
_testLabel.scale = 2.0
let action = CCActionScaleTo(duration: 2.0, scale: 2.0)
_testLabel.runAction(action)
}
同時にActionを行う
func didLoadFromCCB() {
let action1 = CCActionScaleTo(duration: 2.0, scale: 2.0)
let action2 = CCActionRotateTo(duration: 2.0, angle: 30.0)
_testLabel.runAction(action1)
_testLabel.runAction(action2)
}
このようにrunAction
を複数呼び出す事で同時に複数のアクションを実行させる事ができます。
また、以下のようにCCActionをまとめる事もできます。
func didLoadFromCCB() {
let action1 = CCActionScaleTo(duration: 2.0, scale: 2.0)
let action2 = CCActionRotateTo(duration: 2.0, angle: 30.0)
let action = CCActionSpawn(array: [action1, action2])
_testLabel.runAction(action)
}
動作は同じようになります。
順番にアクションを行う。
func didLoadFromCCB() {
let action1 = CCActionScaleTo(duration: 2.0, scale: 2.0)
let action2 = CCActionRotateTo(duration: 2.0, angle: 30.0)
let action = CCActionSequence(array: [action1, action2])
_testLabel.runAction(action)
}
ここまでくれば説明しなくても十分かと思います。
アクションを止める。
上記で作成したCCAction
を保持する事で
_testLabel.stopAction(action)
このようにしてアクションを止めれます。
アクションの一時停止
_testLabel.paused = true
などと記載すれば一時的にアクションを停止できます。
次回は
SpriteBuilderでアニメーションを作る手順をご説明します。
その素材をちょっと探してきます。。。気球と気球にぶら下がってるもの・・・。うーん。