做过手机游戏(尤其是J2me)的程序员想必对各手机自带的系统字都是深恶痛绝的吧:难看,运行效率低,各个机型还不匹配,移植起来也很麻烦。
一般情况每个公司都是用图片代替,这样虽然是很美观,但是图片在程序里是很占内存的。尤其是做Rpg的时候,这么多的剧情文字不可能全都做成图片吧!
后来我研究了一下点阵字库的实现原理,我觉得也可以模仿一下,做个山寨版的点阵字库。
原理如下:
1 获得每个字的点阵数据
把每个字画出来,转成图片,然后获得每个点的颜色信息,这样就知道这个字的点阵数据。(如图1)
2 把这些点阵数据写到二进制文件里,要用的时候读出这些点阵数据,画字的时候再用画线的方法画出来就行了。

(图1)
至于每个字的数据,可以保存点或线的数据。我是保存的线的数据(因为Java里找不到画点的函数,只有画线的,这样做渐变字的时候也很方便,至于说描边,那就要另外再写算法了)
J2me端的实现:
每个字一个MyWord对象
里面就一个属性byte[][] lineData;
下面是画字函数 也很简单(普通的,没有特效)
public static void drawWord(Graphics g,MyWord word, int x, int y, int color) {
if (word == null) {
return;
}
g.setColor(color);
for (int i = 0; i <word.lineData.length; i++) {
int index = 0;
if (word.lineData[i] != null) {
int len =word.lineData[i].length >> 1;
for (int j = 0; j < len;j++) {
g.drawLine(x +word.lineData[i][index], y, x + word.lineData[i][index + 1], y);
index += 2;
}
}
y++;
}
}
下面是画渐变字的函数,传了一个渐变颜色的数组进去
public staticvoid drawWordEffectA(Graphics g, MyWord word, int x, int y, int[] color) {//渐变
if (word== null) {
return;
}
for (inti = 0; i < word.lineData.length; i++) {
intindex = 0;
g.setColor(color[i]);
if(word.lineData[i] != null) {
int len = word.lineData[i].length >> 1;
for (int j = 0; j < len; j++) {
g.drawLine(x + word.lineData[i][index], y, x + word.lineData[i][index +1], y);
index += 2;
}
}
y++;
}
}
OK,总的来说是很简单的一些算法和应用。但是用到游戏里面去,对游戏的整体效果提高了很多。
比较一下点阵字,系统字,图片,这几个方法的优缺点:
|
|
点阵字 |
系统字 |
图片 |
|
数据文件大小
|
跟字的笔画复杂程度成正比, 一般1个字100字节左右,但打包到Jar时会压掉2/3 |
不会增加Jar的大小 |
文件很小 |
|
占用内存
|
每个字的对象里就一个Byte的二维数组,占用内存小 |
不占用内存,每次画的时候还会消耗额外的内存 |
跟图片的面积成正比,当有很多个字的时候,占用的内存就很恐怖了 |
|
运行速度
|
运行速度慢,在N73真机上平均每个字要1毫秒,但丝毫不影响整体运行效果(不知道还有没有优化的方法) |
运行速度快,但每次画的时候还会消耗额外的内存 |
运行速度很快 |
最后总结一下,如果少量的字还是用图片吧,美观省事运行快。
低性能的机子还是不要用这种点阵字库吧。

浙公网安备 33010602011771号