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
560
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
意外と簡単!?フロントエンドでパスキー認証を実現する WebAuthn
teamlab
PRO
2
740
私の後悔をAWS DMSで解決した話
hiramax
4
210
GitHubとGitLabとAWS CodePipelineでCI/CDを組み比べてみた
satoshi256kbyte
4
220
ユーザーも開発者も悩ませない TV アプリ開発 ~Compose の内部実装から学ぶフォーカス制御~
taked137
0
150
[FEConf 2025] 모노레포 절망편, 14개 레포로 부활하기까지 걸린 1년
mmmaxkim
0
1.6k
Deep Dive into Kotlin Flow
jmatsu
1
310
1から理解するWeb Push
dora1998
7
1.9k
Vue・React マルチプロダクト開発を支える Vite
andpad
0
110
Go言語での実装を通して学ぶLLMファインチューニングの仕組み / fukuokago22-llm-peft
monochromegane
0
120
Putting The Genie in the Bottle - A Crash Course on running LLMs on Android
iurysza
0
140
Compose Multiplatform × AI で作る、次世代アプリ開発支援ツールの設計と実装
thagikura
0
140
Kiroの仕様駆動開発から見えてきたAIコーディングとの正しい付き合い方
clshinji
1
210
Featured
See All Featured
Build your cross-platform service in a week with App Engine
jlugia
231
18k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
36
2.5k
Visualization
eitanlees
148
16k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.5k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
580
YesSQL, Process and Tooling at Scale
rocio
173
14k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
Building an army of robots
kneath
306
46k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.4k
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の利用方法を覚えよう - 一度組めば他のアプリに転用できる