Submit Search
Android gameprogramming
•
2 likes
•
5,707 views
M
Masahiro Hidaka
Follow
メビック扇町【クリエイティブクラスターフォーラム】スマートフォンフォーラム発表資料/Android開発Tips
Read less
Read more
1 of 25
Download now
Downloaded 40 times
More Related Content
Android gameprogramming
1.
日本Androidの会 日高 正博
日本Androidの会/日高正博 2010/10/10 1
2.
日高 正博(ひだか まさひろ) ◦ 日本Androidの会/関西支部 Android開発情報サイト Tech Booster 運営 http://techbooster.jpn.org/ 65記事を超えて週に3本ペースで増殖中! Twitter Account @mhidaka 日本Androidの会/日高正博 2010/10/10 2
3.
1. Androidとゲーム • 概要/スレッド構成/注意点 2.
ゲームでの描画 • SurfaceView/時系列処理 3. メモリ管理 • GC/OOM/確保の方法 4. まとめ 日本Androidの会/日高正博 2010/10/10 3
4.
日本Androidの会/日高正博
2010/10/10 4
5.
ユーザ体験:“たのしい!”のために。 • AndroidマーケットでGameは2番目の人気 • より高速に、より小さく!大きいゲームはアンインストールされやすい ユーザレスポンス •
処理には案外時間がかかるものも多い。見せ方を工夫。 • 例:処理中であればスピナー/プログレスバーで通知する • ネットワークアクセス(ライセンスサーバとの通信など) • スコアの保存やデータのバックアップなど 日本Androidの会/日高正博 2010/10/10 5
6.
デーモンスレッド& シングル・スレッド・モデル
ユーザスレッド • Mainスレッド(UI Thread • ユーザスレッド: • Activityに関する処理 処理が終わる(return)まで • ライフサイクル プログラムは終了できない • onCreate/OnPause • デーモンスレッド: プログラム終了時にスレッ • 各UIパーツ(Viewなど) ドの実行終了を待たない の描画処理 日本Androidの会/日高正博 2010/10/10 6
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.
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.
Android端末のインターフェイス • キーボード、タッチパネル、センサー、ハードキー 機種が多いので想定が難しい
タッチパ セン • スマートフォン? TV ? タブレット? ネル サー おすすめはインターフェイスの変 キー ハード ボード インター キー 換部を持つこと フェイス 開発が進んでからでOK 変換 ユーザ・機器に合わせた設定 input 変更が簡単に logic 日本Androidの会/日高正博 2010/10/10 9
10.
日本Androidの会/日高正博
2010/10/10 10
11.
Canvas • 描画にかかわる処理をすべてUIスレッドで行う • 以下の2つに比べると低速だけど簡単 SurfaceView •
演算を別スレッドで実施してUIスレッドで描画 • CanvasとSurfaceViewはCPU処理 GLSurfaceView • OpenGLを使った描画処理を行う。非常に高速。 • ハードウェア処理、機種依存が多少あるので注意。地獄。 日本Androidの会/日高正博 2010/10/10 11
12.
SurfaceView • 画面(Surface)を描画する専用スレッドを提供する
(資源ロックが発生) • 描画には、SurfaceHolderというインターフェイスを利用 実装 • 描画処理はSurfaceHolderのコールバックとして実装する • SurfaceHolder.Callback.surfaceCreated() • SurfaceHolder.Callback.surfaceChanged() • SurfaceHolder.Callback.surfaceDestroyed() 日本Androidの会/日高正博 2010/10/10 12
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.
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.
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.
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.
代表的なレイアウトは4つ 日本Androidの会/日高正博 2010/10/10 17
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.
日本Androidの会/日高正博
2010/10/10 19
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.
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.
Androidのメモリは潤沢ではない ◦ 自分が使うメモリ量を計算する リアルタイムゲームでは 開始前に全部のデータを読み込むといい。 ◦ マップデータ、シナリオ、音声、キャラクターなどなど。 メモリリークに気をつける ◦ 意図せずオブジェクトが解放されなくてメモリを握ったままに なることも。 ◦ 手っ取り早いのはDDMSでメモリ量を確認。 パフォーマンス計測はLog.dやTraceViewもおすすめ。 日本Androidの会/日高正博 2010/10/10 22
23.
日本Androidの会/日高正博
2010/10/10 23
24.
ユーザインターフェイス • レスポンスを大事に。入力デバイスを選べるように。 • ゲームロジックを分割してマルチスレッド化 View •
描画はゲーム特性に合わせて最適なものを。 • ボードゲーム:Canvas、リアルタイム系:OpenGL/SurfaceView メモリ管理 • GCが走るとゲームは止まる • メモリ使用量を把握する、リークはDDMS/MATなどで確認 日本Androidの会/日高正博 2010/10/10 24
25.
ご清聴ありがとうございました 日本Androidの会/日高正博 2010/10/10 25
Download