Android007SourceKafunWarsView

package org.yasrun.game.kafunwars;

import java.util.ArrayList;
import java.util.List;

import org.yasrun.game.kafunwars.objects.Kafun;
import org.yasrun.game.kafunwars.objects.Laser;
import org.yasrun.game.kafunwars.objects.Nose;

import org.yasrun.game.kafunwars.R;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.view.MotionEvent;
import android.view.View;

/**
* 描画用のクラス
*/
public class KafunWarsView extends View implements Updatable {
    private static final int KAFUN_MAX = 100;
    private static final int LASER_MAX = 100;
    private static final int POWER_MAX = 20;
    private static final int TIME_MAX = 100000;
    private static final float TIME_DELTA = 0.1F;
    private static final int NOSE_X = 75;
    private static final int NOSE_Y = 350;

    private Paint myPaint1 = new Paint();
    private Paint myPaint2 = new Paint();

    private Bitmap bmpHana = null;
    private Bitmap bmpKafun = null;
    private List<Kafun> kafuns = null;
    private List<Laser> lasers = null;

    private int touchStartX = 0;
    private int touchStartY = 0;
    private int power = 0;
    private int score = 0;
    private float time = 0;

    private Nose nose = null;

    private boolean gameOver = false;

    private UpdateHandler updateHandler = new UpdateHandler(this);

    /**
     * コンストラクタ
     *
     * @param c
     */
    public KafunWarsView(Context c) {
        super(c);
        setFocusable(true);

        final Resources res = this.getContext().getResources();
        bmpHana = BitmapFactory.decodeResource(res, R.drawable.hana);
        bmpKafun = BitmapFactory.decodeResource(res, R.drawable.kafun);

        myPaint1.setColor(Color.CYAN);
        myPaint1.setStyle(Style.FILL);
        myPaint2.setColor(Color.GREEN);
        myPaint2.setStyle(Style.STROKE);

        init();
    }

    private void init() {
        kafuns = new ArrayList<Kafun>();
        lasers = new ArrayList<Laser>();
        nose = new Nose(NOSE_X, NOSE_Y, 0, 0);
        nose.life = 30;
        gameOver = false;
    }

    /**
     * 処理開始
     */
    public void start() {
        update();
    }

    /**
     * タッチイベント
     */
    public boolean onTouchEvent(MotionEvent event) {

        if (lasers.size() >= LASER_MAX) {
            return true;
        }

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touchStartX = (int) (event.getX());
            touchStartY = (int) (event.getY());
            power = 1;
            break;
        case MotionEvent.ACTION_UP:
            int touchEndX = (int) (event.getX());
            int touchEndY = (int) (event.getY());
            lasers.add(new Laser(touchStartX - 4, touchStartY, touchEndX, touchEndY));
            lasers.add(new Laser(touchStartX, touchStartY, touchEndX, touchEndY));
            lasers.add(new Laser(touchStartX + 4, touchStartY, touchEndX, touchEndY));
            power = 0;
            break;
        case MotionEvent.ACTION_MOVE:
            if (power < POWER_MAX) {
                power++;
            }
            break;
        }

