スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

SurfaceViewの使い方3:ボールを描画して動かす

はじめに


前回の記事では、SurfaceViewに対して、定期的にテキストを描画してみました。今回はよりゲームっぽさを出すために、ボール(というか、単なるCircle)をSurfaceView上に描画して、動かしてみます。また、少しだけ高度に動かすために、画面の端に来たら跳ね返るようにしたいと思います。


ボールを描画するために、今回はCanvasクラスのdrawCircleメソッドを使用します。このメソッドは、引数としてX,Y座標と半径、Paintクラスのインスタンスを受け取ると、その情報に従ってCanvas上に円を描画します。このメソッドを、前回の記事のコードのrunメソッド内で呼び出せば、定期的に円を描画できます。後は、引数に与えるX,Y座標をちょっとずつ増やすor減らす処理を行えば、あたかも移動しているように見えます。


プロジェクトの新規作成


いつものようにEclipseを起動して、新規プロジェクトを作成します。「ファイル」→「新規」→「Androidプロジェクト」を選択して、「新規Androidプロジェクト」ウィンドウを表示させます。そして以下を設定します。



  • プロジェクト名:SampleSurViewCycle

  • ビルド・ターゲット:Android 1.6

  • アプリケーション名:Sample Surface View Cycle

  • パッケージ名:jp.sample.SampleSurViewCycle

  • Create Activity:SampleSurViewCycle


リソースレイアウトの修正


今回もリソースレイアウトmain.xmlファイルは使用しないため、修正は無しです。


ソースコードの修正


今回は、前回の記事で用いたソースコードをベースとします。まずは、全体のソースコード。


package jp.sample.SampleSurViewCycle;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class SampleSurViewCycle extends Activity {
// スレッドクラス
Thread mainLoop = null;
// 描画用
Paint paint = null;

// SurfaceViewを描画するクラス
class DrawSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable{
// 円のX,Y座標
private int circleX = 0;
private int circleY = 0;
// 円の移動量
private int circleVx = 5;
private int circleVy = 5;

public DrawSurfaceView(Context context) {
super(context);
// SurfaceView描画に用いるコールバックを登録する。
getHolder().addCallback(this);
// 描画用の準備
paint = new Paint();
paint.setColor(Color.WHITE);
// スレッド開始
mainLoop = new Thread(this);
mainLoop.start();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO 今回は何もしない。
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
// SurfaceView生成時に呼び出されるメソッド。
// 今はとりあえず背景を白にするだけ。
Canvas canvas = holder.lockCanvas();
canvas.drawColor(Color.BLACK);
holder.unlockCanvasAndPost(canvas);
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO 今回は何もしない。
}

@Override
public void run() {
// Runnableインターフェースをimplementsしているので、runメソッドを実装する
// これは、Threadクラスのコンストラクタに渡すために用いる。
while (true) {
Canvas canvas = getHolder().lockCanvas();
if (canvas != null)
{
canvas.drawColor(Color.BLACK);
// 円を描画する
canvas.drawCircle(circleX, circleY, 10, paint);
getHolder().unlockCanvasAndPost(canvas);
// 円の座標を移動させる
circleX += circleVx;
circleY += circleVy;
// 画面の領域を超えた?
if (circleX < 0 || getWidth() < circleX) circleVx *= -1;
if (circleY < 0 || getHeight() < circleY) circleVy *= -1;
}
}
}

}

// アクティビティが生成されたときに呼び出されるメソッド
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new DrawSurfaceView(this));
}

@Override
public void onDestroy() {
super.onDestroy();
Thread.interrupted();
}
}

ボールの描画は、canvas.drawCircle(circleX, circleY, 10, paint);の部分で行います。単に円を単色で描画しているだけですが。


また、ボールの移動をさせるために、ソースコードでは、circleXとcircleYを変更します。


// 円の座標を移動させる
circleX += circleVx;
circleY += circleVy;

こうしておけば、次にrunメソッドが実行されて、canvas.drawCircleメソッドが実行されたときに、前回より少し移動したボールが描画されます。


また、このままでは画面外までボールが移動してしまうため、画面の端に到達したら、跳ね返るようにします。これは、ソースコードの


// 画面の領域を超えた?
if (circleX < 0 || getWidth() < circleX) circleVx *= -1;
if (circleY < 0 || getHeight() < circleY) circleVy *= -1;

getWidth()で画面の幅を、getHeight()で画面の高さを取得できますので、これらのメソッドを利用してcircleXとcircleYが画面内かどうかを判定しています。画面外となる場合は、ボールを移動させる方向を逆方向にします。


実行結果


SurfaceView_04_drawCircle.png


実行すると、白いボールが画面左上から右下へ移動していきます。どんどん右下へ移動していき、画面端までたどり着くと、壁に跳ね返ったように移動していきます。


なお、このプログラムを終わらせるためには、「←」ボタンを押します。


おわりに


SurfaceView上にボールを描いて移動させることで、けっこうゲームチックな感じになってきたと思います。ただし、このままでは単にボールが勝手に反射しているだけなので、何も楽しくありません。なので、次は、ユーザからの操作を受け付けて、ボールの動きを変えるようなプログラムを作っていきたいと思います。




テーマ : プログラミング
ジャンル : コンピュータ

プロフィール

sepiablue

Author:sepiablue
組込みソフトウェアエンジニアやってます。普段はC言語使い。
趣味はプログラミング、京都旅行で神社巡り。
AndroidアプリをMacで開発中。

最新記事
スポンサードリンク
スポンサードリンク
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。