SlideShare a Scribd company logo
釣り★スタ
グリー株式会社 Web Game Studio部
釣りスタグループ 和田孝尚
COCOS2D-JS
アプリアップデート事例
GL verts: 36
GL calls: 6
57.91 / 0.003
和田孝尚
ショウカイ
エンジニア
アプリ実装を主に担当
レベル:  38
 HP: 166
 MP:  63
2011年 グリー入社
2013年 釣り★スタチームへ
これが初のCOCOS2D-X
GL verts: 192
GL calls: 8
57.82 / 0.004
釣り★スタ
GL verts: 6
GL calls: 1
60.00 / 0.004
• 釣り★スタ 2007年5月サービス開始
セツメイ
• 世界初のモバイルソーシャルゲーム
• アプリは2011年から提供
GL verts: 66
GL calls: 3
59.94 / 0.004
ガメン
GL verts: 18
GL calls: 3
58.81 / 0.008
ギモン
ブラウザゲームじゃないの?
GL verts: 12
GL calls: 2
58.65 / 0.002
• HTMLやらFlashLiteで構成
レキシ
• SP対応時当初はHTML5(Canvasとか)
• 2013年後半LWFに対応
GL verts: 72
GL calls: 4
59.71 / 0.008
※LWF(LightWeightSWF)とはGREEが開発しているオープンソース(zlib License)のフレームワークです。
ケツロン
WebViewの限界
GL verts: 12
GL calls: 2
59.58 / 0.004
ケンショウ
GL verts: 18
GL calls: 3
58.65 / 0.009
• 一部機種でタップ遅延が発生する
チョウサ
• アニメーション再生は許容範囲
• 釣りはアクションゲーム
GL verts: 66
GL calls: 3
59.94 / 0.007
モクヒョウ
すべてのユーザ
に等しい体験を
GL verts: 12
GL calls: 2
60.00 / 0.004
ならば
GL verts: 6
GL calls: 1
59.98 / 0.006
ネイティブ化
GL verts: 6
GL calls: 1
59.24 / 0.005
• 基本はWebViewをベース
ヨウキュウ
• Android2.2以上 / iOS4.3以上
• 端末間の差が発生しにくい
GL verts: 66
GL calls: 3
59.94 / 0.009
選ばれたのは
GL verts: 6
GL calls: 1
59.24 / 0.006
COCOS2D-JS
GL verts: 6
GL calls: 1
58.79 / 0.006
• 2系なら対象OSは問題無し
ジョウキョウ
• 3系だと一部切り捨て(当時β
• GREE-SDK非対応 作るしかない
GL verts: 66
GL calls: 3
57.56 / 0.007
ヨウキュウ
サポート範囲
は既存のまま
GL verts: 12
GL calls: 2
59.62 / 0.004
• COCOS2D-X 2.2系を採用
サイヨウ
• COCOS2D-X 3系以降は独立する
• リソース更新で無限の可能性
GL verts: 66
GL calls: 3
57.46 / 0.008
• UI周りはCOCOS2D-JS
コウセイ
• 固有の処理はJavaScriptBinding
• GREE-SDKをJavaScriptから制御
GL verts: 66
GL calls: 3
58.13 / 0.004
カンケイ
COCOS2D-JS
JavaScriptJSB
Objective-C
iOS Android
JavaC++
COCOS2D-X
Library
GREE-SDK
JSB
GL verts: 510
GL calls: 15
59.04 / 0.011
画面を作ろう
GL verts: 6
GL calls: 1
59.24 / 0.006
• 背景等は固定画像
ガメン
• アイテム類は可変画像
• フルスクリーン表示
GL verts: 72
GL calls: 4
58.16 / 0.008
ガゾウ
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
GL verts: 72
GL calls: 4
57.56 / 0.007
ギョエイ
• DrawNode(CCDrawNode)を利用してみてる
• 図形描画でアニメーション等検討
• ゲーム中の標的でアニメーションが必要
シヨウ
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
タイオウ
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
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
モジ
GL verts: 12
GL calls: 2
58.61 / 0.009
テイギ
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
リヨウ
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
ヨウテン
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
• 背景等は固定画像
ドウグ
• アイテム類は可変画像
• フルスクリーン表示
ユーザ所持アイテム
イベント毎に増加
GL verts: 138
GL calls: 7
58.44 / 0.010
• 背景等は固定画像
ハイケイ
• アイテム類は可変画像
• フルスクリーン表示
ユーザ所持アイテム
イベント毎に増加
• アイテムの所持状態に左右される
• 総量がかなりの量、7年以上の物量
• 全てをダウンロードするには不向き
GL verts: 198
GL calls: 8
59.32 / 0.012
シンジツ
JS側にオンラインで
画像取得の手段なし
GL verts: 12
GL calls: 2
59.12 / 0.006
チョウサ
• XMLHttpRequestとかはある
• 扱えてもテキスト程度(エラーを返さない
• あらかじめ内包する手段もあるが…
GL verts: 66
GL calls: 3
59.37 / 0.004
チョウセン
ないなら作れ
GL verts: 66
GL calls: 3
59.42 / 0.005
ジッソウ
JavaScript-Binding
GL verts: 66
GL calls: 3
59.41 / 0.005
テイギ
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
テイギ
• 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
テイギ
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
テイギ
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
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
テイギ
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
テイギ
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
テイギ
void ImageLoader::onLoadCompleted(CCHttpClient *client, CCHttpResponse *response)
{
if (!response->isSucceed()) {return;}
std::vector<char> *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<cocos2d::CCTexture2D>(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
テイギ
void ImageLoader::onLoadCompleted(CCHttpClient *client, CCHttpResponse *response)
{
if (!response->isSucceed()) {return;}
std::vector<char> *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<cocos2d::CCTexture2D>(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
ホウコク
• 基本クラスのJSB見るのが理解早い
• Callbackは関数定義のほうが見やすいかも
• COCOS2D-X内で完結するものは比較的楽
GL verts: 66
GL calls: 3
58.13 / 0.006
• 背景等は固定画像
ザヒョウ
• アイテム類は可変画像
• フルスクリーン表示
基本的にフルスクリーン
高さ分表示を調整したい
基本処理には存在しない
GL verts: 138
GL calls: 7
58.31 / 0.011
テイギ
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
テイギ
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
テイギ
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
テイギ
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
イショク
GL verts: 12
GL calls: 2
59.33 / 0.006
イショク
どうやって移植するの?
目コピで!
無理理に決まってんだろ!
GL verts: 90
GL calls: 7
59.65 / 0.005
イショク
どうやって移植するの?
目コピで!
無理理に決まってんだろ!
• どうせなら新しい作り方に挑戦したい
• Flasherさんとかでも扱いやすい環境
• 開発側でも調整ができるように
GL verts: 150
GL calls: 9
59.36 / 0.006
コウホ
GL verts: 12
GL calls: 2
59.82 / 0.006
コウホ
CocosBuilder
• Flash風味なインタフェース
• アニメーションの細かい制御できない
• COCOS2D-JS用の出力が可能
GL verts: 78
GL calls: 5
59.82 / 0.006
コウホ
CocosBuilder
• Flash風味…か
• アニメーションの細かい制御できない
• COCOS2D-JS用の出力が可能
公開停止
死亡確認
GL verts: 138
GL calls: 6
59.73 / 0.006
コウホ
GL verts: 12
GL calls: 2
59.81 / 0.008
コウホ
SpriteBuilder
• CocosBuilderの後継?
• 公開直後だったのかやたら不安定
• COCOS2D-JS用の出力不能
GL verts: 78
GL calls: 5
59.86 / 0.005
コウホ
SpriteBuilder
• CocosBuilderの後継?
• 公開直後だったのかやたら不安定
• COCOS2D-JS用の出力不能
利用不能
死亡確認
GL verts: 138
GL calls: 6
59.28 / 0.006
コウホ
GL verts: 12
GL calls: 2
58.63 / 0.007
コウホ
CocoStudio
• Windows用しかない
• αとかβ
• 公式だからアンシーン
利用不能
死亡確認
GL verts: 138
GL calls: 6
59.14 / 0.006
イショク
JavaScriptのコードを移植
GL verts: 72
GL calls: 4
59.68 / 0.007
イショク
• 相性もあるけど比較的楽な形式だった
• アニメーションの計算なんかもそのまま
• 旧:30FPS >> 新:60FPS
GL verts: 72
GL calls: 4
59.43 / 0.008
サクセイ
GL verts: 12
GL calls: 2
58.99 / 0.008
サクセイ
動作が早すぎて無理ゲー
GL verts: 72
GL calls: 4
59.44 / 0.007
サクセイ
• 全く処理落ちしないので想定より早い
• 旧処理と操作回数、ゲーム結果の比較
• 原作のFLasherさんに微調整依頼
GL verts: 72
GL calls: 4
59.42 / 0.007
カンセイ
• ひたすら動作確認の日々
• QA実施「もう過去に戻れない」と評価
• 別イベントとして作成して新旧を比較
GL verts: 72
GL calls: 4
59.62 / 0.008
コウカイ
まずはAndroid先行
GL verts: 72
GL calls: 4
59.81 / 0.008
コウカイ
プレイ後にアンケートを実施
GL verts: 72
GL calls: 4
59.83 / 0.007
シュウケイ
プレイ後にアンケートを実施
GL verts: 78
GL calls: 5
59.77 / 0.008
秘境島=COCOS2D-JS
大イカ=LWF
シュウケイ
プレイ後にアンケートを実施
GL verts: 78
GL calls: 5
59.68 / 0.007
秘境島=COCOS2D-JS
大イカ=LWF
シュウケイ
• 魚の速度は明らかにCOCOS2D-JS
• 遊びやすさは僅差でCOCOS2D-JS
• 結果のスコアなどは比較的均一化された
GL verts: 78
GL calls: 5
59.64 / 0.006
ルイジ
iOS版のアンケートもほぼ同じ結果
GL verts: 72
GL calls: 4
59.56 / 0.007
• 処理上の目標は達成できた
カンソウ
• 今後の処理にも期待が持てる
• 新バージョン(3系)も使えそう
GL verts: 66
GL calls: 3
58.68 / 0.006
END
GL verts: 6
GL calls: 1
58.59 / 0.005
END
GL verts: 6
GL calls: 1
58.99 / 0.005
危険がヤバイ
GL verts: 6
GL calls: 1
59.45 / 0.005
カイシ
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
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
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
タイサク
起動時
• 更新頻度低いもの含めてチェック
• ファイルのハッシュ値比較
• 問題なければJS実行
GL verts: 72
GL calls: 4
59.16 / 0.006
タイサク
起動時
• 更新頻度低いもの含めてチェック
• ファイルのハッシュ値比較
• 問題なければJS実行
通常時
• その時点で必要なもののみチェック
• ファイルのハッシュ値比較
• 更新があればスクリプト再起動
GL verts: 138
GL calls: 6
59.07 / 0.006
ソウカツ
• 基本はHTMLと同じでJSのソースは丸見え
• 見せたくないものはJSB等で隠蔽
• JavaScript上のエラー等も考慮して実装
• デバッグは…習うより慣れろ
GL verts: 66
GL calls: 3
58.87 / 0.005
CONTINUE?
GL verts: 6
GL calls: 1
58.62 / 0.006
COCOS2D-JS3.3
GL verts: 6
GL calls: 1
59.14 / 0.006
カンキョウ
GL verts: 18
GL calls: 3
59.11 / 0.007
ベンリ
• Cocos Code IDEでデバッグ実行
• Cocos StudioでUIやアニメーション作成
• Runtimeパス指定で、JSB等の実装もカバー
GL verts: 78
GL calls: 5
59.48 / 0.007
ジッコウ
• Cocos Code IDEでデバッグ実行
• Cocos StudioでUIやアニメーション作成
• Runtimeパス指定で、JSB等の実装もカバー
>cocos run -p web
GL verts: 138
GL calls: 7
59.65 / 0.007
ドウサ
GL verts: 12
GL calls: 2
59.58 / 0.006
カンキョウ
• 動作はそこまで軽くないが確認には十分
• Chrome等ブラウザから確認可能
• 2系のコードほぼそのまま使える
GL verts: 72
GL calls: 4
59.53 / 0.006
ヘンコウ
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
ヘンコウ
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
ヘンコウ
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
ヘンコウ
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
コンゴ
• COCOS2D-JS自体のバージョンアップ
• 開発効率を上げるためのツール導入
• 運用ノウハウの蓄積
GL verts: 66
GL calls: 3
59.82 / 0.008
END
GL verts: 6
GL calls: 1
60.00 / 0.005

More Related Content

PPTX
Cocos2d-x(JS) ハンズオン #02 「画像表示とアクション」
PPTX
Cocos2d-x(JS) ハンズオン #08「様々な画像描画方法」
PDF
Cocos2d-JSと物理演算で作る横スクロールアクションゲーム #scripty06
PDF
「釣り★スタ」でのCocos2d-JSを使ってのアプリアップデート事例 (2)
PPTX
Cocos2d-x(JS) ハンズオン #03「複数あるボタンの使い分け」
PPTX
Cocos2d-x(JS) ハンズオン #04「タッチイベントの使い方」
PPTX
Cocos2d-x(JS) ハンズオン #06「3rd SDKの導入を簡単にするSDKBOX」
PPTX
Cocos2d-x(JS) ハンズオン #05「Cocos StudioとCocos2d-x (JS)との連携」
Cocos2d-x(JS) ハンズオン #02 「画像表示とアクション」
Cocos2d-x(JS) ハンズオン #08「様々な画像描画方法」
Cocos2d-JSと物理演算で作る横スクロールアクションゲーム #scripty06
「釣り★スタ」でのCocos2d-JSを使ってのアプリアップデート事例 (2)
Cocos2d-x(JS) ハンズオン #03「複数あるボタンの使い分け」
Cocos2d-x(JS) ハンズオン #04「タッチイベントの使い方」
Cocos2d-x(JS) ハンズオン #06「3rd SDKの導入を簡単にするSDKBOX」
Cocos2d-x(JS) ハンズオン #05「Cocos StudioとCocos2d-x (JS)との連携」

What's hot (20)

PDF
Cocos2d-xを用いたゲームアプリ「めちゃギントン」開発の裏側
PDF
Cocos2d xで簡単なゲームを作ってみよう!
PPTX
Cocos2d-x(JS)の紹介
PDF
Cocos2d-x勉強会 2014/10/05
PDF
Cocos2d-xとSpriteStudioを使った音ゲー開発のお話
PPTX
Cocos2d-x(JS) ハンズオン #10「3D機能とVR機能」
PDF
Cocos2d-x 3D Extension
PPTX
Cocos2d-x(JS) ハンズオン #12「Cocos2d-xとSpine」
PDF
はじめての CircleCI
PDF
Cocos2d-x 3.2 Eclipseを利用したAndroid開発環境の構築
PDF
cocos2d-x 3.0による変更点
PPTX
Cocos2d-x(JS) ハンズオン #11「2D物理エンジン」
PDF
Cocos2d-xによる最新ゲーム開発
KEY
Cocos2d xをさわってみよう!
PDF
Cocos2d-x Console @Cocos Talks #3
PDF
【Unite Tokyo 2019】「禍つヴァールハイト」Timelineだから可能だった!モバイルに最適化されたリアルタイム3D演出!
PDF
cocos2d-xを利用したパズドラ風ゲームの作成
PDF
Cocos Code IDEを使ってみた
PDF
Cocos2d-JSはイケてる? イケてない?
PDF
JTF2020 クロスコンパイルだけが能ではない組み込みLinuxシステムのCI/CDインフラ構築
Cocos2d-xを用いたゲームアプリ「めちゃギントン」開発の裏側
Cocos2d xで簡単なゲームを作ってみよう!
Cocos2d-x(JS)の紹介
Cocos2d-x勉強会 2014/10/05
Cocos2d-xとSpriteStudioを使った音ゲー開発のお話
Cocos2d-x(JS) ハンズオン #10「3D機能とVR機能」
Cocos2d-x 3D Extension
Cocos2d-x(JS) ハンズオン #12「Cocos2d-xとSpine」
はじめての CircleCI
Cocos2d-x 3.2 Eclipseを利用したAndroid開発環境の構築
cocos2d-x 3.0による変更点
Cocos2d-x(JS) ハンズオン #11「2D物理エンジン」
Cocos2d-xによる最新ゲーム開発
Cocos2d xをさわってみよう!
Cocos2d-x Console @Cocos Talks #3
【Unite Tokyo 2019】「禍つヴァールハイト」Timelineだから可能だった!モバイルに最適化されたリアルタイム3D演出!
cocos2d-xを利用したパズドラ風ゲームの作成
Cocos Code IDEを使ってみた
Cocos2d-JSはイケてる? イケてない?
JTF2020 クロスコンパイルだけが能ではない組み込みLinuxシステムのCI/CDインフラ構築
Ad

Viewers also liked (9)

PPTX
Cocos2d-x(JS) ハンズオン #01 「はじめてのCocos2d-x (JS)」
PDF
DeNA流cocos2d xとの付き合い方
PDF
cocos2dで手軽にアニメーション
PPTX
Cocos2d-x(JS) ハンズオン #07「新エディタ Cocos Creator v1.0」
PDF
個人開発でゲーム一本完成させるまでの苦難の道のり 〜企画編〜
PPTX
ゲーム制作初心者が知るべき8つのこと
PDF
エターナらないゲーム開発
PPTX
Cocos2d-x 3.0を使ったゲーム “消滅都市” の開発事例
PDF
失敗から学ぶゲーム開発(ドラゴンジェネシス〜聖戦の絆〜の場合)
Cocos2d-x(JS) ハンズオン #01 「はじめてのCocos2d-x (JS)」
DeNA流cocos2d xとの付き合い方
cocos2dで手軽にアニメーション
Cocos2d-x(JS) ハンズオン #07「新エディタ Cocos Creator v1.0」
個人開発でゲーム一本完成させるまでの苦難の道のり 〜企画編〜
ゲーム制作初心者が知るべき8つのこと
エターナらないゲーム開発
Cocos2d-x 3.0を使ったゲーム “消滅都市” の開発事例
失敗から学ぶゲーム開発(ドラゴンジェネシス〜聖戦の絆〜の場合)
Ad

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

KEY
Arctic.js
PDF
Flashup13 Basic Training of Flare3D
PDF
Flashup 12 Basic Training of Away3D
KEY
Cocos2d platforms
KEY
HTML5で作るスマホブラウザゲーム
PPTX
Osakijs #01 「enchant.jsハンズオン資料」
PDF
cocos2d-xハンズオン勉強会 in 名古屋
PDF
かんたんなcocos2d-xの紹介
PPT
Html5conference2012 yota hisamichi_世界に向けたスマートフォンゲームを支える、 greeのテクニカルアーティストについて。
PDF
初心者向けJavaScript/HTML5ゲームプログラミング
PDF
enchant.jsでゲーム制作をはじめてみよう
PDF
Creators'night#14今井
PDF
GTMF2012 SpriteStudio と "Unity" と "CoronaSDK" と "ngCore" ! ~組み合わせて改善する 2D ワーク...
PPTX
長寿なゲーム事業におけるアプリビルドの効率化
PDF
ソーシャルゲーム開発パッケージ化とネイティブアプリの取り組みと開発ノウハウ
PDF
ExGame さくっと入門
PDF
「さくらのINFRA WARS」で 利用されている技術
PDF
CocosBuilderとcocos2d-x JSB
PDF
Cocos2d-x公開講座 in 鹿児島
PDF
Arctic.js開発者から見るFlasherの未来
Arctic.js
Flashup13 Basic Training of Flare3D
Flashup 12 Basic Training of Away3D
Cocos2d platforms
HTML5で作るスマホブラウザゲーム
Osakijs #01 「enchant.jsハンズオン資料」
cocos2d-xハンズオン勉強会 in 名古屋
かんたんなcocos2d-xの紹介
Html5conference2012 yota hisamichi_世界に向けたスマートフォンゲームを支える、 greeのテクニカルアーティストについて。
初心者向けJavaScript/HTML5ゲームプログラミング
enchant.jsでゲーム制作をはじめてみよう
Creators'night#14今井
GTMF2012 SpriteStudio と "Unity" と "CoronaSDK" と "ngCore" ! ~組み合わせて改善する 2D ワーク...
長寿なゲーム事業におけるアプリビルドの効率化
ソーシャルゲーム開発パッケージ化とネイティブアプリの取り組みと開発ノウハウ
ExGame さくっと入門
「さくらのINFRA WARS」で 利用されている技術
CocosBuilderとcocos2d-x JSB
Cocos2d-x公開講座 in 鹿児島
Arctic.js開発者から見るFlasherの未来

More from gree_tech (20)

PPTX
アナザーエデンPC版リリースへの道のり 〜WFSにおけるマルチプラットフォーム対応の取り組み〜
PDF
GREE VR Studio Laboratory「XR-UX Devプロジェクト」の成果紹介
PPTX
REALITYアバターを様々なメタバースで活躍させてみた - GREE VR Studio Laboratory インターン研究成果発表
PPTX
アプリ起動時間高速化 ~推測するな、計測せよ~
PPTX
Cloud Spanner をより便利にする運用支援ツールの紹介
PPTX
WFSにおけるCloud SpannerとGKEを中心としたGCP導入事例の紹介
PPTX
SINoALICE -シノアリス- Google Cloud Firestoreを用いた観戦機能の実現について
PPTX
海外展開と負荷試験
PPTX
翻訳QAでのテスト自動化の取り組み
PPTX
組み込み開発のテストとゲーム開発のテストの違い
PPTX
サーバーフレームワークに潜んでる脆弱性検知ツール紹介
PPTX
データエンジニアとアナリストチーム兼務になった件について
PPTX
シェアドサービスとしてのデータテクノロジー
PPTX
「ドキュメント見つからない問題」をなんとかしたい - 横断検索エンジン導入の取り組みについて-
PPTX
「Atomic Design × Nuxt.js」コンポーネント毎に責務の範囲を明確にしたら幸せになった話
PPTX
比較サイトの検索改善(SPA から SSR に変換)
PPTX
コードの自動修正によって実現する、機能開発を止めないフレームワーク移行
PPTX
「やんちゃ、足りてる?」〜ヤンマガWebで挑戦を続ける新入りエンジニア〜
PPTX
法人向けメタバースプラットフォームの開発の裏側をのぞいてみた(仮)
PPTX
基調講演 -グリーが目指すエンジニアのあり方、チームのあり方-
アナザーエデンPC版リリースへの道のり 〜WFSにおけるマルチプラットフォーム対応の取り組み〜
GREE VR Studio Laboratory「XR-UX Devプロジェクト」の成果紹介
REALITYアバターを様々なメタバースで活躍させてみた - GREE VR Studio Laboratory インターン研究成果発表
アプリ起動時間高速化 ~推測するな、計測せよ~
Cloud Spanner をより便利にする運用支援ツールの紹介
WFSにおけるCloud SpannerとGKEを中心としたGCP導入事例の紹介
SINoALICE -シノアリス- Google Cloud Firestoreを用いた観戦機能の実現について
海外展開と負荷試験
翻訳QAでのテスト自動化の取り組み
組み込み開発のテストとゲーム開発のテストの違い
サーバーフレームワークに潜んでる脆弱性検知ツール紹介
データエンジニアとアナリストチーム兼務になった件について
シェアドサービスとしてのデータテクノロジー
「ドキュメント見つからない問題」をなんとかしたい - 横断検索エンジン導入の取り組みについて-
「Atomic Design × Nuxt.js」コンポーネント毎に責務の範囲を明確にしたら幸せになった話
比較サイトの検索改善(SPA から SSR に変換)
コードの自動修正によって実現する、機能開発を止めないフレームワーク移行
「やんちゃ、足りてる?」〜ヤンマガWebで挑戦を続ける新入りエンジニア〜
法人向けメタバースプラットフォームの開発の裏側をのぞいてみた(仮)
基調講演 -グリーが目指すエンジニアのあり方、チームのあり方-

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