SlideShare a Scribd company logo
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
Wright Flyer Studios部 西田綾佑
Cocos2d-xを用いた
"LINE タワーライジング" の開発事例
GREE GameDevelopers' Meetup 01
#greegdm01
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• 西田綾佑 (にしだ りょうすけ)
• グリー株式会社 Wright Flyer Studio部
• クライアントリード(エンジニア)
• @hosi_mo
• 塔コード : 4M9EVCBK
• 経歴
• 東京大学大学院情報理工学系研究科 修了
• グリー株式会社(2014年~)
自己紹介
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
ゲーム紹介
配信日 : 2015/6/23
ジャンル : RPG、アドベンチャー
プラットフォーム : iOS / Android
おかげさまで事前登録43万人
▼塔はつんでも、人生つむな
▼頭脳系ダンジョンRPG
▼方向音痴の作者が作った、
新しいスタイルのダンジョン探検
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
実はDungeon Flickerがベースとなった
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
“タワーライジング” リリースまでの開発体制
プロデューサー
1名
クライアントプログラマ
4名
サーバプログラマ
3名
アート
2名
ディレクター(原作)
1名
ゲームデザイナー
2名
PM
3名 16名
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
全体スケジュール(14ヶ月)
2015年
3月~ ダンジョンフリッカー公開
2014年
4月~ α開発 10月~ β開発
β開発 ~1月
1月~ LINE連携
4~6月 チュートリアル改善
6月 GA
社内リリース 社内リリース
11月〜ベンダーテスト
ベンダーテスト ~4月
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• Cocos2d-x 3.2
• コーディング環境
• C++ 11
• Mac + Xcode
• 主にiOSの実機開発(手触りを重視)
• Android
• 動作確認 Android 2.3~ (動作保証は現状4.0)
• なにか起きたらlog catを眺めてスレッドを感じる
開発環境
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• libdispatch
• 並列化したい処理だけキューに投げられて便利
• Cricket Audio
• サウンドの再生。安定してる。
• 他プロジェクト(Cocos2d-x)で実績あり
• Jenkins
• 毎日自動でビルドを作って社内チャットに共有
• Hockey App
• ビルド配布
• クラッシュログ収集
要素技術
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
タワーライジングの開発
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• Cocos2d-xで作り直したい
• ダンジョンフリッカーはAdobe Air
• 画面数が少ない
• 複雑な画面が少ない
• 社内ツール : レイアウトローダ(psd -> Cocos2d-x) を使うほどでもない
• 簡素な演出が好まれた
• LWFを使うほどではない
• 当時 : (送りバントと呼ばれたプロジェクト)
• そもそものアサインが少ない(さらにFlashアニメータ自体が社内に少ない)
開発初期(2014年春~夏)
2014年3月にダンジョンフリッカーをリリース
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• UI配置 : エンジニアが頑張る
• UIアニメーション : エンジニアが頑張る
• 演出 : エンジニアが頑張る
結果
oh. . . .
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
アサインされたエンジニアが面食らう
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
UI配置
おわかりいただけるだろうか?
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
タワーライジングは町工場だから
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• UI
• コードに座標打ってもなんとかなる..かも?
• 演出
• runAction()も、Easingもあるじゃないか
• パペットアニメーションの実現は…
開発初期
エンジニアから職人へのジョブチェンジ
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
アニメーション
安心してください、書いてますよ
Avatar.cpp
1200行くらい
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
なんとかなった理由
①画面がシンプル
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
なぜその①
画面の仕様がシンプル
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
なぜその①
画面の仕様がシンプル
• すべての画面を同一のコンポーネントでつくる
• アニメーションが共通化できる
• SEが共通化できる
• 基本的に9sliceで作りきれる範囲の装飾
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
なんとかなった理由
②仕様書もシンプル
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
なぜその②
一枚絵とにらめっこして作り上げられる
• 仕様書が画像一枚(+注釈)
• 位置もこれがマスター
究極的には
エンジニアがこの一枚絵を完コピすれば良い
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
なんとかなった理由
③Flashで動いている
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• Flashでmockを作ってくれた♥
• ソース見てC++に書き換える
• ASのBetweenライクなWrapperをC++で実装
なぜその③
新規のこまかい演出の実装
tween = BetweenAS3.parallel(
BetweenAS3.tween(part.Finger, {y:range * -0.5}, {y:range * 0.5}, 0.6, Quad.easeInOut),
BetweenAS3.tween(part.Gesture, {y:range * -0.5}, {y:range * 0.5}, 0.6, Quad.easeInOut),
BetweenAS3.tween(part.Gesture, {scaleY:2}, {scaleX:0}, 0.6, Quad.easeInOut)
);
anim = Sequence::create(Spawn::create(Between::to(finger, "y:200", 0.7, Easing::QuadInOut),
Between::to(gesture, "y:200", 0.7, Easing::QuadInOut),
Between::to(gesture, "scaleX:2,scaleY:2", 0.7, Easing::QuadInOut),
NULL),
NULL);
ActionScript
C++
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
なんとかなった理由
④消滅都市先輩がいた
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• クライアントサイド
• 通信
• データベース
• サーバーサイド
• 概ね消滅都市と同等の構成(Silex + MagicSpice)
なぜその④
消滅都市から基本機能を切り出して改良した
エンジニアリングにおける挑戦をしなかった
安全な方向に倒す開発に専念した
その他プロジェクトの偵察を怠らなかった
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
設計のはなし
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• TitleScene
• ログイン処理、データベース構築など
• HomeScene
• ホーム画面 (塔を俯瞰したあの画面)
• DungeonScene
• ダンジョン内
• DecorationScene
• デコレーションする画面
全体の設計
シーン一覧 <CCScene.cpp>
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
ステートの分割
UIの動きに見合うステートマシンもどきを設計した
• Layerの管理
• Stack型の状態管理(ゲームロジック)
• Viewのトランジションも自動化
LayerのPush()とPop()で階層的なUIを管理
StateManager::getInstance()->pushState(レイヤー);
StateManager::getInstance()->popState();
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
ステートの分割
(例)ダイアログの表示と消去
auto dlg1 = DialogOne::create();
StateManager::getInstance()->pushState(dlg1);
StateManager::getInstance()->popState();
(例)ダイアログ1のコールバックを受けてダイアログ2を表示
auto dlg1 = DialogOne::create();
auto dlg2 = DialogTwo::create();
StateManager::getInstance()->pushState(dlg1, [dlg2](StateEvent se){
if (se.Name == DialogOne::YES) {
StateManager::getInstance()->pushState(dlg2);
}
});
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• 階層的な画面が容易に作れた
• ウィンドウの表示・非表示のアニメー
ションが楽に統一化できた
• UIベタ書きでもなんとか持ちこたえた
階層的なUIの実現
そのおかげで
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
特徴的な機能の実装例
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• 地道に1フリックごとに状態を保存
• バトル中は特定のタイミングでス
ナップショットをとっている
• ※暗号化しています
オートセーブ機能
ダンジョン内にいる場合いつでもアプリをkillできる
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• グレースケールで書かれたレンガに
画像を乗算してalpha指定
• 横の壁はSpriteを3軸で歪ませて表現
• レンガのパースが厳密でないので鬼の位置調整
デコレーション
乗算でそれっぽく仕上げる
BlendFunc blend;
blend.src = GL_ZERO;
blend.dst = GL_SRC_COLOR;
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• iOS
• Obj-C
• UIImageで頑張る
• Android
• Java
• Bitmap.createBitmapで頑張る
顔はめ込み機能
両OSでNative Bridge先で端末内の画像をcropする
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• GPUによってはRenderTextureで描画が崩れる(ClippingNode. . .)
• スクショを撮る一瞬だけ不必要なnodeを隠した
• 本当はcropしてシェアしたかった
• 全画面スクショで我慢した
画像シェア機能
Utils::captureScreen
this->node->setVisible(false);
utils::captureScreen([this](bool success, const std::string& output) {
this->node->setVisible(true);
}, "capture.png");
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
パフォーマンス
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• アクションゲームではない
• 30FPSで問題ない
• 演出が激しくない
• 要求されるものがすくない
• がんばらなくてよかった
パフォーマンス
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• アイテム画像全部で500KBくらい
• アートさんがモンスターも1枚1枚減色してくれた
• アセットダウンロード無しで初期リリースを決意
• 結果的に初回起動が早い
あえて言うならば
コンパクトなアートリソース
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
反省
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• やっぱりUIとロジックは切り離したい
• 手書きは慣れると早いけど
• オススメはしない
• 大規模な画面仕様の変更がはいると
• QAを厚くしないと不安で寝れない
• エンジニアが全員職人なわけがない
• アニメーションは書かないと感覚が身につかない
反省点
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
苦労したところ
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• Cocos2d-x 3.2に積んでるlibcurlが古い
• HTTP Status : 200なのにresponseが空っぽ
• オプションによってはタイムアウト時にクラッシュ
• libcurlの乗り換え検討中
• SQLiteのWriteが遅い
• Write前にReadしてハッシュ比較
• 探検中データの下位互換
• Nヶ月前のダンジョン内のデータをちゃんと救えるかどうか
• どうしてもダメになるまでは諦めないけどやはり辛い
苦労したところ
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
おわりに
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
• 今後ともタワーライジングを宜しくお願いします!
• もうすぐ自分の塔33階まで解放します!
おわりに
Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved.
Happy Hacking♥

