【無料セール】コンサート開催記念:iOS/Android版プリンキピア 360円→無料 セールを行います!!

来たる2019年3月2日(土)、PRINCIPIA: Master of Science(プリンキピア:マスター・オブ・サイエンス)で使用されている曲を弦楽四重奏の生演奏で聴くことができるコンサートPRINCIPIA: Master of Science String Quartet Concert Music by Daisuke SHIIBAが開催されることになりました!!

作曲者の椎葉大翼さんのインタビューが掲載された記事はこちら↓

あのゲームでおなじみ!? 元任天堂のサウンドクリエイター 椎葉大翼さんのゲーム楽曲コンサートが開催 – Nintendo DREAM WEB

そしてコンサート開催を記念して、

2/20(水)23:59 までの3日間限定で、プリンキピアiOS/Android版アプリの無料セール(通常360円)を実施します!!

(※iOS版は2/17 19時ごろから、Android版は2/18 0:00から)

気になってはいたけどまだ購入されていなかった方、こんなアプリ初めて聞いたという方、この機会にとりあえずダウンロードされてみてはいかがでしょうか!!

PRINCIPIA: Master of Science (プリンキピア:マスター・オブ・サイエンス)

mos

価格: 360 円 無料!!(2019年2月20日(水)23:59 まで)

badge-download-on-the-app-store0  en_badge_web_generic

 

アプリの音楽室(音楽モード)では、収録されている6曲が最初から全て聴くことができるので、事前に予習しておくとコンサートがより一層楽しめると思います。

というか、

とりあえず今のうちにアプリを無料でダウンロードし、[オプション]→[音楽室]から曲(弦楽四重奏のスタジオ生録音)を聞いてみてください!!

コンサートはプリンキピアの他にも「でっかわ彼女」「エコノミシティ」「From_.」「サリーの法則」「World for Two」等のに使用されている椎葉さんの曲も全て生演奏で聴くことができるという贅沢な内容です。

これだけ贅沢な内容なので、前売り券はすでに完売していてもおかしくないと思うのですが、2/17(日)18:00時点でまだ(奇跡的に)空席が若干残っているそうです。

これを見て興味を持たれた方は是非公式サイトを覗いてみてください!!

公式サイト

ちなみに筆者も「プリンキピア開発者」として少しだけ登壇させていただき、各曲についてのエピソードなどについてお話しさせていただく予定です。(あくまで予定です)


アプリストアに必要なスクリーンショットをリサイズで一気に作成するコマンド

こんにちは。

前回アプリを公開したとき(2015年4月)に使った小技ですので、いま有効かどうか未確認ですが、サイズの異なるスクリーンショットを一気に作るコマンドの紹介です。

使用した環境

OS: Mac OS X 10.10.3

準備するもの