        return true;
    }

    /**
     * メイン
     */
    public void update() {
        if (!gameOver) {
            if (time < TIME_MAX) {
                time += TIME_DELTA;
            }

            if (Math.random() < 0.3 && kafuns.size() < KAFUN_MAX) {
                kafuns.add(new Kafun((int) (Math.random() * 320), 0, (int) (Math.random() * 8) - 4, 8));
            }

            isHit2();

            moveLasers();

            moveKafuns();
        }

        invalidate();

        updateHandler.sleep((int) (TIME_DELTA * 1000.0));
    }

    /**
     * レーザー移動
     */
    private void moveLasers() {
        final List<Laser> deadLasers = new ArrayList<Laser>();

        for (Laser laser : lasers) {
            isHit0(laser);
            laser.move();
            laser.judge();
            if (laser.isDead()) {
                deadLasers.add(laser);
            }
        }

        for (Laser laser : deadLasers) {
            lasers.remove(laser);
        }
    }

    /**
     * 判定1
     *
     * @param laser
     *            レーザー
     */
    private void isHit0(Laser laser) {
        for (Kafun kafun : kafuns) {
            if (!kafun.isDead() && laser.isInner(kafun.X + 4, kafun.Y + 4)) {
                kafun.setDead(true);
                score+=100;
            }
        }
    }

    /**
     * 花粉移動
     */
    private void moveKafuns() {
        final List<Kafun> deadKafuns = new ArrayList<Kafun>();

        for (Kafun kafun : kafuns) {
            if (isHit1(kafun)) {
                kafun.setDead(true);
                score+=100;
            }
            kafun.move();
            kafun.judge();
            if (kafun.life == -5) {
                deadKafuns.add(kafun);
            }
        }

        for (Kafun kafun : deadKafuns) {
            kafuns.remove(kafun);
        }
    }

    /**
     * 判定2
     *
     * @param kafun
     *            判定対象花粉
     * @return レーザーに当たっているかどうか。trueならば当たっている。
     */
    private boolean isHit1(Kafun kafun) {
        boolean result = false;
        for (Laser laser : lasers) {
            if (!kafun.isDead() && laser.isInner(kafun.X + 4, kafun.Y + 4)) {
                result = true;
                break;
            }
        }
        return result;
    }

    /**
     * 判定3
     * 鼻と花粉の当たり判定
     */
    private void isHit2() {
        for (Kafun kafun : kafuns) {
            if (!kafun.isDead() && kafun.life >= 0
                    && kafun.X >= nose.X && kafun.X <= nose.X + bmpHana.getWidth() && kafun.Y >= nose.Y
                    && kafun.Y <= nose.Y + bmpHana.getHeight()) {
                kafun.life = -5;
                nose.life--;
                if (nose.life < 0) {
                    nose.life = 0;
                    gameOver = true;
                }
            }
        }
    }

    /**
     * 描画処理
     */
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.BLACK);

//        myPaint2.setStyle(Style.STROKE);
//        canvas.drawRect(0, 4, 319, 402, myPaint2);

        canvas.drawText("Score: " + Integer.toString(score), 20, 20, myPaint2);

        canvas.drawText("Time: " + String.format("%05d", (int) time), 220, 20, myPaint2);

        myPaint2.setStyle(Style.FILL);
        myPaint2.setColor(Color.RED);
        canvas.drawRect(2,  40, 7, 400, myPaint2);
        myPaint2.setColor(Color.GREEN);
        canvas.drawRect(2, 400 - nose.life * 12, 7, 400, myPaint2);

        canvas.drawBitmap(bmpHana, nose.X, nose.Y, myPaint1);

        if (power > 0) {
            int r = power / 2;
            canvas.drawOval(new RectF(touchStartX - r, touchStartY - r, touchStartX + r, touchStartY + r), myPaint1);
        }

        for (Kafun kafun : kafuns) {
            if (!kafun.isDead()) {
                canvas.drawBitmap(bmpKafun, kafun.X, kafun.Y, myPaint1);
            } else {
                canvas.drawLine(kafun.X, kafun.Y, kafun.X + 8, kafun.Y + 8, myPaint1);
                canvas.drawLine(kafun.X + 8, kafun.Y, kafun.X, kafun.Y + 8, myPaint1);
            }
        }

        for (Laser laser : lasers) {
            canvas.drawLine(laser.X1, laser.Y1, laser.X2, laser.Y2, myPaint1);
        }

        if (gameOver) {
            myPaint2.setColor(Color.GREEN);
            canvas.drawText("Game Over" ,125, 200, myPaint2);
        }
    }
}
最終更新:2011年08月17日 14:24