More Related Content

PPTX
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
PPTX
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
PPTX
[CEDEC2017] LINEゲームのセキュリティ診断手法
PDF
TLS, HTTP/2演習
PDF
プロトタイピングとユーザビリティテストで「UXデザイン」を練りあげよう! | UXデザイン基礎セミナー 第4回
PDF
徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2011
PDF
ゲームの仕様書を書こうまとめ
PDF
サイボウズの CI/CD 事情 〜Jenkins おじさんは CircleCI おじさんにしんかした!〜
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
スマホゲームのチート手法とその対策 [DeNA TechCon 2019]
[CEDEC2017] LINEゲームのセキュリティ診断手法
TLS, HTTP/2演習
プロトタイピングとユーザビリティテストで「UXデザイン」を練りあげよう! | UXデザイン基礎セミナー 第4回
徳丸本に学ぶ 安全なPHPアプリ開発の鉄則2011
ゲームの仕様書を書こうまとめ
サイボウズの CI/CD 事情 〜Jenkins おじさんは CircleCI おじさんにしんかした!〜

What's hot (20)

PPTX
BuildKitによる高速でセキュアなイメージビルド
PDF
C++ マルチスレッドプログラミング
PDF
【Unity道場スペシャル 2017札幌】最適化をする前に覚えておきたい技術 -札幌編-
PPTX
UniRxことはじめ
PDF
Nginxを使ったオレオレCDNの構築
PDF
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
PDF
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
PDF
ノベルゲーム動的演出の考え方
PDF
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
PDF
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
PDF
MagicOnion入門
PDF
ゲーム開発者のための C++11/C++14
PPTX
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
PDF
UnityのクラッシュをBacktraceでデバッグしよう!
PDF
Steam ゲーム内購入 サーバーサイド実装について
PPTX
スマートフォンゲーム企画書制作のポイント
PDF
UIElements+UI BuilderでEditor拡張を作ろう
PDF
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
PDF
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
PDF
UniTask入門
BuildKitによる高速でセキュアなイメージビルド
C++ マルチスレッドプログラミング
【Unity道場スペシャル 2017札幌】最適化をする前に覚えておきたい技術 -札幌編-
UniRxことはじめ
Nginxを使ったオレオレCDNの構築
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
ノベルゲーム動的演出の考え方
データの価値を最大化させるためのデザイン~データビジュアライゼーションの方法~ #devsumi 17-E-2
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
MagicOnion入門
ゲーム開発者のための C++11/C++14
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
UnityのクラッシュをBacktraceでデバッグしよう!
Steam ゲーム内購入 サーバーサイド実装について
スマートフォンゲーム企画書制作のポイント
UIElements+UI BuilderでEditor拡張を作ろう
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
UniTask入門
Ad

