Slide 1

Slide 1 text

釣り★スタ グリー株式会社 Web Game Studio部 釣りスタグループ 和田孝尚 COCOS2D-JS アプリアップデート事例 GL verts: 36 GL calls: 6 57.91 / 0.003

Slide 2

Slide 2 text

和田孝尚 ショウカイ エンジニア アプリ実装を主に担当 レベル:  38  HP: 166  MP:  63 2011年 グリー入社 2013年 釣り★スタチームへ これが初のCOCOS2D-X GL verts: 192 GL calls: 8 57.82 / 0.004

Slide 3

Slide 3 text

釣り★スタ GL verts: 6 GL calls: 1 60.00 / 0.004

Slide 4

Slide 4 text

• 釣り★スタ 2007年5月サービス開始 セツメイ • 世界初のモバイルソーシャルゲーム • アプリは2011年から提供 GL verts: 66 GL calls: 3 59.94 / 0.004

Slide 5

Slide 5 text

ガメン GL verts: 18 GL calls: 3 58.81 / 0.008

Slide 6

Slide 6 text

ギモン ブラウザゲームじゃないの? GL verts: 12 GL calls: 2 58.65 / 0.002

Slide 7

Slide 7 text

• HTMLやらFlashLiteで構成 レキシ • SP対応時当初はHTML5(Canvasとか) • 2013年後半LWFに対応 GL verts: 72 GL calls: 4 59.71 / 0.008 ※LWF(LightWeightSWF)とはGREEが開発しているオープンソース(zlib License)のフレームワークです。

Slide 8

Slide 8 text

ケツロン WebViewの限界 GL verts: 12 GL calls: 2 59.58 / 0.004

Slide 9

Slide 9 text

ケンショウ GL verts: 18 GL calls: 3 58.65 / 0.009

Slide 10

Slide 10 text

• 一部機種でタップ遅延が発生する チョウサ • アニメーション再生は許容範囲 • 釣りはアクションゲーム GL verts: 66 GL calls: 3 59.94 / 0.007

Slide 11

Slide 11 text

モクヒョウ すべてのユーザ に等しい体験を GL verts: 12 GL calls: 2 60.00 / 0.004

Slide 12

Slide 12 text

ならば GL verts: 6 GL calls: 1 59.98 / 0.006

Slide 13

Slide 13 text

ネイティブ化 GL verts: 6 GL calls: 1 59.24 / 0.005

Slide 14

Slide 14 text

• 基本はWebViewをベース ヨウキュウ • Android2.2以上 / iOS4.3以上 • 端末間の差が発生しにくい GL verts: 66 GL calls: 3 59.94 / 0.009

Slide 15

Slide 15 text

選ばれたのは GL verts: 6 GL calls: 1 59.24 / 0.006

Slide 16

Slide 16 text

COCOS2D-JS GL verts: 6 GL calls: 1 58.79 / 0.006

Slide 17

Slide 17 text

