在android中开发游戏,一般来说,或想写一个复杂一点的游戏,是必须用到SurfaceView来开发的。 经过这一阵子对android的学习,我找到了自已在android中游戏开发的误区,不要老想着用Layout和view去实现,不要将某个游戏 中的对象做成一个组件来处理。应该尽量想着在Canvas(画布)中画出游戏中的背景、人物、动画等。
SurfaceView提供直接访问一个可画图的界面,可以控制在界面顶部的子视图层。SurfaceView是提供给需要直接画像素而不是使用

窗体部件的应用使用的。Android图形系统中一个重要的概念和线索是surface。View及其子类(如TextView, Button)要画在surface上。每个surface创建一个Canvas对象(但属性时常改变),用来管理view在surface上的绘图操作,如画点画线。

还要注意的是,使用它的时候,一般都是出现在最顶层的:The view hierarchy will take care of correctly compositing
with the Surface any siblings of the SurfaceView that would normally appear on top of it.

使用SurfaceView的时候,一般情况下还要对其进行创建,销毁,改变时的情况进行监视,这就要用到SurfaceHolder.Callback.



例子1:

public class BBatt extends SurfaceView implements SurfaceHolder.Callback, OnKeyListener {    private BFairy bFairy;    private DrawThread drawThread;    public BBatt(Context context) {        super(context);        this.setLayoutParams(new ViewGroup.LayoutParams(Global.battlefieldWidth, Global.battlefieldHeight));        this.getHolder().addCallback( this );        this.setFocusable( true );        this.setOnKeyListener( this );        bFairy = new BFairy(this.getContext());    }    public void surfaceChanged(SurfaceHolder holder,int format,int width,int height) {        drawThread = new DrawThread(holder);        drawThread.start();    }    public void surfaceDestroyed(SurfaceHolder holder) {        if( drawThread != null ) {            drawThread.doStop();            while (true) try {                drawThread.join();                break ;            } catch(Exception ex) {}         }    }    public boolean onKey(View view, int keyCode, KeyEvent event) {}}


实例2: 用线程画一个蓝色的长方形。



public class Test extends Activity {    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(new MyView(this));    }    //内部类    class MyView extends SurfaceView implements SurfaceHolder.Callback{        SurfaceHolder holder;        public MyView(Context context) {            super(context);            holder = this.getHolder();//获取holder            holder.addCallback(this);           //setFocusable(true);        }        @Override        public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}        @Override        public void surfaceCreated(SurfaceHolder holder) {            new Thread(new MyThread()).start();        }        @Override        public void surfaceDestroyed(SurfaceHolder holder) {}        //内部类的内部类        class MyThread implements Runnable{            @Override            public void run() {                Canvas canvas = holder.lockCanvas(null);//获取画布                Paint mPaint = new Paint();                mPaint.setColor(Color.BLUE);                canvas.drawRect(new RectF(40,60,80,80), mPaint);                holder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像            }        }    }}


访问SurfaceView的底层图形是通过SurfaceHolder接口来实现的,通过getHolder()方法可以得到这个SurfaceHolder对象。你应该实现surfaceCreated(SurfaceHolder)和surfaceDestroyed(SurfaceHolder)方法来知道在这个Surface在窗口的显示和隐藏过程中是什么时候创建和销毁的。
SurfaceView可以在多线程中被访问。
注意:一个SurfaceView只在SurfaceHolder.Callback.surfaceCreated() 和 SurfaceHolder.Callback.surfaceDestroyed()调用之间是可用的,其他时间是得不到它的Canvas对象的(null)。
我的访问过程:
创建一个SurfaceView的子类,实现SurfaceHolder.Callback接口。
得到这个SurfaceView的SurfaceHolder对象holder。
holder.addCallback(callback),也就是实现SurfaceHolder.Callback接口的类对象。
在SurfaceHolder.Callback.surfaceCreated()调用过后holder.lockCanvas()对象就可以得到SurfaceView对象对应的Canvas对象canvas了。
用canvas对象画图。
画图结束后调用holder.unlockCanvasAndPost()就把图画在窗口中了。
SurfaceView可以多线程访问,在多线程中画图。


如何让 SurfaceView 响应事件,当然创建你自己的类时,你还是得extendsSurfaceView and implementsCallback接口,然后在构造函数里设置一个属性this.setLongClickable(true);//这里很重要,它是让你的设备支持长按效果的属性,如果它为false 的时候MotionEvent 只能监听到ACTION_DOWN这个事件。

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {    private Context mContext;    private SurfaceHolder mHolder;    public TouchScreenAdjusterSurfaceView(Context context,) {        super(context);        mContext = context;        mHolder = TouchScreenAdjusterSurfaceView.this.getHolder();        mHolder.addCallback(TouchScreenAdjusterSurfaceView.this);        this.setFocusableInTouchMode(true); // to make sure that we can get        // touch events and key events,and        // "setFocusable()" to make sure we        // can get key events    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {        // TODO Auto-generated method stub    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        //now you can get the Canvas and draw something here    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        // TODO Auto-generated method stub    }    public void drawMyShape(PointPostion ps) {        mCanvas = mHolder.lockCanvas();       // draw anything you like       mHolder.unlockCanvasAndPost(mCanvas);    }                                                                                                                                                                                                                                              @Override    public boolean onTouchEvent(MotionEvent event){        switch(event.getAction()){            case MotionEvent.ACTION_DOWN:                Log.d("MotionEvent", "ACTION_DOWN");            break;            case MotionEvent.ACTION_UP:                Log.d("MotionEvent", "ACTION_UP");            break;            case MotionEvent.ACTION_MOVE:                Log.d("MotionEvent", "ACTION_MOVE");            break;        }        return super.onTouchEvent(event);    }




更多相关文章

  1. android service 实例
  2. SurfaceView设置透明效果
  3. Android项目:proguard混淆第三方jar.
  4. android之location01
  5. Android(安卓)学习笔记--android――Activity学习
  6. android之蓝牙操作(二)
  7. 【066】Android(安卓)& Java 难点解析
  8. Android(安卓)神兵利器Dagger2使用详解(三)MVP架构下的使用
  9. Android(安卓)rest接口

随机推荐

  1. Android(安卓)ViewTreeObserver简介
  2. Android studio cmd命令行操作数据库文件
  3. Android Service Manager分析
  4. Android防注入研究
  5. android 在开发WebView时,去掉网页的标题
  6. ANDROID 背光调节
  7. Android解析ClassLoader(一)Java中的ClassL
  8. 解决在Android Studio 3.2找不到Android
  9. android闹钟实现原理
  10. Android未调用Looper.prepare()-Can't cr