View游戏框架

程序编写步骤:

      1.创建MyView类,继承于View类,在MyView类中重写父类的构造函数、绘图函数onDraw、按

键按下事件函数onKeyDown、按键抬起事件函数onKeyUp、触屏事件函数onTouchEvent。

      2.修改MainActivity活动类,让屏幕显示MyView类,关键代码在onCreate()函数中:

setContentView(new MyView(this))

基础知识整理:

      1.绘图函数onDraw

      绘图首先要有一个画布,而View类正好提供了一个画布实例,它位于View的绘制函数onDraw的参数中。

protected void onDraw(Canvas canvas)

{

  //创建一个画笔的实例

  Paint paint = new Paint();

  //设置画笔的颜色

  paint.setColor(Color.WHITE);

  //绘制文本

  canvas.drawText("Game",10,10,paint);

  super.onDraw(canvas);

}

      注意,上述的  paint.setColor(Color.WHITE);等同于  paint.setColor(0xffffffff);用十六进制表示颜色值的好处是更加灵活。

      画布类Canvas的drawText函数有4个参数。参数一是String类型,指文本信息;参数二与参数三分别指文本绘制在屏幕的X、Y位置坐标(默认绘制文字以文字的左下角为锚点);参数四是画笔实例。

      为程序设置全屏:隐去状态栏部分和程序的标题栏部分。

this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

this.requestWindowFeature(window.FEATURE_NO_TITLE);

     注意,设置隐藏标题栏需在显示View视图之前完成,否则程序会发生异常。

     关于手机屏幕坐标的问题,无论是横屏还是竖屏,手机最左上角的点永远是(0,0)点;而(0,0)点水平向右是X轴正方向,(0,0)点垂直向下是Y轴的正方向。

     2.按键监听

     游戏中与玩家交互的主要途径就是手机按钮或触屏这两种事件。View视图类中已经封装了这些函数,只需重写按键、触屏监听函数即可获取当前玩家点击的按键或触屏的位置。

     按键监听有onKeyDown和onKeyUp两个函数。触屏监听函数只有onTouchEvent一个。为何触屏函数只有一个?手指按下屏幕和手指离开屏幕是如何监听的?其实触屏监听函数不只是玩家手指按下时触发响应,当手指离开屏幕、手指在屏幕中滑动等动作都可以通过此函数完成监听。

     为了看到动态图像的效果,需要重新绘制画布。View的onDraw函数虽然是绘制函数,但是此函数只是在View视图一开始创建运行的时候执行一遍而已。即使通过按键改变了绘制的文本坐标,所看到的依然是之前的画布,不是最新的画布状态。

     为了重绘画布,View类提供了invalidate函数和postInvalidate()函数,并且这两个函数会再次调用onDraw。两者的区别主要是,invalidate()函数不能在当前线程中循环调用执行,而postInvalidate可以。注意,这里的线程不是系统的主UI线程,而是子线程(自己创建的线程)。

      3.触屏监听

      要让文本随手指移动,那么文本的坐标就永远是玩家手指在手机屏幕上的位置。为了实现该效果,可在触屏监听函数中添加如下代码:

@Override

public boolean onTouchEvent(MotionEvent event)

{

  int x = (int)event.getX();

  int y = (int)event.getY();

  //玩家手指点击屏幕的动作

  if(event.getAction() == MotionEvent.ACCTION_DOWN){

      textX =x;

      textY =y;

      //玩家手指抬起离开屏幕的动作  

  }else if(event.getAction() == MotionEvent.ACTION_MOVE){

      textX =x;

      textY =y;

      //玩家手指在屏幕上移动的动作

  }else if(event.getAction() == MotionEvent.ACTION_MOVE){

      textX =x;

      textY =y;

  }

  //重绘画布

  invalidate();

  //postInvalidate();

  return super.onTouchEvent(event);

}

      为确保当手指在屏幕中进行滑动的时候,坐标随手指移动,需让触屏监听函数的返回值永远为True。修改触屏监听函数:

@Override

public boolean onTouchEvent(MotionEvent event){

    ...

    return true;

}

      触屏监听函数实际上没必要获取用户的动作,因为无论玩家什么动作,都是手指触摸在屏幕上的X、Y坐标的位置,因此可简化程序如下:

@Override

public boolean onTouchEvent(MotionEvent event)

{

  //获取用户手指触屏的X坐标赋值与文本的X坐标

  textX  = (int)event.getX();

  //获取用户手指触屏的Y坐标赋值与文本的Y坐标

  textY  = (int)event.getY();

  //重绘画布

  invalidate();

  //postInvalidate();

  //return super.onTouchEvent(event);

  return true;

}