Similar to Cocos2d-xを用いた "LINE タワーライジング" の開発事例 (20)

PPTX
Cocos2d-x 3.0を使ったゲーム “消滅都市” の開発事例
PPTX
消滅都市 Cocos2d-xでの演出・UIあれこれ
PDF
福井スマートフォンハッカソン Titanium Mobileの紹介
PDF
第5回業開中心会議
PPTX
クリエイター魂を刺激する!シンラが提案する「ゲームの超進化」ロードマップ
PDF
DeNA流cocos2d xとの付き合い方
PDF
「電車でGO!!」アーケード大型3画面筐体で実在の街並みを表現するUE4開発事例
PDF
Cedec2015 お客様に驚きを提供する運営 消滅都市の事例から-
PDF
「AROW」お披露目(実用編)
PPTX
技術選択とアーキテクトの役割 (要約版)
PDF
Cedec2015_「消滅都市」運用の一年
PDF
アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現
PDF
プライベートクラウド作ってみました
PDF
Windows 8 Developers カンファレンス
PDF
Titanium Mobile ~本当にあったこわい話~
PDF
ニフティクラウドを使った安定運用のススメ
PDF
KinectやRealSenseの概要とさまざまな使い方
PDF
IkaLog Presentation for BMD users
PDF
Automation with SoftLayer and Zabbix
PDF
ソニーのディープラーニングツールで簡単エッジコンピューティング
Cocos2d-x 3.0を使ったゲーム “消滅都市” の開発事例
消滅都市 Cocos2d-xでの演出・UIあれこれ
福井スマートフォンハッカソン Titanium Mobileの紹介
第5回業開中心会議
クリエイター魂を刺激する!シンラが提案する「ゲームの超進化」ロードマップ
DeNA流cocos2d xとの付き合い方
「電車でGO!!」アーケード大型3画面筐体で実在の街並みを表現するUE4開発事例
Cedec2015 お客様に驚きを提供する運営 消滅都市の事例から-
「AROW」お披露目(実用編)
技術選択とアーキテクトの役割 (要約版)
Cedec2015_「消滅都市」運用の一年
アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現
プライベートクラウド作ってみました
Windows 8 Developers カンファレンス
Titanium Mobile ~本当にあったこわい話~
ニフティクラウドを使った安定運用のススメ
KinectやRealSenseの概要とさまざまな使い方
IkaLog Presentation for BMD users
Automation with SoftLayer and Zabbix
ソニーのディープラーニングツールで簡単エッジコンピューティング
Ad

