Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

「釣り★スタ」でのCocos2d-JSを使ってのアプリアップデート事例 (2)

3,855 views

Published on

Cocos2d-x Talks #2(2015/3/15)発表資料

「釣り★スタ」でのCocos2d-JSを使っての アプリアップデート事例

発表者
グリー株式会社 Wright Flyer Studios部 中 貴弘
グリー株式会社 Web Game Studio部 / 釣りスタグループ 和田孝尚

概要
日本最初のモバイルソーシャルゲームである「釣り★スタ」
フィーチャーフォンの時代から存在するゲームをCocos2d-JSを使ってのアプリ作成。
既に稼働中のサービスに対して行うアプリアップデート、その中で一番重視したことは実現できたのか。実際にプレイしたユーザからの反応等も交えて開発の事例を紹介できればと思います。

Published in: Technology
  • Login to see the comments

「釣り★スタ」でのCocos2d-JSを使ってのアプリアップデート事例 (2)

  1. 1. cocos2d-jsでの開発 について Wright Flyer Studios 中 貴弘 1
  2. 2. 自己紹介 • 中 貴弘 • 2012.2 グリー入社 • ∼2014.12 主にGREE プラットホーム向けSDKやミド ルウェア開発(Unity,cocos2d-x/js)に従事 • 現在はWRIGHT FLYER STUDIOSに所属 • グリー入社以前はアーケードゲームやコンシューマーゲー ム、iOSアプリなどを開発 2
  3. 3. 開発を始めた経緯 • 釣りスタプロジェクトからガワアプリで一部をネイ ティブで駆動したいという依頼
 (注:WebViewKitを用いたネイティブ風Webアプリの呼称) • ネイティブ cocos2d-x 3
  4. 4. ターゲットプラットフォームによる 開発環境の制約 • iOS4.3/Android2.2で動作する
 • これまでのガワアプリと相互運用可能
 • jsで実装したい
 
 4
  5. 5. • iOS4.3/Android2.2で動作する
 C++03(gcc) • これまでのガワアプリと相互運用可能
 SDKにはなるべく手を入れずラッパーを作る • jsで実装したい
 3系でのcocos2d-jsは時期尚早
 5 ターゲットプラットフォームによる 開発環境の制約
  6. 6. • iOS4.3/Android2.2で動作する
 C++03(gcc) • これまでのガワアプリと相互運用可能
 SDKにはなるべく手を入れずラッパーを作る • jsで実装したい
 3系でのcocos2d-jsは時期尚早
 => cocos2d-js 2.2.xで開発を行う 6 ターゲットプラットフォームによる 開発環境の制約
  7. 7. プロジェクト構成 について 7
  8. 8. 設計コンセプト • Objective-CとJNIの差異はC++レイヤーで吸収 • pimplイディオムで実装とインターフェースを分離 • できるだけモダンなC++で記述 • JavaScriptとC++のクラスは1対1で紐づく • cocosとWebを別々のViewController、Activityにする • etc… 8
  9. 9. 設計コンセプト • Objective-CとJNIの差異はC++レイヤーで吸収 • pimplイディオムで実装とインターフェースを分離 • できるだけモダンなC++で記述 • JavaScriptとC++のクラスは1対1で紐づく • cocosとWebを別々のViewController、Activityにする • etc… 9
  10. 10. C++コードをJavaScriptで 呼び出せるようにするには? 10
  11. 11. JSBが必要 • JSB(cocos2d javascript bindings)とは?
 Cocos2d-js環境(SpiderMonkey)でCocos2d-x APIコードをコー ルするためのグルーコード。 • グルーコードを実装することで自前のC++コードもJavaScript から呼ぶことが可能になる • 自動的にグルーコードを生成するツールもある(3系)
 https://github.com/cocos2d/bindings-generator • 今回はXMLHttpRequest.cpp/hを参考にグルーコードを実装し た。 11
  12. 12. Cocos2d-JS JSB Cocos2d-x AndroidiOS 12
  13. 13. JSBによる Cocos2d-jsクラス実装の流れ C++クラスのグルーコードを作成 JavaScriptエンジン(SpiderMonkey)に登録処理
 AppDelegate::applicationDidFinishLaunching()内でにて登録する JavaScriptをプロジェクトのリソースに追加する iOSとAndroidで同一スクリプトを参照するにはそれぞれのプロジェクトにパスを追加する 13
  14. 14. JSBで実現出来たこと • JavaScriptのクラスフィールド(というか連想配列)をC++の mapコンテナに変換 • C++のmapをJavaScriptに・・・つまり相互変換可能 • 非同期処理の結果をイベントリスナーで呼び出す • ラムダ式風コールバック処理 • これぐらいができると大抵のことはできそうな気がする 14
  15. 15. JSBの要点(1)
 XMLHttpRequestより ヘッダー ソース 機能 JS_BINDED_CLASS_GLUE JS_BINDED_CLASS_GLUE_IM PL グルーコード定義 JS_BINDED_CONSTRUCTOR JS_BINDED_CONSTRUCTOR _IMPL jsコンストラクタを定義 JS_BINDED_PROP_ACCESSO R getter setterを持つプロパティ 定義JS_BINDED_PROP_GET JS_BINDED_PROP_GET_IMPL getterのみを持つプロパティ JS_BINDED_FUNC JS_BINDED_FUNC_IMPL メンバ関数を定義 15
  16. 16. JSBの要点(2)
 GCを飼い慣らすためのAPI グルーコードによって定義したjsクラスをGCによって破壊されない ようにする必要がある。
 他にもイベントリスナーの実装を行うときにも必須。 JS_CallFunctionValueをコールしたあとはJS_RemoveObjectRoot を呼んでGCの対象に戻すことを忘れずに行う。 API 機能 JS_AddNamedObjectRoot GCのルートにObjectを追加 JS_RemoveObjectRoot GCのルートからObjectを削除 JS_CallFunctionValue Object紐付けられたメソッドの実行 16
  17. 17. JSBの要点(3)
 XMLHttpRequestより JS_BINDED_CONSTRUCTOR_IMPL(MinXmlHttpRequest) { MinXmlHttpRequest* req = new MinXmlHttpRequest(); req->autorelease(); js_proxy_t *p; jsval out; JSObject *obj = JS_NewObject(cx, &MinXmlHttpRequest::js_class, MinXmlHttpRequest::js_proto, MinXmlHttpRequest::js_parent); if (obj) { JS_SetPrivate(obj, req); out = OBJECT_TO_JSVAL(obj); } JS_SET_RVAL(cx, vp, out); p =jsb_new_proxy(req, obj); JS_AddNamedObjectRoot(cx, &p->obj, "XMLHttpRequest"); return JS_TRUE; } 17
  18. 18. 釣りスタにおける WebViewとCocosの レイヤー構成 18
  19. 19. Modal構成 WebViewController cocos2d-x • 釣りスタではproject-creatorで作成し たプロジェクトからWebViewライブラ リを呼び出す構成 • cocos2d-xのviewからiOSでは UIWebViewを持つカスタム ViewController、Androidでは WebViewを持つカスタムActivityを起 動 • 3.3から実装されたWebViewとは違う レイヤー構成 19
  20. 20. 問題発生 20
  21. 21. • iOSでは各モジュールのビルド設定を合わせねばな らず、かなり多くのプロジェクトを組み合わせてい たので複雑。 • iOSは全般的にビルド時間が長く、cocos2d-xのラ イブラリ化やJenkins化など開発効率化が急務。 • iOSでは基本的にビルドの問題が多かった 21
  22. 22. • Androidではコールバックしたリスナー内で cocos のAPIをコールすると例外やエラーが発生。 • 同様にリスナー内で自身が定義したクラスのメソッド を実行すると例外やエラーが発生。 • コールバックしたリスナー内のスクリプトのパースに 失敗するケースも。 • Androidで・・・etc • Androidは実行時のトラブルが主 22
  23. 23. iOSとAndroidの挙動の違い ✤ iOSはUIもcocosもmain threadで動作。注意する箇所は普通 のiOS アプリとそう変わらない。 ✤ AndroidはGLThreadの壁がある。 • cocos API はGLThreadで動作する前提で設計されている。 • jsエンジンであるSpiderMonkeyもAndroidではGLThread でスクリプトのパースおよび実行する仕様である。 • UIなどAndroidのいくつかのAPIはmain threadでのみ動作 する仕様。 23
  24. 24. 対策 • Android UIを操作するメソッドは全てUI Thread 上で動作するようにJavaレイヤーでハンドラーを 実装 • jsのイベントリスナーがGLThreadで動作するよう にJavaレイヤーでハンドラーを実装
 (cocos2d-jsでは特に重要) • つまり各APIが動作するスレッドを確実にしておく 24
  25. 25. //via jni Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable(){ public void run(){ //call Android UI API // } }); Cocos2dxActivity.getContext().runOnGLThread(new Runnable(){ public void run(){ //call cocos2d-x API // } }); cocos2d-x => Android UI API Android Main Thread => cocos2d-x API 25
  26. 26. ご静聴ありがとうございます。 ぜひcocos2d-jsにも 取り組んでみてください 26

×