SurfaceViewならAndroidで高速描画ゲームが作れる:Androidで動く携帯Javaアプリ作成入門(12)(1/3 ページ)
本連載で、SDKとEclipseを使ってAndroidの携帯端末で動くJavaアプリを作成し、Android Marketでの配布を目指しましょう
Androidの開発者はスィーツがお好き?
開発コード「Eclair」(エクレア)で呼ばれていたAndroid 2.0が、2009年10月27日にリリースされました(参考:グーグル、Android 2.0対応のSDKリリース)。
直前のバージョン、Android 1.6 Donut(ドーナツ)から1カ月弱でのメジャーアップデートです。Android 2.0で追加された目玉機能は、Bluetooth用のAPIで、これはAndroid 1.0で搭載を見送りされたいわく付きのAPIでもあります。今後、Bluetoothの機能も本連載で扱いますので、楽しみにお待ちください。なお今後は、この連載もAndroid 2.0の環境をベースにしていきます。
余談ですが、Android 1.5の開発コードネームは「Cupcake」(カップケーキ)でしたし、次期バージョン2.1は、「Flan」 (フラン)だそうです。Androidの開発者は、スィーツが好きなのでしょうか? また、Cupcake→Donut→Eclair→Flanとアルファベット順になっているので、「次のコードネームは「G」で始まるスィーツになるのでは」とWeb上で噂になっています。また、Android 1.0に当たる「A」とAndroid 1.1にあたる「B」は何だったのかも気になります。
さて今回は、ゲーム開発には欠かせない「SurfaceView」について説明します。
ゲーム開発には欠かせない「SurfaceView」とは
SurfaceViewというのは、名前からも分かるとおり、Viewのサブクラスです。以前連載第4回の「簡単でワクワクするAndroidウィジェット10連発!」で紹介した「ウィジェット」も、同様にViewのサブクラスですが、それらのウィジェットとSurfaceViewには決定的な違いがあります。
それは、描画の方式が違うのです。パッケージ「android.widget」に属するウィジェットは、アプリケーションのスレッド内で描画が行われるため、定期的に再描画を繰り返すゲームなどには向いていません。一方、SurfaceViewは、アプリケーションのスレッドと描画処理のスレッドが独立しているため、定期的な再描画に向いています。
例外的に、android.widget.VideoViewクラスは、SurfaceViewのサブクラスです。「SurfaceViewが動画再生などの負荷の描画処理に向いている」という一例ですね。
コラム 「Viewでもゲームは作れる」
今回は、SurfaceViewがテーマなのですが、通常のViewクラスでも問題なくゲームは作れます。
通常のViewはinvalidate()を呼び出して、間接的にonDraw(Canvas)を呼び出します。これまでのJava(Java SEやJava ME)は「repaint()」というメソッド名でしたが、AndroidではWindows APIっぽい「invalidate()」というメソッド名が使用されています。
さて、「通常のViewでもゲームは作れる」といいましたが、それでも以下のようなゲームには向きません。
- 3Dを使用したゲーム
- FPSが高いゲーム
今回のデモアプリに、ViewとSurfaceViewをそれぞれ使用した、十字キーでAndroidマスコットが動くサンプルを含めています。このサンプルは、1秒間当たりの描画回数を表示します。
Viewを使用した場合とSurfaceViewを使用した場合で、数倍の開きがあります。そもそも、10fps以下だと、テーブルゲームなどの限られたジャンルしか作れません。
なお、上記画面のAndroidマスコットは、Bitmapクラスで描画しています。「Bitmapを直接Canvasに描画するよりも、Drawableで描画する方が高速である」と聞いたことがあるので、Drawable版もサンプルに含めています。
ただし筆者の環境では、特に顕著な差は現れませんでした。もしかすると、もっと重いBitmapだと差が出るのかもしれません。ぜひ、皆さんの環境でも動作させてみてください。
SurfaceViewの最も簡単な使い方
さて、それではいつものように以下からプロジェクトをダウンロードして、実際に動作させながら読み進めてください。
SurfaceViewの最も簡単な使い方は、「Click」というサンプルにあります。
@Override public void onClick(View v) { Log.d("TEST", "onClick"); SurfaceView surfaceView = (SurfaceView)v; Canvas canvas = surfaceView.getHolder().lockCanvas(); Paint paint = new Paint(); canvas.drawColor(Color.WHITE); paint.setColor(Color.BLUE); paint.setAntiAlias(true); paint.setTextSize(24); canvas.drawText("Hello, SurfaceView!", 0, paint.getTextSize(), paint); surfaceView.getHolder().unlockCanvasAndPost(canvas); }
SurfaceViewには、「getHolder()」というSurfaceHolderを取得するメソッドがあります。さらにSurfaceHolderには、「lockCanvas()」というCanvasを取得するメソッドがあります。ここで取得したキャンバスに自由に描画し、最後にSurfaceHolderのunlockCanvasAndPost(Canvas)を呼び出して描画を完了します。
Canvasのメソッドは、Java SE(java.awt.Canvasクラス)やJava MEのとよく似ているので、直感的に使い方が理解できると思います。
ただし、このサンプルの使い方は、実は一般的ではありません。一般的には、SurfaceViewは継承して使用します。サンプルのHello.javaを見てください。Hello.javaでは、SurfaceViewのサブクラスを定義して、SurfaceHolderにコールバックを設定して、コールバック内で描画を行っています。
次ページでは、Androidのグラフィックスに関する重要なポイントを確認しましょう。
Copyright © ITmedia, Inc. All Rights Reserved.