01 Android 植物人大战僵尸-画个方块

1. SurfaceView

更新的速度特别快,可以直接从内存或者DMA等硬件接口中取得图像数据的绘图容器

可以在主线程之外的线程中向屏幕绘图上,可以避免绘图任务繁重导致主线程阻塞,从而提高程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等尽量在canvas绘制

2.SurfaceView 与View 的区别

SurfaceView 是在一个新的起的线程中绘制画面,而View必须在UI中绘制更新画面。可以理解为SurfaceView的更新不需要在主线程中进行,这样就可以避免主线程来做大量的界面更新操作,引起ANR(主线程的界面更新的消息队列中存在大量的更新界面请求)

实际开发中,高级UI和低级UI并用

3.SurfaceView的使用

  1. 继承SurfaceView并实现SurfaceHolder.Callback接口

所有绘图工作必须在Surface被创建之后才能爱上,而在Surface被销毁之前必须结束,所以Callback中的SurfaceCreated和SurfaceDestroyer就成了绘图处理代码的边界

Surface是显卡内存的映射

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

SurfaceHolder 为surfaceView的控制器,用来操纵surface。处理他的Canvas上画的效果和动画,控制表面,大小,像素

注意点:
- 2.1 abstact void addCallback(SurfaceHolder.Callback callBack)
给SurfaceView 当前持有者一个回调事件,通过这个建立纽带

mSurfaceHolder = getHolder();
// 设置操作回调事件
mSurfaceHolder.addCallback(this);
  • 2.2 abstractCanvas lockCanvas()
    锁定画布,一般锁定后就可以通过其返回的画布对象Canvase,在其上面画图等操作
// 锁住画布才能绘图
mCanvas = mSurfaceHolder.lockCanvas();
mCanvas.drawRect(50, 50, 100, 100, mPaint);
  • 2.3 abstract Canvas lockCanvas(Rect dirty)
    锁定画布的某个区域进行画图等,因为画完图后,会调用下面的unlockCanvasAndPost来改变显示内容

相对部分内存要求比较高的游戏来说,可以不用重画dirty外的其他区域的像素,可以提高速度

  • 2.4 abstract void unlockCanvasAndPost(Canvas canvas)
    结束锁定画图,并提交改变
// 解锁并提交
mSurfaceHolder.unlockCanvasAndPost(mCanvas);

4.SurfaceView的生命周期

在SurfaceView的派生类中,使用geHolder方法来获取SurfaceHolder对象,向addCallBack来添加回调函数

surfaceChanged:在surfaceView的大小发生改变的时候回调

surfaceCreated:在创建Surface时回调

surfaceDestroyed:在销毁Surface时激发

5.画一个方块

package com.su.botanywarzombies;

import com.su.botanywarzombies.view.GameView;

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


public class MainActivity extends Activity {

    private GameView mGameView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGameView = new GameView(this);

        setContentView(mGameView);

    }

}

GameView 的基本使用方法

package com.su.botanywarzombies.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

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

    public static final String TAG = GameView.class.getSimpleName();

    private boolean gameRunFlag;

    // 绘图画笔
    private Paint mPaint;
    // 绘图画布
    private Canvas mCanvas;

    private SurfaceHolder mSurfaceHolder;

    public GameView(Context context) {
        super(context);

        gameRunFlag = true;
        mPaint = new Paint();
        mSurfaceHolder = getHolder();
        // 设置操作回调事件
        mSurfaceHolder.addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        Log.d(TAG, "surfaceCreated");
        new Thread(this).start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        Log.d(TAG, "surfaceDestroyed");
        gameRunFlag = false;
    }

    @Override
    public void run() {
        while (gameRunFlag) {
            // 这里需要考虑线程同步
            synchronized (mSurfaceHolder) {
                try {

                    // 锁住画布才能绘图
                    mCanvas = mSurfaceHolder.lockCanvas();

                    int color = mPaint.getColor();
                    mPaint.setColor(Color.RED);

                    mCanvas.drawRect(50, 50, 100, 100, mPaint);
                    // 好习惯画笔复位
                    mPaint.setColor(color);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    // 解锁并提交
                    mSurfaceHolder.unlockCanvasAndPost(mCanvas);
                }

                try {
                    // 视频达到24帧,1秒24帧图片,肉眼是感受不到变化
                    Thread.sleep(60);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        }
    }
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

法迪

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

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

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

打赏作者

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

抵扣说明:

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

余额充值