05 Android 植物人大战僵尸-安放豌豆射手到图层

1. 效果

安放豌豆射手

2.思路

点击豌豆射手卡片,生成卡片,并将触摸事件传递给卡片,以便卡片能移动

2.1 第1触摸事件

Activity 的触摸事件

package com.su.botanywarzombies;

public class MainActivity extends Activity {

    private GameView mGameView;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mGameView.onTouchEvent(event);
    }
2.2 第2触摸事件

mGameView 中的卡片选卡触摸事件

public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 第一图层,背景图和放置状态栏的卡片
        for (BaseModel model : gameLayout1) {
            if (model instanceof TouchAble) {
                if (((TouchAble) model).onTouch(event)) {
                    // true 表示触摸事件到此为止不再响应
                    return true;
                }
            }
        }
2.3 第3触摸事件

豌豆射手卡片被点击事件

public class SeedPea extends BaseModel implements TouchAble {

    @Override
    public boolean onTouch(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            // 判断是否点击了卡片,根据是否焦点在触摸区域范围内
            if (touchArea.contains(x, y)) {
                Log.d("sufadi", "touch seed pea");
                applyEmplacePea();
                return true;
            }

        default:
            break;
        }

        return false;
    }
2.4 第4触摸事件

申请一张卡片,并且获取触摸事件,已方便位移操作

2.4.1 请求安放一个卡片
public class SeedPea extends BaseModel implements TouchAble {

    // 请求安放一个卡片
    private void applyEmplacePea() {
        // 向 GameView图层加
        GameView.getInstance().applyEmplacePea(locationX, locationY);
    }
2.4.3 GameView 新增该卡片
public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {


    public void applyEmplacePea(int locationX, int locationY) {
        synchronized (mSurfaceHolder) {
            // 顶层加入被安放状态的植物
            Log.d("sufadi", "applyEmplacePea add EmplacePea");

            gameLayout1.add(new EmplacePea(locationX, locationY));
        }
    }
2.4.3 GameView 绘制该卡片,见图层 gameLayout1

注意下面的图层是有先后顺序的

public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {


    private void onDrawing(Canvas mCanvas) {
        for (BaseModel model : gameLayout2) {
            model.drawSelf(mCanvas, mPaint);
        }

        // 后画的会覆盖先画的,故位置在gameLayout2下面
        if (gameLayout1 != null && !gameLayout1.isEmpty()) {
            for (BaseModel model : gameLayout1) {
                model.drawSelf(mCanvas, mPaint);
            }
        }

    }
2.4.4 GameView 传递触摸事件

注意下面的图层是有先后顺序的

public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 第一图层,背景图和放置状态栏的卡片
        for (BaseModel model : gameLayout1) {
            if (model instanceof TouchAble) {
                if (((TouchAble) model).onTouch(event)) {
                    // true 表示触摸事件到此为止不再响应
                    return true;
                }
            }
        }

        // 第二图层,安放卡片
        for (BaseModel model : gameLayout2) {
            if (model instanceof TouchAble) {
                if (((TouchAble) model).onTouch(event)) {
                    // true 表示触摸事件到此为止不再响应
                    return true;
                }
            }
        }

        return false;
    }
2.4.5 卡片的移动事件
public class EmplacePea extends BaseModel implements TouchAble {

    // 触摸区域
    private Rect touchArea;

      @Override
    public boolean onTouch(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();

        if (touchArea.contains(x, y)) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                break;
            case MotionEvent.ACTION_MOVE:
                // 卡片位置更新
                locationX = x - Config.peaFlames[0].getWidth() / 2;
                locationY = y - Config.peaFlames[0].getHeight() / 2;

                // 触摸点跟随,重新移到新的位置
                touchArea.offsetTo(locationX, locationY);
                break;
            case MotionEvent.ACTION_UP:

                break;
            default:
                break;
            }
        }

        return false;
    }
2.4.6 上述步骤每60秒不断绘制,故图片顺利移动
public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

@Override
    public void run() {
        while (gameRunFlag) {
            // 这里需要考虑线程同步
            synchronized (mSurfaceHolder) {
                try {
                    // 锁住画布才能绘图
                    mCanvas = mSurfaceHolder.lockCanvas();
                    mCanvas.drawBitmap(Config.gameBg, 0, 0, mPaint);
                    // 放置卡片的起始 X 坐标是 (界面宽度-卡片宽度) / 2
                    mCanvas.drawBitmap(Config.seekBank, (Config.screenWidth - Config.seekBank.getWidth()) / 2, 0, mPaint);

                    onDrawing(mCanvas);

                } catch (Exception e) {
                    // e.printStackTrace();
                } finally {
                    // 解锁并提交
                    mSurfaceHolder.unlockCanvasAndPost(mCanvas);
                }

            }

            try {
                Thread.sleep(60);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

3. Demo 下载

https://github.com/sufadi/BotanyWarZombies

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值