第一种方法:在midp1.0中,使用setClip设置一个具体的裁剪区域,drawImage进行绘制,绘制之前再setClip回原来的裁剪区域。绘制时,如果图像是x*y像素,setClip之后,还需要遍历(循环)x*y,这样效率不高。
第二种:J2me资源利用率。只要有改进的空间,人们就会努力去改进。Midp2.0之后,有一个裁剪API,Image.createImage(Image image, int x, int y, int width, int height, int transform),可以用来从一张大图中裁剪出小图,如果原图是透明的,裁剪出来的图也会是透明的。这样,每次画图的时候,直接调用drawImage就可以把要画的块画出来了。比如画数字艺术图9527,只需要事先把0-9的图片裁剪好放到内存中,把数字9游戏策划,5,2,7,一共4张图画出来就可以了。试想一下,用midp1.0来画,不但要不断setClip,而且每次都要把整个图(0-9)画出来,一共4次。Midp2.0显然效率高很多。
参考《移动游戏开发宝典》
第二种绘制方法在理论上绝对是绝妙且正确的。但在实际开发中手机游戏开发全书,还是要谨慎使用。并不是因为有些机器不支持MIP2.0(现在玩游戏用的手机大部分都支持MIP2.0),真正的原因是以下两点:
1 我们再回过头来看第二种方法,大家发现问题了吗?很明显,这是一个空间和效率的矛盾,效率提高了,但是占用了内存。(这里的手机内存是指运行Java程序时,最大可用的堆栈内存)。手机内存并不充裕,如果把每一幅整图都切分成块存放在内存中,很多机型是处理不了的。不管一款游戏有多好,在电脑上开发出来,在模拟器上测试一下,都是很爽的,如果不能在手机上运行,在主流手机上运行,或者换句话说,在大众不能使用的手机上运行手机游戏开发全书,就赚不到钱,就是一个失败的游戏!相信很多公司都在用印度人开发的动作编辑器-MotionWelder,在使用其自带的类读取.anu文件时,就会把图片切成这样,一定要小心。
2 在真机上测试时,使用midp2.0的Image.createImage(Image image, int x, int y, int width, int height, int transform),绘制到手机上的效果在很多机型上都得到了很好的支持。在所有品牌中,我目前的经验告诉我,索尼爱立信对Sun标准的支持最为完美。但有些机型就不那么好了。比如诺基亚的n73系列有时会出现白色的底边;如果放到Nokia7370系列中,就很不幸了,全部都是不知名的彩色底边,一点都不透明!号称支持2.0,但实际上支持并不完美。
从以上可以看出,第二种方法应谨慎使用。
第一种方法已经足够满足所有机型的绘制需求了。同时我们再来看看第一种方法,看看它的效率,是不是真的很低效呢?这个效率低下其实也不是很低:jvm在绘制的时候,如果发现不在裁剪区域内,就不会绘制。而且每张图片都是一个像素一个像素的绘制,绘制是非常耗资源的,不绘制就意味着不消耗资源,只不过是增加了一个是否在裁剪区域的判断而已。绘制的效率远不如判断。所以,第一种方法的效率差别不大。
同时第一个方法告诉我们,在绘制的时候,使用setClip裁剪出一个刚好是游戏屏幕大小的区域会提高效率。
历史就停滞不前了吗?只使用midp1.0的第一种方法绘制?当然不是。第一种方法需要不断使用setClip设置裁剪,很烦人,绘制完之后还得设置回原来没有裁剪的区域。midp2.0提供了drawRegion方法硬件设备,给我们提供了很好的解决办法。drawRegion可以等于setClip和drawImage。而且在效率上,二者差不多。当然drawRegion也不是万能的,在Nokia 7610系列上绘制的时候,如果翻转的话,速度会很慢,这时候就可以使用Nokia的DirectGraphics来解决问题,当然效率提高了,但是不是很高。不翻转的情况下使用drawRegion是很快的。目前的经验告诉我,只有7610系列在翻转drawRegion的时候会慢一些,其他都不会,大家可以放心使用drawRegion。
在开发过程中,如果需要适配 Nokia 7610 系列(这款手机的用户还是不少),这个型号的 CPU 并不快,所以尽量不要做翻转绘制,最好让美工多画一个方向,当然过多、零散的绘制虽然能提高速度,但也会增加内存,降低可移植性,这都是平衡的问题。
既然是讨论,当然会有争议,所以如果可以的话,欢迎网友们提出不同的观点,共同讨论。