marunomaruno-memo

marunomaruno-memo

[Android] 丸が自動的に動く

2012年05月10日 | Android
[Android] 丸が自動的に動く
================================================================================

画面上を○が自動的に動くサンプル。
View クラスをオーバーライドしている以外は、比較的単純なサンプル。


▲ レイアウト

View クラスを継承した CanvasView クラスを使っているので、完全限定クラス名(FQCN)
で要素名を記述している。


□ res/layout/main.xml
---
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <jp.marunomaruno.android.movingcircle.CanvasView
        android:id="@+id/canvasView"
        android:layout_width="match_parent"
        android:layout_height="400px" />

</LinearLayout>
---


▲ アクティビティ

Eclipse が自動生成するものと変わりなし。

□ MovingCircle01Activity.java
---
package jp.marunomaruno.android.movingcircle;

import android.app.Activity;
import android.os.Bundle;

public class MovingCircle01Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}
---


▲ ビュー

View クラスを継承したクラスとして作る。
描画する部分は onDraw() メソッドをオーバーライドして作る。
Thread.sleep() メソッドを利用することで、丸の動きの速さを制御している。
これには、1 ~ 10までの乱数を使う。

□ CanvasView.java
---
package jp.marunomaruno.android.movingcircle;

import java.util.Random;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

/**
 * 丸を自動的に動かす。
 *
 * @author marunomaruno
 * @version 1.0, 2012-05-06
 */
public class CanvasView extends View {

    private int cx;
    private int cy;
    private int radius;

    private int orientationX;
    private int orientationY;

    private Paint paint;

    public CanvasView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public CanvasView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CanvasView(Context context) {
        super(context);
        init();
    }

    /**
     * すべてのコンストラクターで共通の処理。
     */
    private void init() {
        paint = new Paint();
        paint.setColor(Color.YELLOW);
        paint.setAntiAlias(true);

        radius = 30;
        cx = radius;
        cy = radius;

        orientationX = randomInt();
        orientationY = randomInt();
    }

    /**
     * 1~10 までの乱数を返す。
     * @return 1~10 までの乱数
     */
    private int randomInt() {
        return new Random().nextInt(10) + 1;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // 丸を表示する
        canvas.drawCircle(cx, cy, radius, paint);

        // 丸を指定方向に移動する
        cx += orientationX;
        cy += orientationY;

        // 左右の端にぶつかったら反転する
        if (isBorderX()) {
            orientationX *= -1;
        }

        // 上下の端にぶつかったら反転する
        if (isBorderY()) {
            orientationY *= -1;
        }

        // 指定ミリ秒分ウエイトする
        try {
            Thread.sleep(randomInt());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        invalidate();
    }

    /**
     * 横の端かどうかを判断する。
     * @return 端のときは true
     */
    private boolean isBorderX() {
        return isBorder(cx, getWidth());
    }

    /**
     * たての端かどうかを判断する。
     * @return 端のときは true
     */
    private boolean isBorderY() {
        return isBorder(cy, getHeight());
    }

    /**
     * 端かどうかを判断する。
     * @return 端のときは true
     */
    private boolean isBorder(int v, int border) {
        return (v < radius) || (v > border - radius);
    }
}
---

                                                                            以上