SpriteBuilderを使ってみる


### SpriteBuilderって何？

* cocos2dのUIデザインをGUIを使って簡単に作れるツール
* CocosBuilderの後継
* Apportableが主導で開発

ApportableはObjective-C→Android変換を実現してくれるツール

### ダウンロード

最近MacAppStoreにリリースした模様。
[SpriteBuilder](https://itunes.apple.com/us/app/spritebuilder/id784912885?mt=12)

### プロジェクト作成

ツールバーから File → New → Project
SpriteBuilderTest.spritebuilder なんて名前で作ってみた

ディレクトリ構成を見てみる。

```
SpriteBuilderTest.spritebuilder
├── Source
├── SpriteBuilder Resources
├── SpriteBuilderTest.approj
├── SpriteBuilderTest.xcodeproj
└── build
```

* Source 

Xcodeプロジェクトの中身がはいってます。
このディレクトリの中に
Resources/Published-iOS
の中にSpriteBuilderから出力した内容が書き込まれる。


* SpriteBuilderTest.approj

Apportable用の設定ファイル
configuration.jsonは開発者側がいじる事になる。
JSON形式になっていて、サンプルも書き込まれてるので簡単。

```
    // "APPLICATION_IDENTIFIER": "",
	"APPLICATOIN_IDENTIFIER": "com.example.appname",
```

こんな風に書き換えればAndroid版のパッケージ名などを指定できる。
Apportableはこのconfiguration.jsonを見て
AndroidManifest.xmlなどを自動生成してくれる。

* SpriteBuilder Resources

ここにあるものはSpriteBuilder側で使用するものになる。
SpriteBuilder側で出力を行うとPublished-*** に出力される。
(デフォルト設定なので、読み込み先、出力先は好きに変更可)

### 実践

実際にSpriteBuilderを少しだけいじってみる。
基本はCocosBuilderと同じなので
使っていた事のある人は、特に迷わないと思う。


![spritebuilder_01.png](https://qiita-image-store.s3.amazonaws.com/0/31990/b8de6c0f-cd32-e0e5-4fbf-2f8d096d135b.png "spritebuilder_01.png")

最初はこんな画面だと思う。

簡単なコードとの繋ぎ込みをしてみる。
左ペインにある箱のようなボタンを押すと追加できるノード群が表示される。
Buttonを画面上にドラッグする。

コマンド+1、2、3を押すと
iPhone4inch, iPad, iPhone3.5inchの見え方が確認できる。
ボタンがアクティブな状態で右ペインをいじってみる。

Positionの右2つボタンを押すと%に変えられるので
x:50% y:20%くらいにしておく。
どの端末でも似たような表示で再現できてるはず。

そのまま右ペインにある右矢印マークを押すと
CustomClassとCCControlが表示される。

CCControlのセレクターに「touchButton:」とでも入れておく。
Targetを`Document root`に

![SpriteBuilder_02.png](https://qiita-image-store.s3.amazonaws.com/0/31990/2f06296b-55d1-e39b-8241-a009b8ac895c.png "SpriteBuilder_02.png")

この場合のDocument rootは
下ペインのツリーの中の頂点の「CCNode」になる。

CCNodeをクリックしてみて、右ペインを確認すると
CustomClassが「MainScene」になっているはず。

なので、この場合ボタンを押すと
MainSceneクラスの -(void)touchButton:(id)sender;
というメソッドが呼ばれる。

ここらで保存してPublishしとく。
Cmd+Opt+SでPublish

### コードと連携

SpriteBuilderで生成されたxcodeprojを開く。

既に空のMainSceneが存在してるはず。

```objc:MainScene.m
#import "MainScene.h"

@implementation MainScene

- (void)didLoadFromCCB
{
    CCLOG(@"LOG: %@: %@", NSStringFromSelector(_cmd), self);
}

- (void)touchButton:(id)sender
{
    CCLOG(@"Touch");
}

@end
```

didLoadFromCCBは今回特に使わないけど
CCBIファイルの読み込み完了後に呼び出されるので
そこそこ使うと思われ。

これだけじゃアレなので
アニメーション実行もしてみる。

SpriteBuilderのツールバーで
Animation → Edit Timelines
既にDefault Timelineがあると思う。
Autoplayにチェックがはいっているので
ccbi読み込み完了時にこのタイムラインは自動実行される。
新しくタイムラインを作って「Rotate」としてみた。

![SpriteBuilder_03.png](https://qiita-image-store.s3.amazonaws.com/0/31990/c51645a9-1904-8cc5-259d-c94e99cf0fc8.png "SpriteBuilder_03.png")

下ペインの再生ボタンなどの下に
Default Timelineという表記があると思うのでクリックすると
他のタイムラインへ変更などができる。

Rotateに変更する。
SpriteBuilderというCCLabelTTFを1回転させるだけの
アニメーションを設定。

CCLabelTTFを選択した状態で
「R」を押すと、タイムラインの選択している部分に
Rotationのキーフレームがセットされる。
0.0, 0.5, 1.0にキーフレームを挿入して
0 180 360と値を入れて1回転させる。
Duration自体も合わせる事でコードでコールバックを受けやすくなるので
アニメーション時間と同じ時間にしておく。
アニメーションの時間はタイムライン名をクリックして
Set Timeline Durationか右の方にある時間をクリックで変更できる。

![SpriteBuilder_04.png](https://qiita-image-store.s3.amazonaws.com/0/31990/d7020bab-d49b-f19c-3903-0d6515f72eb8.png "SpriteBuilder_04.png")

この状態でPublishして再度Xcodeに戻る。

```objc:MainScene.m
@interface MainScene ()

@property (nonatomic, weak) CCBAnimationManager *animationManager;

@end

@implementation MainScene

- (void)didLoadFromCCB
{
    CCLOG(@"LOG: %@: %@", NSStringFromSelector(_cmd), self);
    
    self.animationManager = self.userObject;
}

- (void)touchButton:(id)sender
{
    CCLOG(@"Touch");
    
    [self.animationManager runAnimationsForSequenceNamed:@"Rotate"];
}

@end
```

didLoadFromCCBで行っている事は
MainScene.ccbiファイルのタイムラインの情報がuserObjectに格納されているので
CCBAnimationManagerに渡してあげてます。

`self.animationManager = self.userObject;`

これを行うのはdidLoadFromCCB内が最適でしょう。

後はボタンがタッチされた時にRotateタイムラインを呼び出しているだけです。

アニメーションの終了通知を受けたい場合は
`CCBAnimationManagerDelegate`を使う。

```objc:MainScene.m
@interface MainScene () <CCBAnimationManagerDelegate>

@property (nonatomic, weak) CCBAnimationManager *animationManager;

@end

@implementation MainScene

- (void)didLoadFromCCB
{
    CCLOG(@"LOG: %@: %@", NSStringFromSelector(_cmd), self);
    
    self.animationManager = self.userObject;
    self.animationManager.delegate = self;
}

- (void)touchButton:(id)sender
{
    CCLOG(@"Touch");
    
    [self.animationManager runAnimationsForSequenceNamed:@"Rotate"];
}

#pragma mark - CCBAnimationManagerDelegate

- (void)completedAnimationSequenceNamed:(NSString *)name
{
    CCLOG(@"%@ end", name);
}

```

アニメーション終了後に`Rotate end`とログ出力されればOK
もし表示されない場合はデリゲートのセットやら
タイムラインの時間調整をしていない(10秒のまま)とかだと思われる。

### Apportable

実際Apportableの情報は少ないと思うけどどう使うの？

インストールは簡単なので大雑把にして省く。

* 会員登録
* 書かれている curlコマンドをコピペしてターミナルで実行
* ~/.apportable ここに本体ができる AndroidNDK、SDKなども包括されている。
* Apportableにパスを通す (curl終了後に案内出る)
* *.xcodeprojがあるディレクトリにターミナルで移動する
* Android実機をUSBで繋いでおく。
* apportable load とコマンドを打つ

基本はこれだけです。
apk生成されて、実機にインスコされて起動します。

~/.apportable/SDK/Buildらへんに生成されたapkがあるはず。


### バグ

SpriteBuilder1.0.2

```objc:AppDelegate.m
    NSMutableDictionary* cocos2dSetup = [NSMutableDictionary dictionaryWithContentsOfFile:[[CCFileUtils sharedFileUtils] fullPathFromRelativePath:@"configCocos2d.plist"]];
```
GitHub見てみたら既にコミットされていたけど
configCocos2d.plistファイルを読み込めていないとか。