自分の場合はiPhone6 に合わせて 750×1336 pixel で、元となるスクリーンショットを5枚作成しました。(今考えると、640×1136 pixel で作っておけば、十分だったかもしれませんが、iPhone6 で 640×1136 のみ対応のアプリを動かすと、ピクセルが拡大されているのが見てわかってしまうので、こだわってしまいました。

 

機種 画面サイズ [Pixel] 必須? 備考
iPhone4s 640×960 必須 そろそろサポートしなくてもよくなるらしい。(もうなっているかも)
iPhone5/5s 640×1136 必須
iPhone6 750×1336 オプション
iPad 1536×2048 iPad対応アプリには必須 とりあえず左記のサイズを用意したら、iPad対応としてサブミットできた。

 

例えば、ss1.png 〜 ss5.png という名前の 750×1336 のスクリーンショット画像を、iphone6という名前のディレクトリに置きます。

Screen Shot 2015-07-24 at 2.23.16 PM

コマンド実行

 

この状態で、ディレクトリ丸ごと、iphone4, iphone5, ipad という名前でコピーします。

 

Screen Shot 2015-07-24 at 2.32.46 PM

サイズの変換には sips コマンドを使います。iPhone6 -> iPhone5 のサイズ変換は、アスペクト比がほぼ等しいので、sips の -z オプションでサイズを指定するだけです。

 

 

iPhone4 や iPad へのサイズ変換は、アスペクト比が異なるので、まず -z オプションでアスペクト比を保つようなサイズに変換したのち、-p オプションでゼロうめをしてサイズを合わせます。こうしないと、単純な引き伸ばしになってしまいます。

 

 

結果

 

プレビューなどで結果を確認します。

ss1 ss1 ss1 ss1

これで、一応は各サイズ用のスクリーンショットが用意できました!(サイドの黒塗りが気になる方は、何か別の手段を使う必要がありますが)

 

Cocos2d-x 公式ソースコードに自分のバグフィックスが取り込まれた

先日 Cocos2d-x の一部、Cocos2d-JS のバグ(彼らは仕様と言うかもしれない)を見つけたので、修正案を GitHub 上で公式に提案(プルリクエスト)してみました。

結果、取り込んでもらえましたので、その時やったことを紹介します。

バクの内容

JS の機能の一つに、JavaScript 側から Objective-C の関数が呼び出せるというものがあります。Cocos2d-JS v3. 6.1 現在、その引数が BOOL 型だったときに値がうまくわたらないので、NSNumber型 を使わなければならないという制限がありました。

[参考]
HOW TO CALL OBJECTIVE-C FUNCTIONS USING JS ON IOS/MAC
http://cocos2d-x.org/docs/manual/framework/html5/v3/reflection-oc/en

JavaScript には int と float の区別はなく、数値は “number” 型なので、int や float はNSNumber を使わなければならないのはよいです。しかし JavaScript でも bool は “boolean” 型があるので、NSNumber を使わなければならないのは違和感がありました。

ソースコードを確認したところ、以下の部分で JavaScript から受けた引数を NSInvocation の引数に変換しているのですが、数値も bool も区別せずに処理していました。

<cocos2d-x/cocos/scripting/js-bindings/manual/platform/ios/JavaScriptObjCBridge.mm>

[gistcode data_gist_id=”d694618edd6f08a811a3″ data_gist_highlight_line=”114″ data_gist_line=”110-119″]

これを isKindOfClass を使い、bool の時だけ特別扱いします。これで BOOL 型を引数とする C++ の関数を、修正することなく呼べるようになりました。

[gistcode data_gist_id=”0b75dc16272371a4e2a5″ data_gist_highlight_line=”114-125″ data_gist_line=”110-129″]

やったこと

バグを見つけるまではよくあることですが、今回は修正案を公式に提案するところまでやってみました。会社のコードとかではよくやってましたが、天下の Cocos2d-x 公式レポジトリに修正案を出すのは緊張します。変な日本人と思われたくない。

修正のコミット

前述の修正を、自分のローカルレポジトリでコミットし、GitHub の自分のクローンしたレポジトリ(自分の場合はshinhirota/cocos2d-x)に push しておきます。

プルリクエスト

フォーク(クローン)してある自分のレポジトリで修正のコミットを済ませていれば、Web上で簡単にできます。Cocos2d-x の開発元は中国の会社なので、レポジトリの管理も中国人エンジニアが行っているようです。詳しいコミットの説明を、英語(か中国語)で添える必要があります。

ss

ss2

説明はマークダウンで記述できるので便利です。十分な説明を書かないと英語で質問メールが来て、それに返事をしたりして時間がかかるか、最悪、無視される恐れがあります。

 

自分の場合は「こんな問題があって、このように直したら動作しました」のようなことを、サンプルコードを添えて、30分くらいかけて書きました。100行の説明より1つのサンプルコードです。

Screen Shot 2015-07-02 at 11.27.30 AM

 

プルリクエストを登録すると、レポジトリの管理者に通知が行くので、運が良ければあとは何もしなくてよいです。

自分の場合は、最初 Cocos2d-x とCocos2d-JSのレポジトリが統合されていたのをしらずに Cocos2d-JS のほうにプルリクエストを登録したら「Cocos2d-xのほうに登録してくれ」と言われてしまいましたが、あとは何もせずにすみました。

Cocos2d-x の管理者が、担当者にレビューを依頼し、その担当者のオーケーが出たので管理者がメインブランチである “v3” にマージしてくれました。やった!

 

 

Fixed iOS/JS-Bind callStaticMethod() with bool arg
https://github.com/cocos2d/cocos2d-x/pull/12598

Screen Shot 2015-07-02 at 11.58.35 AM

Cocos2d-JS の次のバージョン (v3.6.2?) には取り込まれるはずなので楽しみです。

[2015年8月27日 追記] 本修正が Cocos2d-x v3.8 (JSの一部がxに統合されたため、x からのリリース) に取り込まれてリリースされました!

まとめ

Unity人気に押され気味の印象がある Cocos2d-x/JS ですが、オープンソースであると言うのは Unity にはない魅力ですね!

Cocos2d-JS で広告を表示する (iOS編) その2

Cocos2d-JS で広告を表示する (iOS編) その1で単純な表示の方法を紹介したので、今回は位置の調整、表示/非表示を行う手順をまとめます。

Cocos2d-JS が生成するプロジェクトファイルは Interface Builer / Storyboard を使用していないので、ここでも使用しませず、ソースコードのみで実現します。

使用した環境

OS: Mac OS X 10.10.3
Xcode: 6.3.2
Cocos2d-JS: v3.6.1
Google Mobile Ads SDK iOS: 7.3.1

位置の調整

固定の位置で良い場合は、GADBannerView の frame プロパティ を設定すれば反映されます。以下は、画面の下部中央に配置する場合の例です。

<./ios/AppController.mm>

    {
        GADBannerView *gadView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];

        gadView.adUnitID = @"ca-app-pub-3940256099942544/2934735716";  // Official Test ID
        gadView.rootViewController = viewController;
        [gadView loadRequest:[GADRequest request]];

        [viewController.view addSubview:gadView];

        // gadView を画面下部の中心に配置
        CGRect contentFrame = viewController.view.bounds;
        CGRect bannerFrame = gadView.frame;
        bannerFrame.origin.y = contentFrame.size.height - bannerFrame.size.height;
        bannerFrame.origin.x = contentFrame.size.width / 2 - bannerFrame.size.width / 2;
        gadView.frame = bannerFrame;
    }

