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

  • 6
    いいね
  • 0
    コメント

はじめに

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

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

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

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

画面遷移

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

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

}

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

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のコードを見ると改善されてますが、それでも不完全でしたので僕は以下のようにして対応しました。

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];
            }
        }
    }
}

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

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)

これはこちらのリンクの通りで、以下の対応をすればワーニングが出なくなります。

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です。

最後に

僕は最近偽りの物語というゲームを作りました。
その資産を使いたいので、今回はこのまま突き進む事にしました。

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

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

ss_3.png

TownSoft

僕はTownSoftという屋号で仕事をしていますので、何かあればご連絡ください。