美文网首页
游编(2)—SurfaceView游戏框架<上>

游编(2)—SurfaceView游戏框架<上>

作者: 奔跑的佩恩 | 来源:发表于2020-08-23 22:16 被阅读0次

    前言

    在上篇我们已经简单介绍了View游戏框架的相关知识,大家有兴趣的话,可以参考
    游编(1)—View游戏框架
    那么今天就让我们来介绍下另一个游戏框架——SurfaceView

    今天涉及的内容有:

    1. SurfaceView简介
    2. 继承SurfaceView实现一个初步的自定义View
    3. SurfaceView绘图后的刷屏方式
    4. 项目结果图
    5. 优化后的MySurfaceView源码

    先来波效果图


    1.gif
    2.gif

    一. SurfaceView简介

    SurfaceView继承自View,具备View的所有特性。当我们要用SurfaceView来绘制游戏界面的话,我们需要写自定义类(以MySurfaceView为例)来继承SurfaceViewSurfaceView的界面绘制及声明周期等是由SurfaceHolder来控制。然后SurfaceView的绘制方法也不是用ViewonDraw()方法了,而是需要些一个自己的绘制方法。我们一般将自定义的界面绘制方法放到SurfaceView声明周期的创建阶段执行。在自定义的绘制方法中,我们需要在绘制之前,用SurfaceHolder实例来锁住画布(锁住是为了防止多线程绘制导致画布显示混乱),然后执行绘制过程,等绘制结束后,又需要用SurfaceHolder实例来解锁画布。

    二.继承SurfaceView实现一个初步的自定义View

    基于以上SurfaceView的基本知识,然后重写ViewonTouchEvent(MotionEvent event)方法拾取屏幕坐标点,让我们实现一个随着屏幕坐标移动的文字功能,则该自定义SurfaceViewMySurfaceView代码如下:

    public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    
        private Context mContext;
        private SurfaceHolder mSurfaceHolder;//用于控制SurfaceView
        private Paint mPaint;
    
        private float mX=100f;
        private float mY=100f;
    
        public MySurfaceView(Context context) {
            super(context,null);
    
            this.mContext=context;
            //初始化SurfaceHolder
            mSurfaceHolder=this.getHolder();
            mSurfaceHolder.addCallback(this);
            //初始化画笔
            mPaint=new Paint();
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setTextSize(50f);
            mPaint.setColor(Color.GREEN);
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            //创建SurfaceView,绘制文字
            myDraw();
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            //SurfaceView改变的监听
    
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            //SurfaceView销毁
    
        }
    
        /**自定义绘制**/
        private void myDraw(){
            LogUtil.i("=======myDraw=========");
            //锁住画布
            Canvas canvas=mSurfaceHolder.lockCanvas();
            //开始绘制
            canvas.drawText("Text Game",mX,mY,mPaint);
            //释放画布
            mSurfaceHolder.unlockCanvasAndPost(canvas);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            mX=event.getX();
            mY=event.getY();
    
            //重新绘制
            myDraw();
    
            //此处一定要返回true
            return true;
        }
    }
    

    然后在TempActivity中调用MySurfaceView,代码如下:

    public class TempActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
    //        setContentView(R.layout.activity_main);
            setContentView(new MySurfaceView(TempActivity.this));
    
        }
    
    }
    

    运行效果图如下:

    1.gif
    这里发现,随着手指移动,在绘制文字的时候,留下很多轨迹。于是边涉及到SurfaceView绘制后刷新的问题。

    三.SurfaceView绘图后的刷屏方式

    刷屏一般是在绘制逻辑之前执行,SurfaceView的通用刷屏方式有4种。

    • 绘制一个画布大小的rect覆盖到canvas上
    • 重绘前在画布上填充一种颜色
    • 重绘前在画布上用RGB绘制画布
    • 每次绘制之前,绘制一张屏幕大小的图片覆盖到画布上

    基于以上几种方式的话,我们优化了MySurfaceView代码,下面看看执行了刷屏代码的最终实现效果:

    2.gif
    此时便实现了跟随手指滑动的文字效果。

    四. 项目结果图

    下面是项目结构图


    image.png

    五, 优化后的MySurfaceView源码

    下面贴出优化后的MySurfaceView代码:

    相关文章

      网友评论

          本文标题:游编(2)—SurfaceView游戏框架<上>

          本文链接:https://www.haomeiwen.com/subject/yqxarktx.html