Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Develop::Client::Game
Search
Smith
August 18, 2016
Programming
1
29
Develop::Client::Game
Introduction of basic knowledge for mobile game development.
Smith
August 18, 2016
Tweet
Share
More Decks by Smith
See All by Smith
Zig なんもわからん 〜あるいは学びのモチベーション〜
dolow
0
350
Go に Generics がやってきた
dolow
0
570
NFT つくってみた
dolow
0
240
プロのエンジニアが1人日を捻出してレトロJRPGっぽいゲームを本気で作った
dolow
0
840
技術中間組織はじめました
dolow
0
94
About triangle
dolow
0
55
Cipher.Mobile
dolow
0
88
Other Decks in Programming
See All in Programming
なぜあの開発者はDevRelに伴走し続けるのか / Why Does That Developer Keep Running Alongside DevRel?
nrslib
3
400
kiroとCodexで最高のSpec駆動開発を!!数時間で web3ネイティブなミニゲームを作ってみたよ!
mashharuki
0
170
私はどうやって技術力を上げたのか
yusukebe
43
18k
Server Side Kotlin Meetup vol.16: 内部動作を理解して ハイパフォーマンスなサーバサイド Kotlin アプリケーションを書こう
ternbusty
3
180
Devvox Belgium - Agentic AI Patterns
kdubois
1
120
Leading Effective Engineering Teams in the AI Era
addyosmani
3
360
アメ車でサンノゼを走ってきたよ!
s_shimotori
0
220
10年もののAPIサーバーにおけるCI/CDの改善の奮闘
mbook
0
820
uniqueパッケージの内部実装を支えるweak pointerの話
magavel
0
1k
Building, Deploying, and Monitoring Ruby Web Applications with Falcon (Kaigi on Rails 2025)
ioquatix
4
2.1k
あなたとKaigi on Rails / Kaigi on Rails + You
shimoju
0
130
Introducing ReActionView: A new ActionView-Compatible ERB Engine @ Kaigi on Rails 2025, Tokyo, Japan
marcoroth
3
1k
Featured
See All Featured
Navigating Team Friction
lara
190
15k
Git: the NoSQL Database
bkeepers
PRO
431
66k
How STYLIGHT went responsive
nonsquared
100
5.8k
A better future with KSS
kneath
239
18k
Raft: Consensus for Rubyists
vanstee
139
7.1k
Gamification - CAS2011
davidbonilla
81
5.5k
GitHub's CSS Performance
jonrohan
1032
470k
Done Done
chrislema
185
16k
Unsuck your backbone
ammeep
671
58k
How to Think Like a Performance Engineer
csswizardry
27
2k
Typedesign – Prime Four
hannesfritz
42
2.8k
The Power of CSS Pseudo Elements
geoffreycrofte
79
6k
Transcript
Develop::Client::Game // 難易度別・これだけは覚えて帰って欲しい // クライアント開発知識
Employee* me = introduce();
#include <time.h> #include <Drecom/Employee.h> using namespace Drecom; Employee* introduce() {
Employee* me = new Employee<Hirashain>(); me->name = “Smith”; me->division = Division::ClientArchitect::GameArchitect; me->role = Occupation::Engineer::Client; { time_t rawtime; time(&rawtime); struct tm* timeinfo = localtime (&rawtime); timeinfo->tm_year = 2011 - 1900; // 正直、覚えてない timeinfo->tm_mon = 10 - 1; timeinfo->tm_mday = 1; me->hireDate = mktime(timeinfo); } return me; }
#include <time.h> #include <Drecom/Employee.h> using namespace Drecom; Employee* introduce() {
Employee* me = new Employee<Hirashain>(); me->name = “Smith”; me->division = Division::ClientArchitect::GameArchitect; me->role = Occupation::Engineer::Client; { time_t rawtime; time(&rawtime); struct tm* timeinfo = localtime (&rawtime); timeinfo->tm_year = 2011 - 1900; // 正直、覚えてない timeinfo->tm_mon = 10 - 1; timeinfo->tm_mday = 1; me->hireDate = mktime(timeinfo); } return me; }
アプリケーションの種別を問わない クライアントサイド技術に関する総合的な部署 ClientArchitect ClientArchitect::GameArchitect ゲーム製作に特化したクライアント開発環境・基盤の 提供、運用、サポートを行うグループ me 趣味は酒とゲームと睡眠
+ 隠しアカウントで3本くらい
AGENDA 1. はじめに 2. ユーザインタラクションとUI || メインループとパフォーマンスチューニング || ネイティヴ連携に挑戦
はじめに 本スライドは、C/C++ (cocos2d-x) での iOS/ Android 向け開発を前提として進行します Unity 環境については特に重要と思われる箇所 以外では言及しません
ユーザインタラクションとUI
- ユーザインタラクションって何? - OpenGL ってなに? - UIってなに?
ユーザインタラクション - タッチ操作 - キー入力 - センサリング など、ユーザ任意の行動による操作
OpenGL iOS/Androidがサポートするレンダリング エンジン 既存のゲームエンジンが対応している (というか他に選択肢がない) アプリのUIは全てOpenGL描画用の ビューコンテナに描画される OSのWebViewなどはOpenGLよりも上に 表示される App
UI OS OpenGL View Other OS View Components
Touch through OpenGL 1. タップ操作する 2. Java/ObjC層で受け取る 3. OpenGLビューに渡される 4.
タップ座標をOpenGL上の座標に 変換する 5. 変換された座標をアプリが受け取る 6. アプリ任意の処理 App UI OS OpenGL View X:342 Y:107 X:171 Y:515
Touch through OpenGL ゲームエンジンが頑張ってくれてる
Application UI
home unit gacha menu main unit news 1 B A
LV xx coin xxxx stone xxx
UI ただ表示して置いておくだけではなく 制御しなければならない
UI input/output 例 home unit gacha menu main unit news
1 B A LV xx coin xxxx stone xxx ホーム画面を表示する (news ボタンが押される) ボタンを押し込んでいる間は ボタン画像が変わる (news ボタンが押し終わる) ボタンを離すとボタン画像が元に戻り ポップアップが前面に表示され始める news 1 News close
UI input/output 例 ホーム画面を表示する (news ボタンが押される) ボタンを押し込んでいる間は ボタン画像が変わる (news ボタンが押し終わる)
ボタンを離すとボタン画像が元に戻り ポップアップが前面に表示され始める プログラム側で実装 (部品は用意されている)
よくあるトラブル - 異常系処理を忘れがち アニメーションの割り込み、同時押しなど - OS View の座標/サイズ合わせを忘れがち - ローカル座標とグローバル座標で混乱しがち
- 動くものができてからしかフィードバックされない
まとめ - ほとんどのゲームエンジンはOpenGLで描画している - OpenGLはOSでサポートされ、 専用のビューコンポーネントに描画される - アニメーションやユーザインタラクションの制御は 全てプログラムから行う -
ユーザ操作がOSからアプリに届くまでは ゲームエンジンが面倒見てくれる - 仕様について不明瞭な点は、キッチリコミュニケーションしておく
メインループと パフォーマンスチューニング
メインループって? - アプリ起動中は継続的に一定周期で走る処理 1/60秒毎のループが一般的 - このループでの計算結果を描画に反映するケースが多い (=ループの末端で描画処理をする) - メインループでのボトルネックはパフォーマンスに直結 いわゆるカクつきと呼ばれるものが生じる
ボトルネック - I/O などの各種 wait - 過多な/不要な計算 - ドローコール過多
よくある解消方法 - 重い処理はアプリ起動時やシーン切替時に行う - 値の変更をストレージに反映する時は ある程度メモリに載せてからまとめて反映する - 別スレッドに処理を逃がす - そもそものロジック・設計を見直す
クライアントアプリのメモリ
server client transaction main loop memory space memory space transaction
memory space transaction memory space transaction memory space main loop main loop main loop main loop main loop main loop
main loop main loop main loop item = new Item();
itemName = item->name; delete item; item = nullptr; itemName = item->name; // error!
メモリ - 一度割り当てたメモリは生き続ける (=手動で破棄しなければならない) - メモリ不足だと何もできない
対策 - メモリ割り当てやリークについて理解しよう - heap の理解をしておこう - メモリ使用量を確認する手段を知っておこう
余談 - UnityではGCが走るので、意識的なメモリ開放をする 機会はあまりない というか、GCが走ってもメモリ領域を開放せず再利用する
まとめ - メインループは 1/60 秒毎に描画処理をしている - 割り当てられたメモリは自動的に破棄されない - 時間のかかる処理を把握する -
メモリを意識したプログラミングをしよう
ネイティヴ連携に挑戦
- スマフォアプリ作ったことある人? - iOS/Android は何の言語で動いている? - クロスプラットフォーム開発って何? - SDK ってなに?
ネイティヴアプリ OS ネイティヴAPI プラットフォーム機能 ネイティヴ用ライブラリ アプリ/ゲーム実装 - ネイティヴ言語で記述 iOS :
Objective-C Android : Java - OSが提供する諸々と OSに提供された諸々が使える - そのOSでしか動かない
クロスプラットフォーム OS ネイティヴAPI プラットフォーム機能 ネイティヴ用ライブラリ アプリ/ゲーム実装 - C/C++ など、ポータビリティの 高い言語で記述
- 複数のプラットフォームで動く - ネイティヴ層と分離される
Java (Android API) Objective-C (Cocoa) Android iOS C/C++ C/C++ JNI
Java SDK Objective-C SDK ネイティヴ連携って? * Swift のフローは割愛
ネイティヴ連携って必要? - サードパーティSDKはほぼ間違いなく入れる 広告系、計測系、配信系、SNS系など ほとんどがJava/Objective-C のライブラリの提供である - プラットフォーム固有機能もほぼ間違いなく入れる 課金、プッシュ通知、実績など これらもネイティヴ言語での実装のみ
- ネイティヴAPIを利用する場合がある パッケージ名/Bundle ID、バージョン番号取得など アップデートチェックや外部アプリ連携で利用するケースが多い
ネイティヴ連携って必要? C/C++ 向けのAPIがなく Java や Objective-C のAPIを 叩かないと実現できない機能の提供
ネイティヴ言語と プラットフォームを理解する
iOS 言語 : Objective-C (or Swift) プラットフォーム機能 : iOS SDK
同梱 IAP や GameCenter、プッシュ通知などの ライブラリは全て含まれている
Android 言語 : Java JNI を経由して C と Java の連携ができる
プラットフォーム機能 : Android SDK 同梱 IAB や Game Play Service、プッシュ通知などの ライブラリは全て含まれているが低レイヤのみ 公式のサンプルコードをコピペして使うことが推奨されている
ネイティヴ連携手段を理解する
iOS Objective-C のソースには C/C++ が書ける C/C++ header (.h) Obj-C header
(.h) C/C++ Obj-C implements (.mm)
iOS Objective-C のソースには C/C++ が書ける C/C++ header (.h) Obj-C header
(.h) C/C++ Obj-C bridge (.mm) Obj-C implements (.m)
Android C/C++ と Java の間のやりとりには JNI を介す C/C++ header (.h)
Java implements (.java) C/C++ bridge (.cpp) JNI C Interface / implements (.c/.cpp)
iOS // call ObjC method void CppClass::doSomeObjCThing() { [ObjCClass doSomeObjCThing];
} // call cpp method + (void) doSomeCppThing { CppClass::doSomeCppThing(); } Ultra extremely Easy !
Android // call Java method void CppClass::doSomeJavaThing() { const char*
className = "jp/co/drecom/JavaClass”; const char* methodName = "doSomeJavaThing”; const char* signature = "()V”; PluginJniMethodInfo info; if (PluginJniHelper::getStaticMethodInfo(info, className, methodName, signature)) { info.env->CallStaticObjectMethod(info.classID, info.methodID); } }
Android class JavaClass { // call cpp method public static
native void doSomeCppThing(); } … JavaClass. doSomeCppThing();
Android extern "C" { // receive JNI native call and
do cpp thing JNIEXPORT void JNICALL Java_jp_co_drecom_JavaClass_doSomeCppThing(JNIEnv* env, jobject obj) { CppClass::doSomeCppThing(); } }; Ultra extremely bothering !
余談 サードパーティSDKでは iOS版とAndroid版でAPIが異なる場合がある e.g. ある値を取得するメソッド iOS : 返り値として返却 Android :
Listener 経由で受け取る この場合、C/C++ のインターフェイスは Listener で受け取るように統一する (逆は不可)
余談 Unity もおんなじ感じ
まとめ - クロスプラットフォーム開発におけるネイティヴ連携は必須 - OS毎に連携方法が異なる - JNIの利用方法を覚えよう - 一度組めば他のアプリに転用できる