zoukankan      html  css  js  c++  java
  • SurfaceView绘图机制

    虽然前面都使用的View来进行绘图,但View绘图机制存在两个缺陷:

    1、缺乏双缓冲机制

    2、更新图像时,必须更新View上的整张图片,效率低。

    所以在游戏绘制中推荐使用SurfaceView。它可以只对指定区域进行更新,可以提高效率。下面用一个简单示例来演示SurfaceView的使用:

    Activity:

    package com.home.activity; 
      
    import android.app.Activity; 
    import android.graphics.Bitmap; 
    import android.graphics.BitmapFactory; 
    import android.graphics.Canvas; 
    import android.graphics.Color; 
    import android.graphics.Paint; 
    import android.graphics.Rect; 
    import android.os.Bundle; 
    import android.view.MotionEvent; 
    import android.view.SurfaceHolder; 
    import android.view.SurfaceHolder.Callback; 
    import android.view.SurfaceView; 
    import android.view.View; 
    import android.view.View.OnTouchListener; 
      
    import com.home.surfaceviewtest.R; 
      
    public class SurfaceViewActivity extends Activity { 
        // SurfaceHolder负责维护SurfaceView上绘制的内容  
        private SurfaceHolder holder; 
        private Paint paint; 
      
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main); 
            paint = new Paint(); 
            // 获取SurfaceView实例  
            SurfaceView surface = (SurfaceView) findViewById(R.id.main_sv); 
            // 初始化SurfaceHolder对象  
            holder = surface.getHolder(); 
            holder.addCallback(new Callback() { 
                //当surface将要被销毁时回调该方法  
                @Override 
                public void surfaceDestroyed(SurfaceHolder holder) { 
      
                } 
                //当surface被创建时回调该方法  
                @Override 
                public void surfaceCreated(SurfaceHolder holder) { 
                    // 锁定整个SurfaceView  
                    Canvas canvas = holder.lockCanvas(); 
                    // 获取背景资源  
                    Bitmap bitmap = BitmapFactory.decodeResource( 
                            SurfaceViewActivity.this.getResources(), 
                            R.drawable.image2); 
                    // 绘制背景  
                    canvas.drawBitmap(bitmap, 0, 0, null); 
                    // 绘制完成,释放画布,提交修改  
                    holder.unlockCanvasAndPost(canvas); 
                    // 重新锁两次,避免下次lockCanvas遮挡  
                    holder.lockCanvas(new Rect(0, 0, 0, 0)); 
                    holder.unlockCanvasAndPost(canvas); 
                    holder.lockCanvas(new Rect(0, 0, 0, 0)); 
                    holder.unlockCanvasAndPost(canvas); 
                } 
                //当一个surface的格式或大小发生改变时回调该方法  
                @Override 
                public void surfaceChanged(SurfaceHolder holder, int format, 
                        int width, int height) { 
      
                } 
            }); 
            surface.setOnTouchListener(new OnTouchListener() { 
      
                @Override 
                public boolean onTouch(View v, MotionEvent event) { 
                    // 只处理按下事件  
                    if (event.getAction() == MotionEvent.ACTION_DOWN) { 
                        int cx = (int) event.getX(); 
                        int cy = (int) event.getY(); 
                        // 锁定SurfaceView的局部区域,只更新局部内容  
                        Canvas canvas = holder.lockCanvas(new Rect(cx - 60, 
                                cy - 60, cx + 60, cy + 60)); 
                        // 保存canvas的当前状态  
                        canvas.save(); 
                        // 旋转画布  
                        canvas.rotate(30, cx, cy); 
                        paint.setColor(Color.RED); 
                        // 绘制红色方块  
                        canvas.drawRect(cx - 40, cy - 40, cx, cy, paint); 
                        // 恢复canvas之前的保存状态  
                        canvas.restore(); 
                        paint.setColor(Color.GREEN); 
                        // 绘制绿色方块  
                        canvas.drawRect(cx, cy, cx + 40, cy + 40, paint); 
                        // 绘制完成,释放画布,提交修改  
                        holder.unlockCanvasAndPost(canvas); 
                    } 
                    return false; 
                } 
            }); 
        } 
      
    } 
     
    package com.home.activity;
     
    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.os.Bundle;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    import android.view.SurfaceHolder.Callback;
    import android.view.SurfaceView;
    import android.view.View;
    import android.view.View.OnTouchListener;
     
    import com.home.surfaceviewtest.R;
     
    public class SurfaceViewActivity extends Activity {
     // SurfaceHolder负责维护SurfaceView上绘制的内容
     private SurfaceHolder holder;
     private Paint paint;
     
     @Override
     protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      paint = new Paint();
      // 获取SurfaceView实例
      SurfaceView surface = (SurfaceView) findViewById(R.id.main_sv);
      // 初始化SurfaceHolder对象
      holder = surface.getHolder();
      holder.addCallback(new Callback() {
       //当surface将要被销毁时回调该方法
       @Override
       public void surfaceDestroyed(SurfaceHolder holder) {
     
       }
       //当surface被创建时回调该方法
       @Override
       public void surfaceCreated(SurfaceHolder holder) {
        // 锁定整个SurfaceView
        Canvas canvas = holder.lockCanvas();
        // 获取背景资源
        Bitmap bitmap = BitmapFactory.decodeResource(
          SurfaceViewActivity.this.getResources(),
          R.drawable.image2);
        // 绘制背景
        canvas.drawBitmap(bitmap, 0, 0, null);
        // 绘制完成,释放画布,提交修改
        holder.unlockCanvasAndPost(canvas);
        // 重新锁两次,避免下次lockCanvas遮挡
        holder.lockCanvas(new Rect(0, 0, 0, 0));
        holder.unlockCanvasAndPost(canvas);
        holder.lockCanvas(new Rect(0, 0, 0, 0));
        holder.unlockCanvasAndPost(canvas);
       }
       //当一个surface的格式或大小发生改变时回调该方法
       @Override
       public void surfaceChanged(SurfaceHolder holder, int format,
         int width, int height) {
     
       }
      });
      surface.setOnTouchListener(new OnTouchListener() {
     
       @Override
       public boolean onTouch(View v, MotionEvent event) {
        // 只处理按下事件
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
         int cx = (int) event.getX();
         int cy = (int) event.getY();
         // 锁定SurfaceView的局部区域,只更新局部内容
         Canvas canvas = holder.lockCanvas(new Rect(cx - 60,
           cy - 60, cx + 60, cy + 60));
         // 保存canvas的当前状态
         canvas.save();
         // 旋转画布
         canvas.rotate(30, cx, cy);
         paint.setColor(Color.RED);
         // 绘制红色方块
         canvas.drawRect(cx - 40, cy - 40, cx, cy, paint);
         // 恢复canvas之前的保存状态
         canvas.restore();
         paint.setColor(Color.GREEN);
         // 绘制绿色方块
         canvas.drawRect(cx, cy, cx + 40, cy + 40, paint);
         // 绘制完成,释放画布,提交修改
         holder.unlockCanvasAndPost(canvas);
        }
        return false;
       }
      });
     }
     
    }

    布局XML:

    LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:orientation="vertical"> 
      
        <SurfaceView
            android:id="@+id/main_sv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/> 
      
    </LinearLayout> 
     
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
     
        <SurfaceView
            android:id="@+id/main_sv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
     
    </LinearLayout>
  • 相关阅读:
    PHP中的error
    回调函数与PHP实例
    PHP的基本入门知识
    Java script OOP——浅谈
    实现单行或多行文本溢出显示省略号
    ECharts
    session management会话管理的原理
    easyui 入门指南
    H5视频/音频
    CSS清除浮动各种方法
  • 原文地址:https://www.cnblogs.com/a354823200/p/3998731.html
Copyright © 2011-2022 走看看