More from gree_tech (20)

PPTX
アナザーエデンPC版リリースへの道のり 〜WFSにおけるマルチプラットフォーム対応の取り組み〜
PDF
GREE VR Studio Laboratory「XR-UX Devプロジェクト」の成果紹介
PPTX
REALITYアバターを様々なメタバースで活躍させてみた - GREE VR Studio Laboratory インターン研究成果発表
PPTX
アプリ起動時間高速化 ~推測するな、計測せよ~
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
法人向けメタバースプラットフォームの開発の裏側をのぞいてみた(仮)
アナザーエデン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-xを用いた "LINE タワーライジング" の開発事例

  • 1. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. Wright Flyer Studios部 西田綾佑 Cocos2d-xを用いた "LINE タワーライジング" の開発事例 GREE GameDevelopers' Meetup 01 #greegdm01
  • 2. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • 西田綾佑 (にしだ りょうすけ) • グリー株式会社 Wright Flyer Studio部 • クライアントリード(エンジニア) • @hosi_mo • 塔コード : 4M9EVCBK • 経歴 • 東京大学大学院情報理工学系研究科 修了 • グリー株式会社(2014年~) 自己紹介
  • 3. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. ゲーム紹介 配信日 : 2015/6/23 ジャンル : RPG、アドベンチャー プラットフォーム : iOS / Android おかげさまで事前登録43万人 ▼塔はつんでも、人生つむな ▼頭脳系ダンジョンRPG ▼方向音痴の作者が作った、 新しいスタイルのダンジョン探検
  • 4. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. 実はDungeon Flickerがベースとなった
  • 5. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. “タワーライジング” リリースまでの開発体制 プロデューサー 1名 クライアントプログラマ 4名 サーバプログラマ 3名 アート 2名 ディレクター(原作) 1名 ゲームデザイナー 2名 PM 3名 16名
  • 6. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. 全体スケジュール(14ヶ月) 2015年 3月~ ダンジョンフリッカー公開 2014年 4月~ α開発 10月~ β開発 β開発 ~1月 1月~ LINE連携 4~6月 チュートリアル改善 6月 GA 社内リリース 社内リリース 11月〜ベンダーテスト ベンダーテスト ~4月
  • 7. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • Cocos2d-x 3.2 • コーディング環境 • C++ 11 • Mac + Xcode • 主にiOSの実機開発(手触りを重視) • Android • 動作確認 Android 2.3~ (動作保証は現状4.0) • なにか起きたらlog catを眺めてスレッドを感じる 開発環境
  • 8. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • libdispatch • 並列化したい処理だけキューに投げられて便利 • Cricket Audio • サウンドの再生。安定してる。 • 他プロジェクト(Cocos2d-x)で実績あり • Jenkins • 毎日自動でビルドを作って社内チャットに共有 • Hockey App • ビルド配布 • クラッシュログ収集 要素技術
  • 9. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. タワーライジングの開発
  • 10. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • Cocos2d-xで作り直したい • ダンジョンフリッカーはAdobe Air • 画面数が少ない • 複雑な画面が少ない • 社内ツール : レイアウトローダ(psd -> Cocos2d-x) を使うほどでもない • 簡素な演出が好まれた • LWFを使うほどではない • 当時 : (送りバントと呼ばれたプロジェクト) • そもそものアサインが少ない(さらにFlashアニメータ自体が社内に少ない) 開発初期(2014年春~夏) 2014年3月にダンジョンフリッカーをリリース
  • 11. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • UI配置 : エンジニアが頑張る • UIアニメーション : エンジニアが頑張る • 演出 : エンジニアが頑張る 結果 oh. . . .
  • 12. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. アサインされたエンジニアが面食らう
  • 13. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. UI配置 おわかりいただけるだろうか?
  • 14. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. タワーライジングは町工場だから
  • 15. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • UI • コードに座標打ってもなんとかなる..かも? • 演出 • runAction()も、Easingもあるじゃないか • パペットアニメーションの実現は… 開発初期 エンジニアから職人へのジョブチェンジ
  • 16. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. アニメーション 安心してください、書いてますよ Avatar.cpp 1200行くらい
  • 17. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. なんとかなった理由 ①画面がシンプル
  • 18. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. なぜその① 画面の仕様がシンプル
  • 19. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. なぜその① 画面の仕様がシンプル • すべての画面を同一のコンポーネントでつくる • アニメーションが共通化できる • SEが共通化できる • 基本的に9sliceで作りきれる範囲の装飾
  • 20. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. なんとかなった理由 ②仕様書もシンプル
  • 21. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. なぜその② 一枚絵とにらめっこして作り上げられる • 仕様書が画像一枚(+注釈) • 位置もこれがマスター 究極的には エンジニアがこの一枚絵を完コピすれば良い
  • 22. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. なんとかなった理由 ③Flashで動いている
  • 23. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • Flashでmockを作ってくれた♥ • ソース見てC++に書き換える • ASのBetweenライクなWrapperをC++で実装 なぜその③ 新規のこまかい演出の実装 tween = BetweenAS3.parallel( BetweenAS3.tween(part.Finger, {y:range * -0.5}, {y:range * 0.5}, 0.6, Quad.easeInOut), BetweenAS3.tween(part.Gesture, {y:range * -0.5}, {y:range * 0.5}, 0.6, Quad.easeInOut), BetweenAS3.tween(part.Gesture, {scaleY:2}, {scaleX:0}, 0.6, Quad.easeInOut) ); anim = Sequence::create(Spawn::create(Between::to(finger, "y:200", 0.7, Easing::QuadInOut), Between::to(gesture, "y:200", 0.7, Easing::QuadInOut), Between::to(gesture, "scaleX:2,scaleY:2", 0.7, Easing::QuadInOut), NULL), NULL); ActionScript C++
  • 24. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. なんとかなった理由 ④消滅都市先輩がいた
  • 25. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • クライアントサイド • 通信 • データベース • サーバーサイド • 概ね消滅都市と同等の構成(Silex + MagicSpice) なぜその④ 消滅都市から基本機能を切り出して改良した エンジニアリングにおける挑戦をしなかった 安全な方向に倒す開発に専念した その他プロジェクトの偵察を怠らなかった
  • 26. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. 設計のはなし
  • 27. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • TitleScene • ログイン処理、データベース構築など • HomeScene • ホーム画面 (塔を俯瞰したあの画面) • DungeonScene • ダンジョン内 • DecorationScene • デコレーションする画面 全体の設計 シーン一覧 <CCScene.cpp>
  • 28. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. ステートの分割 UIの動きに見合うステートマシンもどきを設計した • Layerの管理 • Stack型の状態管理(ゲームロジック) • Viewのトランジションも自動化 LayerのPush()とPop()で階層的なUIを管理 StateManager::getInstance()->pushState(レイヤー); StateManager::getInstance()->popState();
  • 29. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. ステートの分割 (例)ダイアログの表示と消去 auto dlg1 = DialogOne::create(); StateManager::getInstance()->pushState(dlg1); StateManager::getInstance()->popState(); (例)ダイアログ1のコールバックを受けてダイアログ2を表示 auto dlg1 = DialogOne::create(); auto dlg2 = DialogTwo::create(); StateManager::getInstance()->pushState(dlg1, [dlg2](StateEvent se){ if (se.Name == DialogOne::YES) { StateManager::getInstance()->pushState(dlg2); } });
  • 30. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • 階層的な画面が容易に作れた • ウィンドウの表示・非表示のアニメー ションが楽に統一化できた • UIベタ書きでもなんとか持ちこたえた 階層的なUIの実現 そのおかげで
  • 31. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. 特徴的な機能の実装例
  • 32. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • 地道に1フリックごとに状態を保存 • バトル中は特定のタイミングでス ナップショットをとっている • ※暗号化しています オートセーブ機能 ダンジョン内にいる場合いつでもアプリをkillできる
  • 33. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • グレースケールで書かれたレンガに 画像を乗算してalpha指定 • 横の壁はSpriteを3軸で歪ませて表現 • レンガのパースが厳密でないので鬼の位置調整 デコレーション 乗算でそれっぽく仕上げる BlendFunc blend; blend.src = GL_ZERO; blend.dst = GL_SRC_COLOR;
  • 34. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • iOS • Obj-C • UIImageで頑張る • Android • Java • Bitmap.createBitmapで頑張る 顔はめ込み機能 両OSでNative Bridge先で端末内の画像をcropする
  • 35. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • GPUによってはRenderTextureで描画が崩れる(ClippingNode. . .) • スクショを撮る一瞬だけ不必要なnodeを隠した • 本当はcropしてシェアしたかった • 全画面スクショで我慢した 画像シェア機能 Utils::captureScreen this->node->setVisible(false); utils::captureScreen([this](bool success, const std::string& output) { this->node->setVisible(true); }, "capture.png");
  • 36. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. パフォーマンス
  • 37. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • アクションゲームではない • 30FPSで問題ない • 演出が激しくない • 要求されるものがすくない • がんばらなくてよかった パフォーマンス
  • 38. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • アイテム画像全部で500KBくらい • アートさんがモンスターも1枚1枚減色してくれた • アセットダウンロード無しで初期リリースを決意 • 結果的に初回起動が早い あえて言うならば コンパクトなアートリソース
  • 39. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. 反省
  • 40. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • やっぱりUIとロジックは切り離したい • 手書きは慣れると早いけど • オススメはしない • 大規模な画面仕様の変更がはいると • QAを厚くしないと不安で寝れない • エンジニアが全員職人なわけがない • アニメーションは書かないと感覚が身につかない 反省点
  • 41. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. 苦労したところ
  • 42. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • Cocos2d-x 3.2に積んでるlibcurlが古い • HTTP Status : 200なのにresponseが空っぽ • オプションによってはタイムアウト時にクラッシュ • libcurlの乗り換え検討中 • SQLiteのWriteが遅い • Write前にReadしてハッシュ比較 • 探検中データの下位互換 • Nヶ月前のダンジョン内のデータをちゃんと救えるかどうか • どうしてもダメになるまでは諦めないけどやはり辛い 苦労したところ
  • 43. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. おわりに
  • 44. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. • 今後ともタワーライジングを宜しくお願いします! • もうすぐ自分の塔33階まで解放します! おわりに
  • 45. Copyright © 2015 Wright Flyer Studios, Inc. All Right Reserved. Happy Hacking♥