程序编写步骤:
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;
}