連載
» 2009年12月08日 00時00分 UPDATE

Androidで動く携帯Javaアプリ作成入門(12):SurfaceViewならAndroidで高速描画ゲームが作れる (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)を呼び出します。これまでのJavaJava SEJava ME)は「repaint()」というメソッド名でしたが、AndroidではWindows APIっぽい「invalidate()」というメソッド名が使用されています。

さて、「通常のViewでもゲームは作れる」といいましたが、それでも以下のようなゲームには向きません。

  • 3Dを使用したゲーム
  • FPSが高いゲーム

今回のデモアプリに、ViewとSurfaceViewをそれぞれ使用した、十字キーでAndroidマスコットが動くサンプルを含めています。このサンプルは、1秒間当たりの描画回数を表示します。

図1 ケース1:ジェスチャーとして認識されたケース 図1 View(左)とSurfaceView(右)のFPSの違い

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のグラフィックスに関する重要なポイントを確認しましょう。

       1|2|3 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。