『こなへん』ができるまで ☆リリース直前編☆
DESCRIPTION
第3回iphone_dev_jp 東京iPhone/Mac勉強会で発表したスライドですTRANSCRIPT
『こなへん』ができるまで ☆リリース直前編☆
西山信行
5mingame2
はじめに
• 私はこれまでに iPhoneアプリをシリーズ物とかで12本くらいリリース
している、ほんのり専業アプリ開発者です。
• Objective-Cは5年目、C++は2年目。
はじめに
• 5月末に、生まれて初めてほぼC++で書いたiPhoneアプリ『こなへん』が無事公
開されました!皆さんのおかげです!多謝。
–今回は実験的に、拙ブログにて公開直前バージョンのソースを配布していますので併せてどうぞ(スライドの最後に案内があります)
はじめに
それでは、まずはみなさん一番困っているであろう『こなへん』の発音から。
前回までのあらすじ
• 新ジャンル「マゾプログラミング」
• C++とOpenGLとOpenALでマルチプラットフォームなゲームが作れる
• 「3M」プログラミング –画像・サウンドの読み込み処理ない…マゾい
–日本語テキスト表示ない…マゾい
– iOSライブラリ使えない…マゾい
今回のマゾプログラミング
• GameCenter & iAd対応はどうした
• ローカライズはどうした
• テスト&デバッグはどうした
• 動作パフォーマンスはどうした
GameCenter & iAd対応
GameCenter & iAd対応
• アプリはUIViewControllerが1つだけの単純な構造
–XcodeのOpenGL ESのひな形まんま
GameCenter & iAd対応
• まず、そのUIViewControllerにGKLeaderboardViewControllerDelegateとADBannerViewDelegateを担当させる
GameCenter & iAd対応
• GameCenter.mmというソースを用意。 GameCenter関連を処理する関数群をそこに押し込んだ。
• クラスにはしないですべて関数で実装 – これだとC++のコードから関数が呼び出せる。
• 関数内では [[NSString alloc] init]; とか色々普通に使えます。
GameCenter & iAd対応
GameCenter & iAd対応
GameCenter & iAd対応
ローカライズ
ローカライズ
• iPhoneの NSLocalizedString() を真似る所からスタート
–定義ファイルをutf-8で用意
• en.langとかjp.langとか
–[元のテキスト] TAB [翻訳テキスト]
–その定義ファイルをstd::mapに流し込むだけ~
ローカライズ
ローカライズ
• さて、準備はできたけど、C++で
実行環境が「英語」なのか「日本語」なのかはどうやって調べようか…
ローカライズ
• Windowsはstd::localeを使って言語環境を判定
std::locale lc(“”); if (lc.name() == std::string(“Japanese_Japan.932”)) { /* jp.langを読み込む */ }
ローカライズ
• OSXは CFCopyLocalizedString() で判定
• iOSは NSLocalizedString() で判定
• どういう事?
ローカライズ
• OSXとiOSは Localizable.strings を用意
するだけで読み込む定義ファイルを決められる。簡単!
• “langFile” = “en.lang”; とか書いておく。
–NSLocalizedString(@” langFile”, 0) で読み込む定義ファイルを決めればいい。
ローカライズ
• そして、 NSLocalizedString() 同様 std::string text = localize.get(“hoge”);
みたいにして、文字列を取得するようになっています。
テスト&デバッグ
テスト&デバッグ
• 僕はプログラムの動作中に状況を簡単に確認できるデバッグプリントが大好きなので、いろんな場所で std::cout << “座標:” << x << “,” << y << std::endl; とかしたくなるのですが…。
テスト&デバッグ
• Xcode
–コンソールに表示される
• Windows
–へんじがない ただの しかばねの ようだ
テスト&デバッグ
• マリアナ海溝よりも深い理由があるのか。この件、VisualStudioはいいかげん対応してほしい! –VisualStudio2010調べ
• でも自分でなんとかできちゃった。
テスト&デバッグ
class DbgStreambuf : public std::streambuf { std::vector<char> str_; public: int_type overflow(int_type c = EOF) { str_.push_back(c); return c; } int sync() { str_.push_back('¥0'); OutputDebugString(&str_[0]); // VSの出力に文字列を表示する str_.clear(); return 0; } };
テスト&デバッグ
DbgStreambuf dbgStream; std::streambuf *stream; stream = std::cout.rdbuf(&dbgStream); std::cout << "hogehoge" << std::endl; // VSの出力にちゃんと出力される std::cout.rdbuf(stream); // 元に戻す
テスト&デバッグ
• NSLog() は、リリースビルドだと処理がスキップされるようになっている。
• std::cout も同じようにできないだろうか…
テスト&デバッグ
• こう書くことで解決。 #ifdef _DEBUG #define DOUT std::cout #else #define DOUT 0 && std::cout #endif DOUT << “hoge piyo” << std::endl;
テスト&デバッグ
• その他デバッグ機能の紹介
–キーを押してスナップショット
–キーを押してどこでもポーズ
–連続スナップショット
–マップ確認&データ変換ツール
–地球プレビュワー
動作パフォーマンス
動作パフォーマンス
• 『こなへん』の地球は、1つの球体データをテクスチャを切り替えたりして何度も重ね描きしています。
動作パフォーマンス
• 開発中期、iPhone4でだけ30fpsになる現象が発生して慌てた。 – iPhone3GSは常時60fps。
• iPhone4の画像プロセッサにはRetinaディスプレイはしんどいらしい。 –これをどうやって解決しよう…>_<
動作パフォーマンス
• Xcode4から導入された OpenGL ES Performance Detective Instruments(OpenGL ES Analysis) を使って描画負荷の原因を調べてみた。
–アップルから配布されている「iOS OpenGL ESプログラミングガイド(日本語!)」にかなり親切な解説があります。
動作パフォーマンス
• 診断の結果なんと 「頂点バッファを使え」 「テクスチャ圧縮を使え」
と具体的に指摘されました。英語でですが…(汗)
–これに対応したらiPhone4でもほぼ60fpsを達成できた
動作パフォーマンス
• CPU負荷はXcodeの Instruments (Time Profiler) で計測。CPUの負荷を計測したり、処理の重い関数をリストアップしてくれる! – これもアップルから配布されている「Instrumentsユーザガイド(日本語!)」で詳しく解説されています。素敵すぎます。
動作パフォーマンス
• 計測の結果「プログラム最適化の必要なし」
–C++初心者ゆえのダサい書き方は放置
–計測で問題なければ、最適化をする必要は「まったく」無い。
動作パフォーマンス
• 問題が発生した時に、まずは処理負荷を計測、「負荷となっている箇所」を絞り込む作戦で問題を解決できた。
• 結果、初代iPadでもほぼ60fps!
• 僕は勘で直せるほど精通してないので…:P
まとめ
まとめ
• GameCenter & iAd対応 – iOSに特化した処理なので、大人しくObjective-Cで書いた。
• ローカライズ – OSXやiOSのを真似て自分で実装した。
• テスト&デバッグ –デバッグビルドで検証用の機能を実装したら楽できた。
• 動作パフォーマンス –各種検証用ツールがあるXcodeは最高!
余談
• 今回サポートページをfacebookに
作って直接リンクを設定したけどリジェクトされなかった:D – facebookのアカウントが無くても、アプリ
の情報や連絡先が見られるようにしたからいい…のかな?
おしまいです
• こんな感じですが…マゾっぽくないみなさんの参考になりましたでしょうか…
– blog 「でらうま倶楽部」
• http://blog.livedoor.jp/tek_nishi/
• @5mingame2
• 5mingame2