性懲りも無くSpriteBuilderを使っている方へ

## はじめに
この記事を見た方。
多分、僕と同じで古臭い技術を使っている方でしょう。

本当なら`cocos2d-x`や`Unity`などで開発をしたいところが、`Swift`を使いたいからなどで`SpriteBuilder`を使っているかと思います。
※他の技術を覚えるのが面倒という方もいると思いますが・・・w
（もはや`Unity`の一人勝ちの気もしてますが・・・。残念です。）

僕個人的には`SpriteBuilder`はかなり名器だと思っているのですが、スポンサーが抜けたためか更新は止まりAppStoreからも削除されました。
非常に残念です。

僕も現在作っているゲームを最後に`SpriteBuilder`をやめる事にしますが、今回は無理やり使おうと思います。
その際に問題となる箇所をここに記載しておきます。

## 画面遷移
iOS9・・・というか、`Capitan`から以下のコードが落ちるようになりました。
（xCodeのバージョンのせいかもしれない。とにかく最新だと落ちます。）

```objc:CCTransition.m
-(void)draw:(CCRenderer *)renderer transform:(const GLKMatrix4 *)transform
{
    typedef id (*Func)(id, SEL);
    ((Func)objc_msgSend)(self, _drawSelector);
    
}
```

この箇所は以下のように書き換えると動きます。

```objc:CCTransition.m
-(void)draw:(CCRenderer *)renderer transform:(const GLKMatrix4 *)transform
{
//	typedef id (*Func)(id, SEL);
//	((Func)objc_msgSend)(self, _drawSelector);
    
    void (*Func)(id, SEL) = (void(*)(id, SEL)) objc_msgSend;
    Func(self, _drawSelector);
}
```

## 日本語対応
iOS9より`[NSLocale preferredLanguages]`の戻り値が変わります。
そのため独自で言語管理をしていたサービスは軒並み`英語`になったり、落ちたりしてます。
（ファイナルファンタジーなどのメジャーどころですら、対応に手間取っていたのを知っている方もいるでしょう。）

`SpriteBuilder`も同様です。
最新の`Cococs2d`のコードを見ると改善されてますが、それでも不完全でしたので僕は以下のようにして対応しました。

```objc:Source/libs/cocos2d-iphone/cocos2d-ui/CCBReader/CCBLocalizationManager.m
- (void) loadStringsFile:(NSString*) file
{
    // Load default localization dictionary
    NSString* path = [[CCFileUtils sharedFileUtils] fullPathForFilename:file];
    
    // Load strings file
    NSDictionary* ser = [NSDictionary dictionaryWithContentsOfFile:path];
    
    // Check that format of file is correct
    NSAssert([[ser objectForKey:@"fileType"] isEqualToString:@"SpriteBuilderTranslations"], @"Invalid file format for SpriteBuilder localizations");
    
    // Check that file version is correct
    NSAssert([[ser objectForKey:@"fileVersion"] intValue] == 1, @"Translation file version is incompatible with this reader");
    
    // Load available languages
    NSArray* languages = [ser objectForKey:@"activeLanguages"];
    
    // Determine which language to use
    NSString* userLanguage = NULL;
    
    NSArray* preferredLangs = [NSLocale preferredLanguages];
    for (NSString* preferredLang in preferredLangs)
    {
        if ([languages containsObject:preferredLang])
        {
            userLanguage = preferredLang;
            break;
        }
    }
    
    // Create dictionary for translations
    _translations = [[NSMutableDictionary alloc] init];
    
    // Load translations
    if (userLanguage != NULL)
    {
        NSArray* translations = [ser objectForKey:@"translations"];
        
        for (NSDictionary* translation in translations)
        {
            NSString* key = [translation objectForKey:@"key"];
            NSString* value = [(NSDictionary*)[translation objectForKey:@"translations"] objectForKey:userLanguage];
            
            if (key != NULL && value != NULL)
            {
                [_translations setObject:value forKey:key];
            }
        }
    }
}
```

