スポンサーサイト

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

SurfaceViewの使い方4:ユーザがタッチできるようにする

はじめに


前回の記事では、ボールをSurfaceViewに描画して、画面内を跳ね返りながら動かすプログラムを作成しました。ただ、これでは勝手にボールが動くだけのプログラムなので、ユーザがいろいろ操作できるようにしたいと思います。


基本的に、Androidでユーザがタッチパネルにタッチしたことを受け取るためには、onTouchEventメソッドをOverrideしてやることで実現できます。また、キー入力を受け取るためには、onKeyDownやonKeyUpメソッドをOverrideしてやることで実現できます。


そして、いろいろ調べてみると、SurfaceViewクラスでも、onTouchEventなどのメソッドを用いてタッチイベントなどを拾えるそうです。SurfaceViewクラスを継承したクラスで、onTouchEventメソッドをOverrideすることで、タッチイベントを受け取る事ができます。今回は、このonTouchEventをOverrideして、ユーザが画面をタッチしたら、ボールの移動する方向を変えるようなプログラムを作成したいと思います。


プロジェクトの新規作成


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


  • プロジェクト名:SampleSurViewCycle

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

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

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

  • Create Activity:SampleSurViewCycle

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


    今回もリソースレイアウトは使用しません。SurfaceViewクラスを継承したクラスを用いますので。


    ソースコードの修正


    今回修正するコードは、前回の記事のSampleSurfaceViewCycle.javaをベースにして、onTouchEventメソッドのみをOverrideして追加します。コードの全体は以下です。


    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;
    import android.view.MotionEvent;;

    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する
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    // 移動する方向を反転させる
    // onTouchEventでは、以下の動きをとらえる事ができる
    // [ACTION_DOWN] [ACTION_UP] [ACTION_MOVE] [ACTION_CANCEL]
    // 今回はACTION_DOWN(タッチパネルが押されたとき)に、ボールの動きを反転させます
    switch (event.getAction())
    {
    case MotionEvent.ACTION_DOWN:
    circleVx *= -1;
    circleVy *= -1;
    break;
    default:
    break;
    }
    return true;
    }

    @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();
    }
    }

    コードが長くなってしまいましたが、前回の記事と異なるのはonTouchEventメソッドの部分だけです。onTouchEventメソッドを、SurfaceViewクラスを継承したDrawSurfaceViewクラス内でOverrideします。すると、SurfaceView上でタッチした場合に、そのイベントを拾えるようになります。


    onTouchEventメソッドでは、ユーザがどのようなアクションをしたかを判別する事ができます。MotionEvent.ACTION_DOWN・・・タッチしたとき、MotionEvent.ACTION_UP・・・タッチを離したとき、MotionEvent.ACTION_MOVE・・・タッチしながら移動させているとき、等。他にもいろいろイベントを拾えるようです。詳しくは、MotionEvent | Androidを参照すると良いと思います。


    実行結果


    SurfaceView_06_onTouchEvent_01.png

    まずは起動直後。白いボールが画面左上から右下へ移動していきます。前回はこのまま動き続けるだけですが、今回はタッチすると動きが反転するので、エミュレータ上でタッチ(正確にはマウスでクリック)してみます。


    SurfaceView_07_onTouchEvent_02.png

    静止画なので、ボールの動きが反転しているかどうか分かりませんが、上記コードを実行するとうまく動いているようです。もう一度タッチすると、またボールの動きが反転します。これで今回の目的は達成しました。


    おわりに


    今回はSurfaceViewでユーザのタッチイベントを受け付けるようにしました。少しだけ、前回よりゲームチックになったように思います(まだまだしょぼいですが)。ただし、これだけでは、まだまだ使えるレベルではないので、次回はよりゲームチックな要素を取り入れたサンプルを作りたいと思います。





    スポンサーサイト

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

    プロフィール

    sepiablue

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

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