ただし画面回転に対応したり、親ビューがレイアウトを変更したりする場合、ビューコントローラーの viewDidLayoutSubviews メソッドをオーバーライドするなどの対処が必要ですが、ここでは省略します。

うまく動作すれば、広告が画面の下部中央に表示されます。

実行結果Screen Shot 2015-06-21 at 1.27.51 PM

表示/非表示

やっと Cocos2d-JS 特有の話になります。

ゲームなどで、タイトル画面では広告を表示し、ゲーム中は広告を非表示にしたりしたいことがあると思います。そのために、まずは JavaScript から C++ の関数を呼ぶ必要があります。Cocos2d-JS では JavaScript 側に jsb.reflection.callStaticMethod という関数が用意されています。名前の通り、スタティックメソッドしか呼びだせません。

C++側

まずC++側で、任意のクラスのスタティックメソッドを用意します。

そのためのクラスを作っても良いですが、ここでは変更を少なく抑えるため既存のクラス AppController isAdVisible と setAdVisible というスタティックメソッドを追加します。

C++側では、戻り値、引数として BOOL, 数値 (NSNumber), 文字列 (NSString) が使用できます。ただし現在の Cocos2d-JS の実装の制限として、BOOL の引数を受ける場合、NSNumber* で受けて boolValue に変換しないとうまく動作しないので注意してください。(将来改善されるかもしれません)

<./ios/AppController.h>

@interface AppController : NSObject <UIAccelerometerDelegate, UIAlertViewDelegate, UITextFieldDelegate,UIApplicationDelegate>
{
    UIWindow *window;
    RootViewController    *viewController;
}

// 追加
+ (void) setAdVisible:(NSNumber*) isVisible;
+ (BOOL) isAdVisible;

@end

<./ios/AppController.mm>

// gadView をローカル変数ではなくスタティック変数にする
static GADBannerView* gadView = nullptr;
@implementation AppController
 :
(中略)
 :
+ (void) setAdVisible:(NSNumber*) isVisible {
    gadView.hidden = ([isVisible boolValue] == false);
}

+ (BOOL) isAdVisible {
    return gadView.hidden == false;
}

@end

JavaScript側

Cocos2d-JSのサンプルのメニューボタンを押したときに、先ほど作成したC++ のメソッドを呼び出し、表示/非表示をトグルできるようにします。

<./src/app.js>


