写在开始:如果您没时间详细阅读,可直接选读加粗文字和图片;或先收藏本文,作为今后参考。
我们已经知道,在Android应用中,图片不仅可以使用ImageView来显示,也可作为Button、Window的背景。图片的格式包括不限于*png、*.jpg、*.gif等各种格式的位图。
除了已有的图片外,android应用还常需要在运行时动态生成图片,例如一个手机游戏。
而所谓的游戏动画,其实就是不断地重复调用View组件的onDraw(Canvas canva)方法,如果每次在View组件上绘制的图形不相同,那么就成了我们常说的动画。
这是我上一学期(大二)学习Win32编程时的课程设计作业,加入了双缓冲、游戏循环等小技能。做这个游戏也是为了怀念小学时玩的第一个游戏——QQ堂。
如今加入android开发学习,当然要尝试开发android游戏啦。开发前,先来了解android绘图的常用基础API(应用程序编程接口):Canvas、Path。
Canvas:
重写onDraw()方法时首先涉及一个绘图API:Canvas,Canvas代表“依附”于指定View的画布,它提供了一系列方法用作绘制点、线、圆、矩形、位图等各种图形,部分方法如下:
除此之外,Canvas还提供了一些方法进行坐标转换,如旋转、缩放变换,感兴趣的读者可以查阅安卓官方文档。
Canvas提供的方法还涉及一个API:Paint,Paint代表Canvas上的画笔,相当于Win32中的HPEN。所以Paint类主要用于设置绘制风格,包括画笔颜色、画笔笔触粗细、填充风格等。Paint提供了如下所示的方法:
Path:
在Canvas提供的绘制方法中还用到了一个API:Path。Android提供的Path是一个非常有用的类,它可以预先在View上将N个点连成一条“路径”,然后调用Canvas的drawPath(path,paint)方法即可沿着路径绘制图形。
Android还为路径绘制提供了PathEffect来定义绘制效果,这里不再赘余。
绘制游戏动画:
之前已经提到,在android应用中绘制几何图形,关键在于自定义一个View组件,并重写View组件的onDraw(Canvas)方法。
游戏动画无非是在此基础上让View组件上绘制的图形发生改变(位置、大小、角度等等),这就需要程序采用变量“记住”这些状态数据。
1)如果需要游戏动画随用户操作而改变,就为用户的动作编写事件监听器(如按键触发事件),在监听器中修改这些数据。
2)如果需要游戏动画随时间的流逝“自动”改变,那就需要使用定时器(Timer),让Timer控制这些状态数据定期改变。
无论使用哪种方式,每次View组件上的图形状态数据发生改变时,都应该通知View调用onDraw(Canvas canvas)方法重绘该组件。通知View重绘可调用invalidate(在UI线程中)或postInvalidate(在非UI线程中)。
下面开发一个简单的弹球游戏,通过这个实例来对android游戏动画有一个直观的认识。
小球和球拍分别以圆形区域和矩形区域代替,小球开始以随即速度向下运动,遇到边框或球拍时反弹;球拍则由用户控制,当用户按下左、右键,球拍会左、右移动。
MainActivity代码已上传:弹球游戏源码 具体我们分以下五部分细讲。
·1 变量初始化
程序最开始,我们先做初始化操作,定义一些全局变量,如桌面大小、小球速度、运动方向等,均已详细注释。
·2 工作空间初始化
接着我们在onCreate()中加入逻辑处理,首先是创建GameView组件,在setContentView()中替代原来的activity_main布局。
然后获取窗口管理器管理当前窗口,并将屏幕的宽、高赋给变量tableWidth、tableHeight。这里还定义了一个Handler接受子线程发送的数据来更新UI,这是为了在定时器中修改小球坐标后进行重绘(刷新)。
·3 响应键盘消息
这部分code非常简单,先获取用户触发的按键,然后对全局变量做相应的处理;如果按enter键就退出程序。记得在处理完后一定要调用invalidate()函数对View进行重绘。
·4 设置定时器
Timer是一种定时器工具,用来在后台线程计划执行指定任务。
在Timer中存放对小球坐标的操作,让小球自己能够“动起来”。同时对游戏是否结束做逻辑判断,最后发送一条消息通知系统重绘组件,timer.schedule()第三个参数“100”表示100毫秒重绘一次。
·5 重写onDraw方法
绘图继承自View组件,并重写onDraw方法。在onDraw方法中,定义画笔Paint的属性,并绘制小球、球拍,最终在画布Canvas上显示出来。我们直接看到的图形效果就产生自这一方法。
本实例完整代码到此结束。当前的弹球游戏还略显粗糙,但我们只要找一些精美图片替换程序中的小球、球拍,再设置一些障碍物以及小球碰撞边界、球拍时的音效,游戏就会变得生动起来。
当然,以上内容只是android庞大的图形与图像处理技术中的冰山一角,作为第一个练手的android游戏倒是不错。
我常调侃自己,从玩第一个游戏到开发第一个游戏(都是QQ堂)用了10年。随着编程基础的累积,今后的开发之路依旧充满荆棘但注定畅通光明。本学期个人打算再做一个类似的经典游戏,例如合金弹头、黄金矿工,再加上网络技术....
总之,边学习边充实最终代码化。
今后,我会继续深入学习android开发知识,并尽己所能把相关知识分享给更多的读者。欢迎您持续关注。
作者:叶琛
一只痴迷旅行的大三程序狗