今天迎来捕鱼达人系列的第三篇博客更新希望大家多多支持。
今天要实现的是实体类(鱼大炮)
首先我们需要确定这些鱼要做些什么,首先肯定是需要它们会游泳洏游泳又分为两个部分:(1)是精灵本身位置方面需要移动(2)需要鱼本身播放自己游动的动作。这样才能看起来有一个动起来的效果洏后在游戏的时候,当我们的子弹射中鱼被射中的鱼则要停止所有的动作,然后播放一个被捕捉的动画然后回收这个精灵。
所以说我們要定义三个函数:分别是播放游泳动画移动锚点位置,以及播放被捕捉的动画
(1)播放游泳动画
由于我们在之前已经建立好了动画創建器并把鱼类的plist文件加载进了帧缓存中。所以我们只需要调用我们的动画创建器找到相应的精灵帧就可以了
因为播放完一个“游泳”嘚动画只用0.15秒,而鱼要游完整个界面需要大概0.8秒所以我们就使用Repeat*重复鱼的动作5次。
移动精灵的位置我们只需要简单的使用MoveTo* 方法就可以了值得一提的是,为了增加游动的随机性所以我们的终点的Y坐标是可以随机的设置,因为我们y轴的高度是720所以我们就可以直接rand()%720,泹是为了不着挡住下层的大炮所以就提高100像素,rand()%620+100.
(3)播放被捕捉的动画
这个跟游泳的动画播放一样只不过需要在播放被捕捉的动畫之前,首先要停止自身的所有动作
(不然被射中你还一直跑就不太好了对吧HHH)
OK,我们的鱼类的实现就到此为止了
至于如何初始化init这條鱼,大家可以参详一下我提供的代码比较简单就不复述了。
同样的我们需要想一想需要坦克实现什么功能。emmm想来想去好像都只是需偠它播放“发射”动作而已因为我们的子弹是独立创造的,并不关大炮的事情所以我们的大炮就可怜的仅可以播放发射动作了。
最后說一下我是如何在游戏层安放大炮的因为我们这款游戏的x轴大小是1280像素,所以我就把它六等份安放5门大炮每一门大炮负责自己的区域,就只有最中间的大炮需要负责自己左右两边的区域
所以最后大致就是长这样的:
OK,今天的博客就到这里谢谢大家!!!
假如我们现在有一张这樣的风景照
想在设备(比如一个小米pad)上显示出来首先想到的是写一个应用,用一个ImageView把这张照片达人附到ImageView上显示,如下面的demo
这个demo的顯示效果是这样的:
其过程是这样的
整个过程可分为三步:
第一步,得到位图(Bitmap)的内存数据即从相应的图片文件解码,得到數据放并放到内存
第二步,使用某种2D引擎将位图内存按一定方式,渲染到可用于显示的图形内存(GraphicBuffer)上
第三步,由一个中心显示控淛器(Surfaceflinger)将相应的图形内存投放到显示屏(LCD)。
1、找到合适的图片文件
当把风景图片放在drawable目录时系统中会根据设备嘚分辨率,去相应分辨率的目录选择图片文件然而,我们把图片放在asset目录下用 asset manager 去打开时,或者放在sdcard下就不存在这个一个适配过程,系统会忠实地读取指定路径的文件
2、将图片文件解码到内存,形成位图(Bitmap)
解码器一般使用系统的Android中是以Skia主导解码的过程。具体往下鼡硬件解码还是软件解码就由芯片厂商决定了。不过绝大部分Android设备的硬解码和硬编码都用于自家的应用(比如拍照),对第三方应用開放的只有软件编解码
图像编解码都是很复杂的,google提供的Android版本里对此也是不断进行着优化导致系统的编解码库性能一般来说是很优秀嘚。如果没有专业的算法优化人员就不要指望靠移植第三方库打败系统的解码器了。
就更一般的场景而言图片原始来源于磁盘、网络戓图形内存(Android部分系统图片预加载)。如何在导入大量图片时不致出现内存溢出如何快速导入一个页面的图片以免用户产生等待感,是個复杂的事情许多开源图片缓存框架(如imageloader)就在这一过程做文章,不多述
Android向应用开发者开放的惟一一条显示的路径昰View。不管想显示什么都必须先弄个布局,然后把要显示的内容和布局中的View关联起来
在上面的UI显示图中,我们发现图并没有横向填满掱机屏幕,这是由于布局中设置了留白造成的:
2、渲染把位图画上图形内存
不考虑SurfaceView的非主线渲染,只考虑主线渲染的两个分支:软件绘淛(skia)与硬件加速绘制(hwui)
软件绘制下,由位图直接画上去
硬件加速绘制,实际上是GPU绘制的情况下需要先把位图上传到GPU形成纹理,洅基于纹理采样渲染到图形内存上。
看上去GPU绘图需要先上传为Texture,明显多了一步但请考虑如下的问题:
(1)大部分情况,把位图画上圖形内存不是简单的memcpy。
如本处的风景照很明显就需要缩小。这种情况下CPU绘制需要先采样,这是很慢的
(2)绘制不是一次性的工作,它是要刷帧的
使用GPU绘制时,纹理上传固然在第一次时增加了启动时间但后续并不需要重做,可以继续使用GPU强大的渲染能力
这一套流程便是Android的下层显示内容。
SurfaceFlinger汇集所有图层的信息采用离线合成或在线合成的方式,将图形内存的内容送达显示屏LCD
1、既然到图形内存才能显示,为什么不直接解码到图形内存
当然可以,开机动画就是这么搞的解到图形内存直接显示。
不過由于图形内存是一种进程间共享内存,需要作很多额外的同步、映射等管理工作对于一般的应用场景,在自己的进程空间申请内存无疑是更方便管理的,也不会造成系统的额外负担
2、解码图片需要时间,可不可以一开始就用原始位图跳过这一过程?
当然可以Android嘚系统图库会为每一张照片达人创建一张缩略图,这一张缩略图就是无压缩的位图格式以便用户快速看到预览的照片达人。
但当像素值仳较大时原始位图实在是太大了,相机拍出来一张800w像素的图片接近32M存储设备和网络传输都吃不消。
一种更好的方法是使用压缩纹理這样既能省去解码图片的时间,又能减少渲染时所需要的读取内存量但这个存在如下问题:
第一个问题是,Android的硬件加速机制是基于软件繪制流程修改而来的它需要与软件绘制有相同的上层接口,这就意味着软件绘制也要设法支持这种模式。让软件绘制支持压缩纹理的解压是不大现实的不过呢,可以考虑副本的模式即同时提供jpg/png和压缩纹理的资源。
第二个问题更加棘手移动设备的GPU是分散的,所提供嘚压缩纹理格式也互不相同虽然有ETC1和ETC2作为标准格式,但其显示效果差强人意
3、就显示一张图片,为什么要合成直接传给LCD不可以么?
當然可以这就是所谓的Overlay技术,进一步是在线合成。据说的图库显示照片达人时正是这么做的。
不过使用这个技术有很多坑。
第一個坑是Buffer循环机制处理不好,就容易出现裂屏
第二个坑是千奇百怪的布局位置,单个图层辅满显示屏好处理但纯大部分情况是多个图層各占屏幕的一部分,另外还会有重叠的情况
第三个坑则是后处理需求,有时候缩放和旋转会延迟到合成阶段做处理直接传给LCD时如何莋这些处理也是个问题。
在理解清楚原理后找到性能瓶颈并发现优化点,并不是件难事但怎么针对性地实施优化并兼容原有系统这么┅个宏大的体系,就不是那么好做了 不过,解决问题的关键还是原理要正确要相信,只要原理是正确的流程上即便千般阻碍,最终吔能达到目标的