var HelloWorldLayer = cc.Layer.extend({
    sprite:null,
    ctor:function () {
        //////////////////////////////
        // 1. super init first
        this._super();

        /////////////////////////////
        // 2. add a menu item with "X" image, which is clicked to quit the program
        //    you may modify it.
        // ask the window size
        var size = cc.winSize;

        // add a "close" icon to exit the progress. it's an autorelease object
        var closeItem = new cc.MenuItemImage(
            res.CloseNormal_png,
            res.CloseSelected_png,
            function () {
                cc.log("Menu is clicked!");

                // 現在の表示状態を取得
                var isVisible = jsb.reflection.callStaticMethod(
                    "AppController",
                    "isAdVisible"
                );

                // 表示/非表示を設定
                jsb.reflection.callStaticMethod(
                    "AppController",
                    "setAdVisible:",
                    isVisible == false
                );

            }, this);
        closeItem.attr({
            x: size.width - 20,
            y: 20,
            anchorX: 0.5,
            anchorY: 0.5
        });

        var menu = new cc.Menu(closeItem);
        menu.x = 0;
        menu.y = 0;
        this.addChild(menu, 1);

うまくいけば右下のメニューボタンを押すたびに広告の非常/非表示が切り替わります!

Screen Shot 2015-06-21 at 7.16.56 PMScreen Shot 2015-06-21 at 1.27.51 PM

参考

HOW TO CALL OBJECTIVE-C FUNCTIONS USING JS ON IOS/MAC
http://cocos2d-x.org/docs/manual/framework/html5/v3/reflection-oc/en

 

Cocos2d-JS で広告を表示する (iOS編) その1

こんにちは。Cocos2d-JS で広告を表示したときの手順をまとめます。

概要

今回は、とりあえず AdMob を表示するまでをまとめます。実際のアプリに組み込む場合、位置の調整、表示・非表示などの制御が必要だと思いますが、それについては次回以降。

使用した環境

OS: Mac OS X 10.10.3
Xcode: 6.3.2
Cocos2d-JS: v3.6.1
Google Mobile Ads SDK iOS: 7.3.1

手順

ただ単にバナー広告をずっと表示していればよい場合は、JavaScript 側ではなにもせず、iOS 上の Objective-C++ 側の View に AdMob の GADBannerView を貼り付ければよいです。

JavaScript (Cococs2d-JS) とは関係のない話になってしまいますが、以下のように AdMob を組み込みます。

AdMob SDK をダウンロード

以下のページから googlemobileadssdkios.zip をダウンロードし、解凍します。

Downloads | Mobile Ads SDK | Google Developers
https://developers.google.com/mobile-ads-sdk/download?hl=ja#downloadios

Screen Shot 2015-06-19 at 9.56.32 AM

zip の中身はこのようになっています。

Screen Shot 2015-06-19 at 10.05.38 AM

Xcode プロジェクトに追加

広告を表示したい Cocos2d-JS プロジェクトに含まれる Xcode プロジェクトに、ダウンロードした SDK を追加します。

(参考:Cocos2d-JS のサンプルを動かしてみる (iOS編))

Xcode でプロジェクトを右クリックし、[Add Files to “xxxx”…] を選びます。

Screen Shot 2015-06-19 at 10.20.48 AM

先ほどダウンロードし、展開しておいた GoogleMobileAds.framework を選びます。この際、Copy items if needed のチェックはON、Added folders は Create groups、Add to targets は xxxxx iOS のみチェック、にします。

ss

Framework の追加

AdMob 公式ページの最新の手順では @import 文を使えば Framework は自動的に追加されると書かれていますが、Cocos2d-JS/x のプロジェクトでは Objective-C++ (.mmファイル) を使っているからわかりませんが、@import がうまくいきませんでした。

ここでは手動で Framework を追加する方法でやります。以下の Framework を プロジェクト設定からリンク対象に追加します。

  • SystemConfiguration
  • StoreKit
  • MessageUI
  • EventKitUI
  • EventKit
  • AdSupport
  • CoreTelephony
  • CoreMedia

Screen Shot 2015-06-20 at 8.58.00 AM

AdView 表示コードを追加

最低限、AppController.mm に以下のコードを追加すれば AdMob 広告が表示されます。

./ios/AppController.mm

 

#import "GoogleMobileAds/GADRequest.h"    //追加
#import "GoogleMobileAds/GADBannerView.h" //追加

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    // didFinishLaunchingWithOptions 内に以下のコードを追加
    {
        GADBannerView *gadView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];

        gadView.adUnitID = @"ca-app-pub-3940256099942544/2934735716";  // Official Test ID
        gadView.rootViewController = viewController;
        [gadView loadRequest:[GADRequest request]];

        [viewController.view addSubview:gadView];
    }

}

 実行結果

うまくいけば画面左上部に AdMob のテストバナーが表示されます。

Screen Shot 2015-06-20 at 9.36.59 AM

次回「状況に応じて表示/非表示を切り替える場合」についてまとめる予定です。

参考

AdMob iOS ガイド (オフィシャルドキュメント)
https://developers.google.com/mobile-ads-sdk/docs/admob/ios/quick-start?hl=ja