google developer day 2010 japan: android でリアルタイムゲームを開発する方法:...
DESCRIPTION
Android 用ゲームを作るのには、何が必要でしょうか。Android 専用ゲームというのは、どんなゲームでしょうか。Android の様々な端末に対応するのには、どうすればいいでしょうか。このセッションでは Android の成功するゲームの作り方を説明します。ダウンロード回数 120 万回を超える「ワンダのレプリカ島」という横スクロールアクションゲームを利用した、Android 的なゲーム開発方法についての発表になります。技術的な内容だけではなく、ゲームのプラニングや Android マーケットについて説明します。TRANSCRIPT
Developer DayGoogle 2010
Developer DayGoogle 2010
Android でリアルタイムゲームを開発する方法:リベンジChris Pruett
Developer DayGoogle 2010
再帰代名詞• Androidの「デベロッパーアドボケイト」です。
–ちょっと無理があるタイトルですが。。。
•グーグル入社前は、ゲーム会社で働く。
– GBA, PS2, PSP, Wii用に約10本のゲーム開発にエンジニアとして参加。
Developer DayGoogle 2010
Developer DayGoogle 2010
第一世代第二世代
端末の種類
• 528mhz ARM11 CPU (約 400mhzに設定)
• Qualcomm MSM7200A など
• OpenGL ES 1.0 / 1.1 + ATI GPU•画面は3.2” HVGA (480x320)
• 30ヘルツ内に約5000頂点*
• 60ヘルツ内に約1024頂点*
Developer DayGoogle 2010
第一世代端末
*Textured, unlit, colored verts
Developer DayGoogle 2010
第二世代端末
*Textured, unlit, colored verts
• 600 mhz - 1 ghz CPUs• Snapdragon, OMAP3• OpenGL ES 2.0, 1.1•画面はWVGA (800x480)
• 30ヘルツ内に約3万頂点*
• 30ヘルツを超えられない端末も存在
Developer DayGoogle 2010
端末の特徴•画面サイズ、解像度
•インプット機能
– トラックボール、十字キー、キーボード、マルチタッチ
– API的に対応しやすい• MotionEvent か KeyEvent
• OpenGL- テクスチャフォーマット: ATITC? PVRTC? ETC1?
- OpenGL バーション
- GL_EXTENSIONS?
Developer DayGoogle 2010
現在のAndroidのバーションの割合
as of 9/1/2010source: http://developer.android.com/resources/dashboard/platform-versions.html
Android 1.5Android 1.6Android 2.1Android 2.2
29%
42%
18%
12%
Android 1.5
Android 1.6
Android 2.1
Android 2.2
• OpenGL ES 1.1– Static VBO, floating point units– Verts, texture, colors– 512x512x16 texture, no mip maps, no compression– Variable scene complexity
Developer DayGoogle 2010
パフォーマンステスト
Developer DayGoogle 2010
HeightMapProfiler
Developer DayGoogle 2010
HeightMapProfiler
Developer DayGoogle 2010
端末比較
32 ms
Results of testing with HeightMapProfiler
Developer DayGoogle 2010
頂点を増やしたテスト
32 ms
Results of testing with HeightMapProfiler
Developer DayGoogle 2010
LODの価値
4 FPS 16 FPS 35 FPS
Developer DayGoogle 2010
パフォーマンスを高める方法•必ずVBOを利用
• VBOの数を減らす
•浮動小数点数の頂点を利用
•テクスチャコンプレッションならETC1
• 2DならOpenGLのdraw_textureエクステンション
• 30ヘルツで遊べるように プランニング
•第一世代端末から第二世代端末までランタイムでスケール
– GL_EXTENSIONSは役に立つ
•第二世代のみの端末用ゲームなら、GLES2.0を利用
Developer DayGoogle 2010
ワンダのレプリカ島の描画方法
Sprites: draw_texture
Background: draw_texture
Tile layers: VBOs
Developer DayGoogle 2010
バックグラウンドの表示
一つのVBOからタイルのスキャンライン
Developer DayGoogle 2010
二つのスレッドの仕組み
Activity
SurfaceHolder
RenderingThread
OpenGL ESContext
GameThread
SoundPool
Android Framework
Input Events
Input Events
Developer DayGoogle 2010
Render Thread
Activity
SurfaceHolder
RenderingThread
OpenGL ESContext
GameThread
SoundPool
Android Framework
Input Events
Input Events
GLSurfaceView
Developer DayGoogle 2010
Activity + GLSurfaceViewpublic class GameActivity extends Activity { private GLSurfaceView mGLView;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
AwesomeGameRenderer renderer = new AwesomeGameRenderer(); mGLView = new GLSurfaceView(this); mGLView.setRenderer(renderer); setContentView(mGLView); }
@Override protected void onPause() { super.onPause(); mGLView.onPause(); }
@Override protected void onResume() { super.onResume(); mGLView.onResume(); }}
Developer DayGoogle 2010
GLSurfaceView.Renderer
class AwesomeGameRenderer implements GLSurfaceView.Renderer { public void onSurfaceCreated(GL10 gl, EGLConfig config) { // One-time GL setup goes here }
public void onSurfaceChanged(GL10 gl, int w, int h) { // Viewport operations go here. }
public void onDrawFrame(GL10 gl) { // Draw the frame }
}
Activity
SurfaceHolder
RenderingThread
OpenGL ESContext
GameThread
SoundPool
Android Framework
Input Events
Input Events
Developer DayGoogle 2010
NDKとの繋がり
NativeCode
NativeCode
Developer DayGoogle 2010
JNIでレンダリングclass AwesomeGameRenderer implements GLSurfaceView.Renderer {
static { System.loadLibrary("nativegamelib"); } private static native void nativeGameInit(); private static native void nativeGameResize(int w, int h); private static native void nativeDrawFrame(); public void onSurfaceCreated(GL10 gl, EGLConfig config) { // One-time GL setup goes here nativeGameInit(); }
public void onSurfaceChanged(GL10 gl, int w, int h) { // Viewport operations go here. nativeGameResize(w, h); }
public void onDrawFrame(GL10 gl) { // Draw the frame nativeDrawFrame(); }
}
Developer DayGoogle 2010
JNIで接続
extern "C" { JNIEXPORT void JNICALL Java_com_package_ AwesomeGameRenderer_nativeGameInit(JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_com_package_ AwesomeGameRenderer_nativeGameResize(JNIEnv * env, jobject obj, jint width, jint height); JNIEXPORT void JNICALL Java_com_package_ AwesomeGameRenderer_nativeDrawFrame(JNIEnv * env, jobject obj);
}
Developer DayGoogle 2010
JNIで接続第二パターンstatic JNINativeMethod methods[] = { {"nativeGameInit", "()V", (void*)nativeGameInit }, {"nativeDrawFrame", "()V", (void*)nativeDrawFrame }, {"nativeGameResize", "(II)V", (void*)nativeRender }, };
/* * Register several native methods for one class. */static int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* gMethods, int numMethods){ jclass clazz; char* className = "com/package/AwesomeGameRenderer";
clazz = env->FindClass(className); if (clazz == NULL) { char error[255]; sprintf(error, "Native registration unable to find class '%s'\n", className); __android_log_print(ANDROID_LOG_ERROR, "AwesomeGame", error); return JNI_FALSE; } if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { char error[255]; sprintf(error, "RegisterNatives failed for '%s'\n", className); __android_log_print(ANDROID_LOG_ERROR, "AwesomeGame", error); return JNI_FALSE; }
return JNI_TRUE;}
Developer DayGoogle 2010
100%NDKモデル
Activity
SurfaceHolder
RenderingThread
OpenGL ESContext
SoundPool
Android Framework
Input Events
Input Events
NativeCode
Developer DayGoogle 2010
EGL Context and Pausing
VRAM
Developer DayGoogle 2010
EGL Context and Pausing
VRAM
Developer DayGoogle 2010
Developer DayGoogle 2010
ワンダのレプリカ島の最初の4ヶ月
0
300,000
600,000
900,000
1,200,000
1,500,000
Mar 9, 2010
Mar 18, 2010
Mar 27, 2010
Ap
r 5, 2010
Ap
r 14, 2010
Ap
r 23, 2010
May 3, 2010
May 12, 2010
May 21, 2010
May 31, 2010
Jun 9, 2010
Jun 18, 2010
Jun 28, 2010
Jul 7, 2010Replica Island: First For Months
Developer DayGoogle 2010
学んだこと:操作設定は必要
Developer DayGoogle 2010
Original Input System
Activity Thread
Input System
Game
MotionEvents
KeyEvents
Track Ball
Developer DayGoogle 2010
Original Input System
Activity Thread
Input System
Game
MotionEvents
KeyEvents
Track Ball
Touch Screen OrientationSensor
Developer DayGoogle 2010
Original Input System
Activity Thread
Input System
Game
MotionEvents
KeyEvents
Track Ball
Touch Screen OrientationSensor
Keyboard
Tilt Controls
D-Pad
Developer DayGoogle 2010
Current Input System
Activity Thread
Input System
Game
MotionEvents
KeyEvents
Input Interface
Raw State
JumpTiltMovement Attack
Developer DayGoogle 2010
これって楽しいだろうか
Developer DayGoogle 2010
ユーザーデータ
Developer DayGoogle 2010
100%NDKモデル
Activity
SurfaceHolder
RenderingThread
OpenGL ESContext
SoundPool
Android Framework
Input Events
Input Events
NativeCode
Developer DayGoogle 2010
Android でしか存在しない仕組み
Activity
SurfaceHolder
RenderingThread
OpenGL ESContext
WebServer
SoundPool
Android Framework
Input Events
Input Events
NativeCode
Developer DayGoogle 2010
“It’s not really about innovation so much as exploring interestingness.”
Jonathan Blow, author of Braid
楽しいゲームには「革新」より「面白さ」のほうが大事
Developer DayGoogle 2010
Android上のゲームダウンロード
Androidマーケットのゲームカテゴリ
• ユーザランキン第2位
• ダウンロードが一番多い
• インプレッションは一番高い
2/19 3/20 4/18 5/18 6/17 7/16 8/14 9/12
Android Daily Game Downloads
Source: Internal Google Data, September 2010
Developer DayGoogle 2010
Useful Links
• http://developer.android.com– 初めに
• http://code.google.com/p/apps-for-android/– SpriteMethodTest, HeightMapProfiler
•http://replicaisland.net– ソースコード、ブログ、など