パナソニックAVCマルチメディアソフト株式会社
         日本Androidの会 日高 正博




             日本Androidの会/日高正博   2010/10/10   1
   日高 正博(ひだか まさひろ)
    ◦ パナソニックAVCマルチメディアソフト株式会社
    ◦ 日本Androidの会/関西支部
   Android開発情報サイト Tech Booster 運営
    http://tec...
1. Androidとゲーム
• 概要/スレッド構成/注意点

2. ゲームでの描画
• SurfaceView/時系列処理

3. メモリ管理
• GC/OOM/確保の方法

4. まとめ

                      日本A...
日本Androidの会/日高正博   2010/10/10   4
ユーザ体験:“たのしい!”のために。
• AndroidマーケットでGameは2番目の人気
• より高速に、より小さく!大きいゲームはアンインストールされやすい

ユーザレスポンス
• 処理には案外時間がかかるものも多い。見せ方を工夫。
 • ...
デーモンスレッド&
 シングル・スレッド・モデル
                             ユーザスレッド

• Mainスレッド(UI Thread   • ユーザスレッド:
 • Activityに関する処理        ...
描画・ロジック・UIでスレッド分割
• 描画/CPU処理などで応答遅延を防ぐ
                                             UI
• タスクの占有はANRの対象(Application        ...
   AsyncTask                メソッド名                             内容
                             onPreExecute()             ...
Android端末のインターフェイス
• キーボード、タッチパネル、センサー、ハードキー

機種が多いので想定が難しい
                                      タッチパ           セン
• スマート...
日本Androidの会/日高正博   2010/10/10   10
Canvas
• 描画にかかわる処理をすべてUIスレッドで行う
• 以下の2つに比べると低速だけど簡単

SurfaceView
• 演算を別スレッドで実施してUIスレッドで描画
• CanvasとSurfaceViewはCPU処理

GLSu...
SurfaceView
• 画面(Surface)を描画する専用スレッドを提供する
  (資源ロックが発生)
• 描画には、SurfaceHolderというインターフェイスを利用

実装
• 描画処理はSurfaceHolderのコールバックと...
ActivityにViewを設定
   public class surfaceViewActivity extends Activity {
     /** Called when the activity is first created...
SurfaceView生成logic
  //SurfaceView生成時に呼び出される
  public void surfaceCreated(SurfaceHolder holder) {
      //初期描画(生成タイミングで描画す...
Runnableインターフェイス
  • ユーザスレッドの作成。別スレッドで時間、移動量を決定
   public class sampleSurfaceView extends SurfaceView
   implements Surfac...
   RunnableインターフェイスのRunメソッド
//スレッドによるSurfaceView更新処理
public void run() {
           while (mLooper != null) {

          ...
   代表的なレイアウトは4つ




                   日本Androidの会/日高正博   2010/10/10   17
   FrameLayoutで上から描画を重ねる

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ...
日本Androidの会/日高正博   2010/10/10   19
ガベージコレクション
• JavaHeapが足りなくなるとメモリ確保のためGCが走る
• 一度GCすると100~200msはゲームが止まる




05-14 17:43:25.916: DEBUG/dalvikvm(51):
        ...
Activityがメモリを食いつぶす
 • 利用可能なメモリは24MB。かならずこの範囲に収める

OutOfMemoryError
 • GCによるメモリ・アロケーション時。
   JavaHeap内で、要求サイズ分の空きが無ければ発生

0...
   Androidのメモリは潤沢ではない
    ◦ 自分が使うメモリ量を計算する
   リアルタイムゲームでは
    開始前に全部のデータを読み込むといい。
    ◦ マップデータ、シナリオ、音声、キャラクターなどなど。
   メ...
日本Androidの会/日高正博   2010/10/10   23
ユーザインターフェイス
• レスポンスを大事に。入力デバイスを選べるように。
• ゲームロジックを分割してマルチスレッド化

View
• 描画はゲーム特性に合わせて最適なものを。
• ボードゲーム:Canvas、リアルタイム系:OpenGL/...
   ご清聴ありがとうございました




                 日本Androidの会/日高正博   2010/10/10   25
Próxima SlideShare
Cargando en…5
×

Android gameprogramming

14.485 visualizaciones

Publicado el

メビック扇町【クリエイティブクラスターフォーラム】スマートフォンフォーラム発表資料/Android開発Tips

0 comentarios
2 recomendaciones
Estadísticas
Notas
  • Sé el primero en comentar

Sin descargas
Visualizaciones
Visualizaciones totales
14.485
En SlideShare
0
De insertados
0
Número de insertados
6.701
Acciones
Compartido
0
Descargas
40
Comentarios
0
Recomendaciones
2
Insertados 0
No insertados

No hay notas en la diapositiva.

Android gameprogramming

  1. 1. パナソニックAVCマルチメディアソフト株式会社 日本Androidの会 日高 正博 日本Androidの会/日高正博 2010/10/10 1
  2. 2.  日高 正博(ひだか まさひろ) ◦ パナソニックAVCマルチメディアソフト株式会社 ◦ 日本Androidの会/関西支部  Android開発情報サイト Tech Booster 運営 http://techbooster.jpn.org/ 65記事を超えて週に3本ペースで増殖中! Twitter Account @mhidaka 日本Androidの会/日高正博 2010/10/10 2
  3. 3. 1. Androidとゲーム • 概要/スレッド構成/注意点 2. ゲームでの描画 • SurfaceView/時系列処理 3. メモリ管理 • GC/OOM/確保の方法 4. まとめ 日本Androidの会/日高正博 2010/10/10 3
  4. 4. 日本Androidの会/日高正博 2010/10/10 4
  5. 5. ユーザ体験:“たのしい!”のために。 • AndroidマーケットでGameは2番目の人気 • より高速に、より小さく!大きいゲームはアンインストールされやすい ユーザレスポンス • 処理には案外時間がかかるものも多い。見せ方を工夫。 • 例:処理中であればスピナー/プログレスバーで通知する • ネットワークアクセス(ライセンスサーバとの通信など) • スコアの保存やデータのバックアップなど 日本Androidの会/日高正博 2010/10/10 5
  6. 6. デーモンスレッド& シングル・スレッド・モデル ユーザスレッド • Mainスレッド(UI Thread • ユーザスレッド: • Activityに関する処理 処理が終わる(return)まで • ライフサイクル プログラムは終了できない • onCreate/OnPause • デーモンスレッド: プログラム終了時にスレッ • 各UIパーツ(Viewなど) ドの実行終了を待たない の描画処理 日本Androidの会/日高正博 2010/10/10 6
  7. 7. 描画・ロジック・UIでスレッド分割 • 描画/CPU処理などで応答遅延を防ぐ UI • タスクの占有はANRの対象(Application • 入力、レスポンス Not Responding) • Activityの処理 • リアルタイムゲームであれば 画面への ユーザ入力 30FPSが理想 フィードバック TimerEvent • 将棋などCPUがんばる系のゲーム logic大事(Android2.2のJIT?) グラフィック logic • 画像処理、エフェクト • ゲームの論理構造 • タッチイベント飛び過ぎ • SurfaceView • 無限ループ onTouchEventの中でSleepする 画像処理 日本Androidの会/日高正博 2010/10/10 7
  8. 8.  AsyncTask メソッド名 内容 onPreExecute() 事前準備の処理を記述する ◦ 非同期処理 doInBackground(Params...) バックグラウンドで行う処理を記述する onProgressUpdate(Progress...) 進捗状況をUIスレッドで表示する処理を記述する onPostExecute(Result) バックグラウンド処理が完了し、UIスレッドに反映す る処理を記述する public class MonochromeTask extends AsyncTask<Bitmap, Integer, Bitmap> { @Override protected Bitmap doInBackground(Bitmap... bitMap) { Bitmap outBitMap = bitMap[0].copy(Bitmap.Config.ARGB_8888, true);  Runnable,Thread ◦ Javaマルチスレッド処理(同期、優先度制御etc)が可能 ◦ Runnableインターフェイス、Threadクラス。あとで解説します 日本Androidの会/日高正博 2010/10/10 8
  9. 9. Android端末のインターフェイス • キーボード、タッチパネル、センサー、ハードキー 機種が多いので想定が難しい タッチパ セン • スマートフォン? TV ? タブレット? ネル サー  おすすめはインターフェイスの変 キー ハード ボード インター キー 換部を持つこと フェイス  開発が進んでからでOK 変換  ユーザ・機器に合わせた設定 input 変更が簡単に logic 日本Androidの会/日高正博 2010/10/10 9
  10. 10. 日本Androidの会/日高正博 2010/10/10 10
  11. 11. Canvas • 描画にかかわる処理をすべてUIスレッドで行う • 以下の2つに比べると低速だけど簡単 SurfaceView • 演算を別スレッドで実施してUIスレッドで描画 • CanvasとSurfaceViewはCPU処理 GLSurfaceView • OpenGLを使った描画処理を行う。非常に高速。 • ハードウェア処理、機種依存が多少あるので注意。地獄。 日本Androidの会/日高正博 2010/10/10 11
  12. 12. SurfaceView • 画面(Surface)を描画する専用スレッドを提供する (資源ロックが発生) • 描画には、SurfaceHolderというインターフェイスを利用 実装 • 描画処理はSurfaceHolderのコールバックとして実装する • SurfaceHolder.Callback.surfaceCreated() • SurfaceHolder.Callback.surfaceChanged() • SurfaceHolder.Callback.surfaceDestroyed() 日本Androidの会/日高正博 2010/10/10 12
  13. 13. ActivityにViewを設定 public class surfaceViewActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new sampleSurfaceView(this)); } } SurfaceViewのコンストラクタ private Bitmap mImage; //コンストラクタ public sampleSurfaceView(Context context) { super(context); getHolder().addCallback(this); mImage = BitmapFactory.decodeResource(getResources(), R.drawable.bakeneko); } 日本Androidの会/日高正博 2010/10/10 13
  14. 14. SurfaceView生成logic //SurfaceView生成時に呼び出される public void surfaceCreated(SurfaceHolder holder) { //初期描画(生成タイミングで描画する必要があるもの) //Canvasの取得(マルチスレッド環境対応のためLock) Canvas canvas = holder.lockCanvas(); Paint paint = new Paint(); paint.setTextSize(24); paint.setColor(Color.WHITE); //描画処理(Lock中なのでなるべく早く) canvas.drawBitmap(mImage, 0, 0, paint); canvas.drawText("TechBooster",0,200,paint); //LockしたCanvasを解放、ほかの描画処理スレッドがあればそちらに。 holder.unlockCanvasAndPost(canvas); } 日本Androidの会/日高正博 2010/10/10 14
  15. 15. Runnableインターフェイス • ユーザスレッドの作成。別スレッドで時間、移動量を決定 public class sampleSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable{ private Thread mLooper; (省略) } //SurfaceView変更時に呼び出される //SurfaceView生成時に呼び出される public void surfaceChanged(SurfaceHolder holder, int{format, int width, int height) { public void surfaceCreated(SurfaceHolder holder) //スレッド処理を開始 if(mLooper != null ){ //スレッドの生成 mHolder = holder; mLooper.start(); } mLooper = new Thread(this); } } 日本Androidの会/日高正博 2010/10/10 15
  16. 16.  RunnableインターフェイスのRunメソッド //スレッドによるSurfaceView更新処理 public void run() { while (mLooper != null) { //描画処理 doDraw(); //位置更新処理 //処理落ちによるスローモーションをさけるため現在時刻を取得 long delta = System.currentTimeMillis() - mTime; mTime = System.currentTimeMillis(); //次の描画位置 int nextPosition = (int)( ( delta / 1000.0 ) * 200 ); //1秒間に200px動くとして //描画範囲の設定 if(mPositionTop + nextPosition < mHeight ){ mPositionTop += nextPosition; } (省略) } } 日本Androidの会/日高正博 2010/10/10 16
  17. 17.  代表的なレイアウトは4つ 日本Androidの会/日高正博 2010/10/10 17
  18. 18.  FrameLayoutで上から描画を重ねる public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FrameLayout frameLayout = new FrameLayout(this); setContentView(frameLayout); frameLayout.addView(new sampleSurfaceView(this),new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); //サンプル表示用のボタンを作成 Button button = new Button(this); button.setText("Start Button"); frameLayout.addView(button, new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } 日本Androidの会/日高正博 2010/10/10 18
  19. 19. 日本Androidの会/日高正博 2010/10/10 19
  20. 20. ガベージコレクション • JavaHeapが足りなくなるとメモリ確保のためGCが走る • 一度GCすると100~200msはゲームが止まる 05-14 17:43:25.916: DEBUG/dalvikvm(51): GC freed 637 objects / 29528 bytes in 86ms 日本Androidの会/日高正博 2010/10/10 20
  21. 21. Activityがメモリを食いつぶす • 利用可能なメモリは24MB。かならずこの範囲に収める OutOfMemoryError • GCによるメモリ・アロケーション時。 JavaHeap内で、要求サイズ分の空きが無ければ発生 05-14 17:16:45.035: INFO/ActivityManager(51): Config changed: { scale=1.0 imsi=310/260 loc=en_US touch=3 keys=2/1/2 nav=3/1 orien=1 layout=18} 05-14 17:16:45.075: ERROR/dalvikvm-heap(187): 2457600-byte external allocation too large for this process. 05-14 17:16:45.075: ERROR/(187): VM won't let us allocate 2457600 bytes…省略… 05-14 17:16:45.204: ERROR/AndroidRuntime(187): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 日本Androidの会/日高正博 2010/10/10 21
  22. 22.  Androidのメモリは潤沢ではない ◦ 自分が使うメモリ量を計算する  リアルタイムゲームでは 開始前に全部のデータを読み込むといい。 ◦ マップデータ、シナリオ、音声、キャラクターなどなど。  メモリリークに気をつける ◦ 意図せずオブジェクトが解放されなくてメモリを握ったままに なることも。 ◦ 手っ取り早いのはDDMSでメモリ量を確認。 パフォーマンス計測はLog.dやTraceViewもおすすめ。 日本Androidの会/日高正博 2010/10/10 22
  23. 23. 日本Androidの会/日高正博 2010/10/10 23
  24. 24. ユーザインターフェイス • レスポンスを大事に。入力デバイスを選べるように。 • ゲームロジックを分割してマルチスレッド化 View • 描画はゲーム特性に合わせて最適なものを。 • ボードゲーム:Canvas、リアルタイム系:OpenGL/SurfaceView メモリ管理 • GCが走るとゲームは止まる • メモリ使用量を把握する、リークはDDMS/MATなどで確認 日本Androidの会/日高正博 2010/10/10 24
  25. 25.  ご清聴ありがとうございました 日本Androidの会/日高正博 2010/10/10 25

×