このメソッドを以下のように変更します。

```objc:Source/libs/cocos2d-iphone/cocos2d-ui/CCBReader/CCBLocalizationManager.m
- (void) loadStringsFile:(NSString*) file
{
    // Load default localization dictionary
    NSString* path = [[CCFileUtils sharedFileUtils] fullPathForFilename:file];
    
    // Load strings file
    NSDictionary* ser = [NSDictionary dictionaryWithContentsOfFile:path];
    
    // Check that format of file is correct
    NSAssert([[ser objectForKey:@"fileType"] isEqualToString:@"SpriteBuilderTranslations"], @"Invalid file format for SpriteBuilder localizations");
    
    // Check that file version is correct
    NSAssert([[ser objectForKey:@"fileVersion"] intValue] == 1, @"Translation file version is incompatible with this reader");
    
    // Load available languages
    NSArray* languages = [ser objectForKey:@"activeLanguages"];
    
    // Determine which language to use
    NSString* userLanguage = NULL;
    
    NSArray* preferredLangs = [NSLocale preferredLanguages];
    for (NSString* preferredLang in preferredLangs)
    {
        // now loop thru languages from our cocosbuilder
        for (NSString *localizedLanguage in languages)
        {
            // doing range of string as we might have en-GB set in our phone and that will match our en from the activeLanguages
            if ([preferredLang rangeOfString:localizedLanguage].location != NSNotFound)
            {
                userLanguage = localizedLanguage;
                break;
            }
        }
        
        if (userLanguage != NULL) {
            break;
        }
    }
    
    // Create dictionary for translations
    _translations = [[NSMutableDictionary alloc] init];
    
    // Load translations
    if (userLanguage != NULL)
    {
        NSArray* translations = [ser objectForKey:@"translations"];
        
        for (NSDictionary* translation in translations)
        {
            NSString* key = [translation objectForKey:@"key"];
            NSString* value = [(NSDictionary*)[translation objectForKey:@"translations"] objectForKey:userLanguage];
            
            if (key != NULL && value != NULL)
            {
                [_translations setObject:value forKey:key];
            }
        }
    }
}
```

これで`SpriteBuilder`で言語管理ができるようになります。

## ワーニング
とにかくワーニングがひたすら出ます。
以下のワーニングが30個くらい出てきます。

```
ld: warning: object file (/.../Build/Products/Debug-iphonesimulator/libcocos2d.a(IOSVersion.o)) was built for newer iOS version (9.3) than being linked (8.0)
```

これは[こちら](http://forum.cocos2d-objc.org/t/xcode7-warnings/17609)のリンクの通りで、以下の対応をすればワーニングが出なくなります。

```
The culprit is the minimum deployment target for the ObjectAL library - 
In Xcode delve into the cocos2d project -> external -> ObjectAL project: 
Goto build settings and search for 'deployment target' 
and set the value to be <= your main project minimum deployment target.
```

上記の通りで

「cocos2d project -> external -> ObjectAL」のフォルダをたどってから「build settings」を表示します。
その中の「deployment target」を自分のプロジェクトに合わせた最小ターゲットにすればOKです。


## 最後に
僕は最近[偽りの物語](https://itunes.apple.com/jp/app/id1084085985)というゲームを作りました。
その資産を使いたいので、今回はこのまま突き進む事にしました。

なので、この記事では困ったことをここに追記していこうと思っています。
同じ`SpriteBuilder`で困っている方は是非ストック＆コメントお願いします。
数少ない`SpriteBuilder`を使っている同志同士で頑張りましょう！w

ちなみに偽りの物語のスクリーンショットはこんな感じです。
よければ、遊んでください♪

![ss_3.png](https://qiita-image-store.s3.amazonaws.com/0/79216/24ebf7ca-e9bb-2fab-1eed-839670890f2a.png)

## TownSoft
僕は[TownSoft](http://townsoft.jp)という屋号で仕事をしていますので、何かあればご連絡ください。