• 2系なら対象OSは問題無し ジョウキョウ • 3系だと一部切り捨て(当時β • GREE-SDK非対応 作るしかない GL verts: 66 GL calls: 3 57.56 / 0.007

Slide 18

Slide 18 text

ヨウキュウ サポート範囲 は既存のまま GL verts: 12 GL calls: 2 59.62 / 0.004

Slide 19

Slide 19 text

• COCOS2D-X 2.2系を採用 サイヨウ • COCOS2D-X 3系以降は独立する • リソース更新で無限の可能性 GL verts: 66 GL calls: 3 57.46 / 0.008

Slide 20

Slide 20 text

• UI周りはCOCOS2D-JS コウセイ • 固有の処理はJavaScriptBinding • GREE-SDKをJavaScriptから制御 GL verts: 66 GL calls: 3 58.13 / 0.004

Slide 21

Slide 21 text

カンケイ COCOS2D-JS JavaScript JSB Objective-C iOS Android Java C++ COCOS2D-X Library GREE-SDK JSB GL verts: 510 GL calls: 15 59.04 / 0.011

Slide 22

Slide 22 text

画面を作ろう GL verts: 6 GL calls: 1 59.24 / 0.006

Slide 23

Slide 23 text

• 背景等は固定画像 ガメン • アイテム類は可変画像 • フルスクリーン表示 GL verts: 72 GL calls: 4 58.16 / 0.008

Slide 24

Slide 24 text

ガゾウ var bgLayer = cc.Sprite.create("RaidBattle/bgselect.jpg"); bgLayer.setPosition( cc.p(layerSize.width*.5, layerSize.width*.5)); this.addChild(bgLayer); • Sprite(CCSprite)で画像表示 • 1枚画像なんかは 基本これのみ • リソースパス等あれば初期化時に設定する GL verts: 126 GL calls: 5 57.89 / 0.009

Slide 25

Slide 25 text

GL verts: 72 GL calls: 4 57.56 / 0.007 ギョエイ • DrawNode(CCDrawNode)を利用してみてる • 図形描画でアニメーション等検討 • ゲーム中の標的でアニメーションが必要

Slide 26

Slide 26 text

シヨウ JS_FN("drawDot", js_cocos2dx_CCDrawNode_drawDot, 3, JSPROP_PERMANENT | JSPROP_ENUMERATE), JS_FN("drawSegment", js_cocos2dx_CCDrawNode_drawSegment, 4, JSPROP_PERMANENT | JSPROP_ENUMERATE), • 2系だと描画命令が少ない • 3系だともう少し増える • 2系と3系で機能が違うものも多々ある GL verts: 126 GL calls: 5 57.56 / 0.006

Slide 27

Slide 27 text

タイオウ JS_FN("drawDot", js_cocos2dx_CCDrawNode_drawDot, 3, JSPROP_PERMANENT | JSPROP_ENUMERATE), JS_FN("drawSegment", js_cocos2dx_CCDrawNode_drawSegment, 4, JSPROP_PERMANENT | JSPROP_ENUMERATE), • 2系だと描画命令が少ない • 3系だともう少し増える • 2系と3系で機能が違うものも多々ある var fishSp = cc.Sprite.create("RaidBattle/fish_sprite.png"); var fishBody = cc.Sprite.create(); var animeCache = cc.AnimationCache.getInstance(); var fishAnime = animeCache.getAnimation("raidfish"); if(fishAnime == null){ var fish1 = cc.SpriteFrame.createWithTexture( fishSp.getTexture(), cc.rect(0, 0, 200, 100)); var fish2 = cc.SpriteFrame.createWithTexture( fishSp.getTexture(), cc.rect(0, 100, 200, 100)); var animFrames = []; animFrames.push(fish1); animFrames.push(fish2); fishAnime = cc.Animation.create(animFrames, 0.05); animeCache.addAnimation(fishAnime, "raidfish"); } fishBody.runAction( cc.RepeatForever.create(cc.Animate.create(fishAnime))); GL verts: 186 GL calls: 7 57.94 / 0.008

Slide 28

Slide 28 text

JS_FN("drawDot", js_cocos2dx_CCDrawNode_drawDot, 3, JSPROP_PERMANENT | JSPROP_ENUMERATE), JS_FN("drawSegment", js_cocos2dx_CCDrawNode_drawSegment, 4, JSPROP_PERMANENT | JSPROP_ENUMERATE), • 2系だと描画命令が少ない • 3系だともう少し増える • 2系と3系で機能が違うものも多々ある var fishSp = cc.Sprite.create("RaidBattle/fish_sprite.png"); var fishBody = cc.Sprite.create(); var animeCache = cc.AnimationCache.getInstance(); var fishAnime = animeCache.getAnimation("raidfish"); if(fishAnime == null){ var fish1 = cc.SpriteFrame.createWithTexture( fishSp.getTexture(), cc.rect(0, 0, 200, 100)); var fish2 = cc.SpriteFrame.createWithTexture( fishSp.getTexture(), cc.rect(0, 100, 200, 100)); var animFrames = []; animFrames.push(fish1); animFrames.push(fish2); fishAnime = cc.Animation.create(animFrames, 0.05); animeCache.addAnimation(fishAnime, "raidfish"); } fishBody.runAction( cc.RepeatForever.create(cc.Animate.create(fishAnime))); ヨウテン • Animation(CCAnimation)やAction類の利用 • 1画面内で使う画像などは1枚にまとめる • 既存の素材を再編集して使い回し GL verts: 246 GL calls: 8 58.23 / 0.014

Slide 29

Slide 29 text

モジ GL verts: 12 GL calls: 2 58.61 / 0.009

Slide 30

Slide 30 text

テイギ common lineHeight=32 base=0 scaleW=1 scaleH=1 pages=1 packed=0 page id=0 file="raid_font.png" chars count=28 char id=48 x=5 y=0 width=50 height=64 xoffset=0 yoffset=0 xadvance=50 page=0 chnl=0 // 0 ʢதུʣ char id=19975 x=192 y=192 width=64 height=64 xoffset=0 yoffset=0 xadvance=64 page=0 chnl=0 // ສ char id=33021 x=256 y=192 width=64 height=64 xoffset=0 yoffset=0 xadvance=64 page=0 chnl=0 // ೳ GL verts: 66 GL calls: 3 59.02 / 0.007

Slide 31

Slide 31 text

リヨウ common lineHeight=32 base=0 scaleW=1 scaleH=1 pages=1 packed=0 page id=0 file="raid_font.png" chars count=28 char id=48 x=5 y=0 width=50 height=64 xoffset=0 yoffset=0 xadvance=50 page=0 chnl=0 // 0 ʢதུʣ char id=19975 x=192 y=192 width=64 height=64 xoffset=0 yoffset=0 xadvance=64 page=0 chnl=0 // ສ char id=33021 x=256 y=192 width=64 height=64 xoffset=0 yoffset=0 xadvance=64 page=0 chnl=0 // ೳ var rod_status = cc.LabelBMFont.create(“ສೳ","raid_font.fnt"); rod_status.setPosition(cc.p(160, 365)); rod_status.setZOrder(1); this.addChild(rod_status); GL verts: 126 GL calls: 4 58.59 / 0.007

Slide 32

Slide 32 text

ヨウテン common lineHeight=32 base=0 scaleW=1 scaleH=1 pages=1 packed=0 page id=0 file="raid_font.png" chars count=28 char id=48 x=5 y=0 width=50 height=64 xoffset=0 yoffset=0 xadvance=50 page=0 chnl=0 // 0 ʢதུʣ char id=19975 x=192 y=192 width=64 height=64 xoffset=0 yoffset=0 xadvance=64 page=0 chnl=0 // ສ char id=33021 x=256 y=192 width=64 height=64 xoffset=0 yoffset=0 xadvance=64 page=0 chnl=0 // ೳ • LabelBMFont(CCLabelBMFont)を利用 • 子要素にアクセスして文字列アニメ等 • 白色で作ると色変更なんかも可能 GL verts: 186 GL calls: 6 58.84 / 0.006

Slide 33

Slide 33 text

• 背景等は固定画像 ドウグ • アイテム類は可変画像 • フルスクリーン表示 ユーザ所持アイテム イベント毎に増加 GL verts: 138 GL calls: 7 58.44 / 0.010

Slide 34

Slide 34 text

• 背景等は固定画像 ハイケイ • アイテム類は可変画像 • フルスクリーン表示 ユーザ所持アイテム イベント毎に増加 • アイテムの所持状態に左右される • 総量がかなりの量、7年以上の物量 • 全てをダウンロードするには不向き GL verts: 198 GL calls: 8 59.32 / 0.012

Slide 35

Slide 35 text

シンジツ JS側にオンラインで 画像取得の手段なし GL verts: 12 GL calls: 2 59.12 / 0.006

Slide 36

Slide 36 text

チョウサ • XMLHttpRequestとかはある • 扱えてもテキスト程度(エラーを返さない • あらかじめ内包する手段もあるが… GL verts: 66 GL calls: 3 59.37 / 0.004

Slide 37

Slide 37 text

チョウセン ないなら作れ GL verts: 66 GL calls: 3 59.42 / 0.005

Slide 38

Slide 38 text

ジッソウ JavaScript-Binding GL verts: 66 GL calls: 3 59.41 / 0.005

Slide 39

Slide 39 text

テイギ JSClass js_class = { "ImageLoader", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, basic_object_finalize, JSCLASS_NO_OPTIONAL_MEMBERS }; DownloadResource::js_class = js_class • JavaScript側でのクラス定義 • 基本は既存クラスの処理を真似すればいい GL verts: 126 GL calls: 5 57.74 / 0.007

Slide 40

Slide 40 text

テイギ • JavaScript側でのクラス定義 • 基本は既存クラスの同類の処理を真似 Property,function,static_functionの定義 static JSPropertySpec props[] = { {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER} }; static JSFunctionSpec funcs[] = { JS_BINDED_FUNC_FOR_DEF(ImageLoader, loadURL), JS_FS_END }; static JSFunctionSpec st_funcs[] = { JS_FS_END }; GL verts: 246 GL calls: 7 57.98 / 0.006

Slide 41

Slide 41 text

テイギ static JSPropertySpec props[] = { {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER} }; static JSFunctionSpec funcs[] = { JS_BINDED_FUNC_FOR_DEF(ImageLoader, loadURL), JS_FS_END }; static JSFunctionSpec st_funcs[] = { JS_FS_END }; ImageLoader::js_parent = NULL; ImageLoader::js_proto = JS_InitClass(cx, global, NULL, &ImageLoader::js_class , ImageLoader::_js_constructor, 0, props, funcs, NULL, st_funcs); • 既存クラスの継承等も可能 • サンプル類は豊富にあるので読んで理解 • 2系と3系で微妙に違うので注意 GL verts: 366 GL calls: 9 57.98 / 0.006

Slide 42

Slide 42 text

テイギ JS_BINDED_CONSTRUCTOR_IMPL(ImageLoader) { ImageLoader* pAuthorizer = new ImageLoader(); pAuthorizer->autorelease(); js_proxy_t *p; jsval out; JSObject *obj = JS_NewObject(cx, &ImageLoader::js_class, ImageLoader::js_proto, ImageLoader::js_parent); if (obj) { JS_SetPrivate(obj, pAuthorizer); out = OBJECT_TO_JSVAL(obj); } JS_SET_RVAL(cx, vp, out); p =jsb_new_proxy(pAuthorizer, obj); JS_AddNamedObjectRoot(cx, &p->obj, "ImageLoader"); return JS_TRUE; } GL verts: 66 GL calls: 3 58.24 / 0.007

Slide 43

Slide 43 text

JS_BINDED_CONSTRUCTOR_IMPL(ImageLoader) { ImageLoader* pAuthorizer = new ImageLoader(); pAuthorizer->autorelease(); js_proxy_t *p; jsval out; JSObject *obj = JS_NewObject(cx, &ImageLoader::js_class, ImageLoader::js_proto, ImageLoader::js_parent); if (obj) { JS_SetPrivate(obj, pAuthorizer); out = OBJECT_TO_JSVAL(obj); } JS_SET_RVAL(cx, vp, out); p =jsb_new_proxy(pAuthorizer, obj); JS_AddNamedObjectRoot(cx, &p->obj, "ImageLoader"); return JS_TRUE; } テイギ var imageLoader = new ImageLoader(); JavaScript GL verts: 132 GL calls: 5 58.32 / 0.006

Slide 44

Slide 44 text

テイギ JS_BINDED_FUNC_IMPL(ImageLoader, loadURL) { jsval *arg = JS_ARGV(cx, vp); if (argc == 1) { JSStringWrapper arg0(arg[0]); CCHttpReqest *request = new CCHttpRequest(); request->setUrl(arg0.c_str()); request->setRequestType(CCHttpRequest::kHttpGet); request->setResponseCallback(this, httpresponse_selector(ImageLoader::onLoadCompleted)); CCHttpClient::getInstance()->send(request); request->release(); return JS_TRUE; } return JS_FALSE; } GL verts: 66 GL calls: 3 58.27 / 0.007

Slide 45

Slide 45 text

テイギ JS_BINDED_FUNC_IMPL(ImageLoader, loadURL) { jsval *arg = JS_ARGV(cx, vp); if (argc == 1) { JSStringWrapper arg0(arg[0]); CCHttpReqest *request = new CCHttpRequest(); request->setUrl(arg0.c_str()); request->setRequestType(CCHttpRequest::kHttpGet); request->setResponseCallback(this, httpresponse_selector(ImageLoader::onLoadCompleted)); CCHttpClient::getInstance()->send(request); request->release(); return JS_TRUE; } return JS_FALSE; } var imageLoader = new ImageLoader(); imageLoader.loadURL(“http://xxx.com/test.png”); JavaScript GL verts: 132 GL calls: 5 58.26 / 0.008

Slide 46

Slide 46 text

テイギ void ImageLoader::onLoadCompleted(CCHttpClient *client, CCHttpResponse *response) { if (!response->isSucceed()) {return;} std::vector *buffer = response->getResponseData(); CCImage *image = new CCImage(); image->initWithImageData(&(buffer->front()), buffer->size()); /* ~response͔Βը૾ੜ੒ޙ~ */ js_proxy_t* p = jsb_get_native_proxy(this); JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); js_proxy_t *sp = js_get_or_create_proxy(cx, texture); jsval retval; jsval v[] = { v[0] = OBJECT_TO_JSVAL(sp->obj) }; ScriptingCore::getInstance()->executeFunctionWithOwner( OBJECT_TO_JSVAL(p->obj),"imageRequestComplete", 1, v, &retval); image->release(); } GL verts: 66 GL calls: 3 57.97 / 0.004

Slide 47

Slide 47 text

テイギ void ImageLoader::onLoadCompleted(CCHttpClient *client, CCHttpResponse *response) { if (!response->isSucceed()) {return;} std::vector *buffer = response->getResponseData(); CCImage *image = new CCImage(); image->initWithImageData(&(buffer->front()), buffer->size()); /* ~response͔Βը૾ੜ੒ޙ~ */ js_proxy_t* p = jsb_get_native_proxy(this); JSContext* cx = ScriptingCore::getInstance()->getGlobalContext(); js_proxy_t *sp = js_get_or_create_proxy(cx, texture); jsval retval; jsval v[] = { v[0] = OBJECT_TO_JSVAL(sp->obj) }; ScriptingCore::getInstance()->executeFunctionWithOwner( OBJECT_TO_JSVAL(p->obj),"imageRequestComplete", 1, v, &retval); image->release(); } var imageLoader = new ImageLoader(); imageLoader.imageRequestComplete = function(texture) { var t = texture.getContentSize() var loadSprite = getXXXXImageSprite(); loadSprite.setTexture(texture); loadSprite.setTextureRect( cc.rect(0, 0, t.width, t.height)); } imageLoader.loadURL(“http://xxx.com/test.png”); JavaScript GL verts: 132 GL calls: 5 57.75 / 0.005

Slide 48

Slide 48 text

ホウコク • 基本クラスのJSB見るのが理解早い • Callbackは関数定義のほうが見やすいかも • COCOS2D-X内で完結するものは比較的楽 GL verts: 66 GL calls: 3 58.13 / 0.006

Slide 49

Slide 49 text

• 背景等は固定画像 ザヒョウ • アイテム類は可変画像 • フルスクリーン表示 基本的にフルスクリーン 高さ分表示を調整したい 基本処理には存在しない GL verts: 138 GL calls: 7 58.31 / 0.011

Slide 50

Slide 50 text

テイギ float CCDeviceInfo::getStausBarHeight(){ CGRect statusBarRect = [UIApplication sharedApplication].statusBarFrame; CGFloat statusBarHeight = statusBarRect.size.height > statusBarRect.size.width ? statusBarRect.size.width : statusBarRect.size.height; return statusBarHeight; } iOS public static int getStausBarHeight(){ return 0; } Java GL verts: 84 GL calls: 6 58.83 / 0.009

Slide 51

Slide 51 text

テイギ float CCDeviceInfo::getStausBarHeight(){ CGRect statusBarRect = [UIApplication sharedApplication].statusBarFrame; CGFloat statusBarHeight = statusBarRect.size.height > statusBarRect.size.width ? statusBarRect.size.width : statusBarRect.size.height; return statusBarHeight; } iOS public static int getStausBarHeight(){ return 0; } Java • iOSなら拡張子*.mmにしてC++とObj-C併用 • AndroidはJNI利用して呼び出し GL verts: 144 GL calls: 8 58.82 / 0.007

Slide 52

Slide 52 text

テイギ CCDirector *pDirector = CCDirector::sharedDirector(); pDirector->setOpenGLView(CCEGLView::sharedOpenGLView()); CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); CCSize frameSize = pEGLView->getFrameSize(); pDirector->setContentScaleFactor(frameSize.width/320); cocos2d::CCEGLView::sharedOpenGLView()->setDesignResolutionSize( 320, 480, kResolutionFixedWidth); AppDelegate.cpp • 利用する画像の基準でScaleを指定 • 固定サイズで調整するのが簡単(320,480) GL verts: 132 GL calls: 6 58.79 / 0.006

Slide 53

Slide 53 text

テイギ CCDirector *pDirector = CCDirector::sharedDirector(); pDirector->setOpenGLView(CCEGLView::sharedOpenGLView()); CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); CCSize frameSize = pEGLView->getFrameSize(); pDirector->setContentScaleFactor(frameSize.width/320); cocos2d::CCEGLView::sharedOpenGLView()->setDesignResolutionSize( 320, 480, kResolutionFixedWidth); AppDelegate.cpp • 利用する画像の基準でScaleを指定 • 固定サイズで調整するのが簡単(320,480) var imgScale = 1/imgDirector.getContentScaleFactor(); var scaleSize = cc.rect(x*imgScale, y*imgScale, width*imgScale, height*imgScale); createWithTexture౳ɿRetina(x2)૝ఆ var imgScale = imgDirector.getContentScaleFactor()/2; imageSprite.setScale(imgScale); Sprite౳ɿRetina(x2)૝ఆ GL verts: 266 GL calls: 10 58.79 / 0.006

Slide 54

Slide 54 text

イショク GL verts: 12 GL calls: 2 59.33 / 0.006

Slide 55

Slide 55 text

イショク どうやって移植するの? 目コピで! 無理理に決まってんだろ! GL verts: 90 GL calls: 7 59.65 / 0.005

Slide 56

Slide 56 text

イショク どうやって移植するの? 目コピで! 無理理に決まってんだろ! • どうせなら新しい作り方に挑戦したい • Flasherさんとかでも扱いやすい環境 • 開発側でも調整ができるように GL verts: 150 GL calls: 9 59.36 / 0.006

Slide 57

Slide 57 text

コウホ GL verts: 12 GL calls: 2 59.82 / 0.006

Slide 58

Slide 58 text

コウホ CocosBuilder • Flash風味なインタフェース • アニメーションの細かい制御できない • COCOS2D-JS用の出力が可能 GL verts: 78 GL calls: 5 59.82 / 0.006

Slide 59

Slide 59 text

コウホ CocosBuilder • Flash風味…か • アニメーションの細かい制御できない • COCOS2D-JS用の出力が可能 公開停止 死亡確認 GL verts: 138 GL calls: 6 59.73 / 0.006

Slide 60

Slide 60 text

コウホ GL verts: 12 GL calls: 2 59.81 / 0.008

Slide 61

Slide 61 text

コウホ SpriteBuilder • CocosBuilderの後継? • 公開直後だったのかやたら不安定 • COCOS2D-JS用の出力不能 GL verts: 78 GL calls: 5 59.86 / 0.005

Slide 62

Slide 62 text

コウホ SpriteBuilder • CocosBuilderの後継? • 公開直後だったのかやたら不安定 • COCOS2D-JS用の出力不能 利用不能 死亡確認 GL verts: 138 GL calls: 6 59.28 / 0.006

Slide 63

Slide 63 text

コウホ GL verts: 12 GL calls: 2 58.63 / 0.007

Slide 64

Slide 64 text

コウホ CocoStudio • Windows用しかない • αとかβ • 公式だからアンシーン 利用不能 死亡確認 GL verts: 138 GL calls: 6 59.14 / 0.006

Slide 65

Slide 65 text

イショク JavaScriptのコードを移植 GL verts: 72 GL calls: 4 59.68 / 0.007

Slide 66

Slide 66 text

イショク • 相性もあるけど比較的楽な形式だった • アニメーションの計算なんかもそのまま • 旧:30FPS >> 新:60FPS GL verts: 72 GL calls: 4 59.43 / 0.008

Slide 67

Slide 67 text

サクセイ GL verts: 12 GL calls: 2 58.99 / 0.008

Slide 68

Slide 68 text

サクセイ 動作が早すぎて無理ゲー GL verts: 72 GL calls: 4 59.44 / 0.007

Slide 69

Slide 69 text

サクセイ • 全く処理落ちしないので想定より早い • 旧処理と操作回数、ゲーム結果の比較 • 原作のFLasherさんに微調整依頼 GL verts: 72 GL calls: 4 59.42 / 0.007

Slide 70

Slide 70 text

カンセイ • ひたすら動作確認の日々 • QA実施「もう過去に戻れない」と評価 • 別イベントとして作成して新旧を比較 GL verts: 72 GL calls: 4 59.62 / 0.008

Slide 71

Slide 71 text

コウカイ まずはAndroid先行 GL verts: 72 GL calls: 4 59.81 / 0.008

Slide 72

Slide 72 text

コウカイ プレイ後にアンケートを実施 GL verts: 72 GL calls: 4 59.83 / 0.007

Slide 73

Slide 73 text

シュウケイ プレイ後にアンケートを実施 GL verts: 78 GL calls: 5 59.77 / 0.008 䡧秘境島=COCOS2D-JS 䡧大イカ=LWF

Slide 74

Slide 74 text

シュウケイ プレイ後にアンケートを実施 GL verts: 78 GL calls: 5 59.68 / 0.007 䡧秘境島=COCOS2D-JS 䡧大イカ=LWF

Slide 75

Slide 75 text

シュウケイ • 魚の速度は明らかにCOCOS2D-JS • 遊びやすさは僅差でCOCOS2D-JS • 結果のスコアなどは比較的均一化された GL verts: 78 GL calls: 5 59.64 / 0.006

Slide 76

Slide 76 text

ルイジ iOS版のアンケートもほぼ同じ結果 GL verts: 72 GL calls: 4 59.56 / 0.007

Slide 77

Slide 77 text

• 処理上の目標は達成できた カンソウ • 今後の処理にも期待が持てる • 新バージョン(3系)も使えそう GL verts: 66 GL calls: 3 58.68 / 0.006

Slide 78

Slide 78 text

END GL verts: 6 GL calls: 1 58.59 / 0.005

Slide 79

Slide 79 text

END GL verts: 6 GL calls: 1 58.99 / 0.005

Slide 80

Slide 80 text

危険がヤバイ GL verts: 6 GL calls: 1 59.45 / 0.005

Slide 81

Slide 81 text

カイシ bool AppDelegate::applicationDidFinishLaunching() { // initialize director CCDirector *pDirector = CCDirector::sharedDirector(); pDirector->setOpenGLView(CCEGLView::sharedOpenGLView()); // turn on display FPS pDirector->setDisplayStats(true); // set FPS. the default value is 1.0/60 if you don't call this pDirector->setAnimationInterval(1.0 / 60); ScriptingCore* sc = ScriptingCore::getInstance(); /* ~লུ~ */ sc->start(); CCScriptEngineProtocol *pEngine = ScriptingCore::getInstance(); CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine); ScriptingCore::getInstance()->runScript("cocos2d-jsb.js"); return true; } GL verts: 66 GL calls: 3 59.47 / 0.005

Slide 82

Slide 82 text

bool AppDelegate::applicationDidFinishLaunching() { // initialize director CCDirector *pDirector = CCDirector::sharedDirector(); pDirector->setOpenGLView(CCEGLView::sharedOpenGLView()); // turn on display FPS pDirector->setDisplayStats(true); // set FPS. the default value is 1.0/60 if you don't call this pDirector->setAnimationInterval(1.0 / 60); ScriptingCore* sc = ScriptingCore::getInstance(); /* ~লུ~ */ sc->start(); CCScriptEngineProtocol *pEngine = ScriptingCore::getInstance(); CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine); ScriptingCore::getInstance()->runScript("cocos2d-jsb.js"); return true; } カイセキ • JS自体はアプリ内に存在 • runScriptから処理を開始 • 難読化しても読もうと思えば読める GL verts: 126 GL calls: 5 59.78 / 0.005

Slide 83

Slide 83 text

bool AppDelegate::applicationDidFinishLaunching() { // initialize director CCDirector *pDirector = CCDirector::sharedDirector(); pDirector->setOpenGLView(CCEGLView::sharedOpenGLView()); // turn on display FPS pDirector->setDisplayStats(true); // set FPS. the default value is 1.0/60 if you don't call this pDirector->setAnimationInterval(1.0 / 60); ScriptingCore* sc = ScriptingCore::getInstance(); /* ~লུ~ */ sc->start(); CCScriptEngineProtocol *pEngine = ScriptingCore::getInstance(); CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine); ScriptingCore::getInstance()->runScript("cocos2d-jsb.js"); return true; } シボウ 書き換えも可能 GL verts: 126 GL calls: 5 59.25 / 0.005

Slide 84

Slide 84 text

タイサク 起動時 • 更新頻度低いもの含めてチェック • ファイルのハッシュ値比較 • 問題なければJS実行 GL verts: 72 GL calls: 4 59.16 / 0.006

Slide 85

Slide 85 text

タイサク 起動時 • 更新頻度低いもの含めてチェック • ファイルのハッシュ値比較 • 問題なければJS実行 通常時 • その時点で必要なもののみチェック • ファイルのハッシュ値比較 • 更新があればスクリプト再起動 GL verts: 138 GL calls: 6 59.07 / 0.006

Slide 86

Slide 86 text

ソウカツ • 基本はHTMLと同じでJSのソースは丸見え • 見せたくないものはJSB等で隠蔽 • JavaScript上のエラー等も考慮して実装 • デバッグは…習うより慣れろ GL verts: 66 GL calls: 3 58.87 / 0.005

Slide 87

Slide 87 text

CONTINUE? GL verts: 6 GL calls: 1 58.62 / 0.006

Slide 88

Slide 88 text

COCOS2D-JS3.3 GL verts: 6 GL calls: 1 59.14 / 0.006

Slide 89

Slide 89 text

カンキョウ GL verts: 18 GL calls: 3 59.11 / 0.007

Slide 90

Slide 90 text

ベンリ • Cocos Code IDEでデバッグ実行 • Cocos StudioでUIやアニメーション作成 • Runtimeパス指定で、JSB等の実装もカバー GL verts: 78 GL calls: 5 59.48 / 0.007

Slide 91

Slide 91 text

ジッコウ • Cocos Code IDEでデバッグ実行 • Cocos StudioでUIやアニメーション作成 • Runtimeパス指定で、JSB等の実装もカバー >cocos run -p web GL verts: 138 GL calls: 7 59.65 / 0.007

Slide 92

Slide 92 text

ドウサ GL verts: 12 GL calls: 2 59.58 / 0.006

Slide 93

Slide 93 text

カンキョウ • 動作はそこまで軽くないが確認には十分 • Chrome等ブラウザから確認可能 • 2系のコードほぼそのまま使える GL verts: 72 GL calls: 4 59.53 / 0.006

Slide 94

Slide 94 text

ヘンコウ var direvtor = cc.Director.getInstance(); var color_a = cc.c4b(0, 0, 0, 255); var color_b = cc.BLACK; var sp_test = cc.Sprite.create(“test.png”); var direvtor = cc.director; var color_a = cc.color(0, 0, 0, 255); var color_b = cc.color.BLACK; var sp_test = new cc.Sprite(“test.png”); Cocos2d-html5 v2.x Cocos2d-JS v3.x GL verts: 84 GL calls: 6 59.37 / 0.008

Slide 95

Slide 95 text

ヘンコウ var direvtor = cc.Director.getInstance(); var color_a = cc.c4b(0, 0, 0, 255); var color_b = cc.BLACK; var sp_test = cc.Sprite.create(“test.png”); var direvtor = cc.director; var color_a = cc.color(0, 0, 0, 255); var color_b = cc.color.BLACK; var sp_test = new cc.Sprite(“test.png”); Cocos2d-html5 v2.x Cocos2d-JS v3.x • Webもサポートするなら書き方注意 • 基本はそのまま • 旧記述のままだと挙動が変わるケースも GL verts: 144 GL calls: 8 59.48 / 0.008

Slide 96

Slide 96 text

ヘンコウ this.setTouchMode(cc.TOUCH_ONE_BY_ONE); this.setTouchEnabled(true); this.onTouchBegan = function( touch ) { /*~ TODO:Touch Event ~*/ } cc.eventManager.addListener(cc.EventListener.create({ event: cc.EventListener.TOUCH_ONE_BY_ONE, onTouchBegan:function (touches, event) { /*~ TODO:Touch Event ~*/ } }), this); Cocos2d-html5 v2.x Cocos2d-JS v3.x GL verts: 84 GL calls: 6 59.36 / 0.007

Slide 97

Slide 97 text

ヘンコウ this.setTouchMode(cc.TOUCH_ONE_BY_ONE); this.setTouchEnabled(true); this.onTouchBegan = function( touch ) { /*~ TODO:Touch Event ~*/ } cc.eventManager.addListener(cc.EventListener.create({ event: cc.EventListener.TOUCH_ONE_BY_ONE, onTouchBegan:function (touches, event) { /*~ TODO:Touch Event ~*/ } }), this); Cocos2d-html5 v2.x Cocos2d-JS v3.x • Touchイベントはcocos2d-xと同様の変更 • WebもやるならMouseイベントも設定 • サンプルにだいたい欲しい処理がある GL verts: 144 GL calls: 8 59.34 / 0.008

Slide 98

Slide 98 text

コンゴ • COCOS2D-JS自体のバージョンアップ • 開発効率を上げるためのツール導入 • 運用ノウハウの蓄積 GL verts: 66 GL calls: 3 59.82 / 0.008

Slide 99

Slide 99 text

END GL verts: 6 GL calls: 1 60.00 / 0.005