Google Developer Day 2010 Japan: Android でリアルタイムゲームを開発する方法:...

Preview:

DESCRIPTION

Android 用ゲームを作るのには、何が必要でしょうか。Android 専用ゲームというのは、どんなゲームでしょうか。Android の様々な端末に対応するのには、どうすればいいでしょうか。このセッションでは Android の成功するゲームの作り方を説明します。ダウンロード回数 120 万回を超える「ワンダのレプリカ島」という横スクロールアクションゲームを利用した、Android 的なゲーム開発方法についての発表になります。技術的な内容だけではなく、ゲームのプラニングや Android マーケットについて説明します。

Citation preview

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– ソースコード、ブログ、など