posts - 0,  comments - 0,  trackbacks - 0
发贴心情
关于使用调色板进行手机游戏的开发

公司倒闭,心情特别不好,3年多的经历回想起来真是感慨万千。

打算把自己的一些经验写出来,以抛砖引玉,希望对各位有所帮助。

同时也想问问,哪里需要开发人员,我也好找口饭吃:)

以下为正文,暂时先写这么多,以后慢慢写出来...........

关于使用调色板进行手机游戏的开发( j2me 以及 Symbian 平台)

                       作者: zjstu

                       联系方式 :zjstu@sohu.com

                       QQ:29715774

调色板贴图与位图贴图的特点描述( j2me Image Symbian CFbsBimap

Graphics.drawImage();

J2me 的贴图函数 drawImage ()以及 Symbian c++ 的贴图函数 GC.Bitblt() 函数贴图的好处: ( 以下只说 j2me)

1.  简单,贴图函数算法全部内部实现,只需要进行函数参数调用。

2.  J2me 平台可以使用 game 包(虽然我从来不用 :

但是,这种简单的贴图函数却有不少的缺点

1.  底层被封装,使得开发人员不能对底层数据进行操作 .( 比如 alpha 混合,灰度,对象换色 )

2.  占用内存大,以现在的主流彩色手机为例子 , 一般的彩屏手机为 4096 色、 65000 色甚至 24 万色, 4096 色格式的 444 位模式, 65000 色为 565 的格式,那么,每一个象素必须占用 16 为,即 2 byte ,更不用说 24 万色模式了。

3.  贴图速度慢,对于单个位图的绘画, J2ME 平台上的绘画速度是和贴图的次数相关,这样就限制了游戏画面的细腻度,所以经常可以看见很多游戏使用 32X32 的块图。

调色板贴图描述 :

缺点

1.  实现复杂 , 前期开发时间长。必须自己实现图片的绘画,包括总共 8 个方向的翻转。 ( 做的我吐血,但是好处多多 )

2.  速度的不确定,比如,在 nokia 平台,以前的老 40CPU 比较慢,自己实现的象素贴图就非常慢,明显不如系统的贴图函数,但在 6600,7610 60 平台就基本持平了。

 
 
ip地址已设置保密
2006-9-12 12:03:00

好处就多了:

1.  支持象素级的访问,alpha混合,人物变色,角色透明等都很简单了,而不需要象png图片一样非要存一个alpha通道,并且永远不能变.

2.  占用内存小,因为一个象素只占用一个byte,所以一般用调色板做一张图片大体只需要原来位图占用内存的一半。

3.  速度快,这个快有点不绝对,相对的来说,如果游戏使用的图层越多,那么用Graphics.drawImage()肯定就会非常慢。在此我对比我做的一个游戏,在nokia 7610平台,采用8层背景图层,加上大约10个角色贴图,不采用任何的优化算法,耗时100-120ms之间。

4.  可以完全杜绝j2me的内存出错这个bug。当然,自己必须实现游戏的内存管理。

另外:可能会有人疑问,png图片是经过压缩的,但自己做的调色板完全不用png,那打包的jar文件不就很大么?完全没问题,因为png图片与jar文件的压缩算法都是ziplz77压缩算法,所以当你的txt文件存储进jar中时会进行压缩,压缩比基本上与png一样。

 

另外,如果游戏中可以不使用线程 ( 比如 nokia 的手机就可以不用 ) ,也尽量不要用。因为 java 虚拟机中本身也有个时钟周期 ( 此时钟周期非 CPU 的时钟周期,只是我随便叫个名字而已 ) ,并且比线程的时钟周期精确度高。

比如在 nokia 平台

Thread:

int threadDelay;// 帧时间

public class GameCanvas extends FullCanvas implements Runnable{

       public void run(){

              // 游戏处理

              …………………….

              try{

                     Thread.sleep(threadDelay);

}catch(Exception e){}

}

};

一般只能运行大约 10fps 6600 7610 symbian 7.0 平台 ,N70 8.0 平台可能会快些)。

如果这样做 :

long nextTime, currentTime;

int threadDelay;// 帧时间

Boolean isThreadRun = true;

public void loopRun(){

    nextTime = System.currentTimeMillis();

    while(isThreadRun){

      currentTime = System.currentTimeMillis();

      if(currentTime>=nextTime){

        // 游戏处理

              ………………..

        timeProcess = System.currentTimeMillis() - currentTime;

        if(timeProcess>=threadDelay){

          nextTime = currentTime+timeProcess+1;

        }else nextTime = currentTime+threadDelay;

      }

    }

 }

那么可以运行到 13fps 6600 7610 symbian 7.0 平台) , 速度提升非常客观。

下面说一下我的调色板游戏实现方法 :

J2me 平台上,可以用 midp2.0 Graphics.drawRGB 将象素绘画到屏幕上 (midp1.0 中就只能使用厂商的 api 了,比如 nokia dg.drawPixels()) ,一般这个只需要调用一次,也就是将象素贴到屏幕上。

游戏中使用两种图片 : (为了容易理解,我用类进行封装)

1.  对应 Graphics.drawRGB 的屏幕位图 :

class RGBImage{

    public int imageWidth;

public int imageHeight;

public int[] imageData;// 长度 = imageWidth* imageHeight;

};

2.  对应调色板的图片集合

class PalletteImages {

public int[128] palette;

public int imageNumbers;

public int[] imageSize;

public int[] imageDataFromIndex;

public byte[] data;

};

为什么要调色板为 128 呢?因为 java 中的 byte -127 - +127 ,要用 256 色就必须算加法,如果不想用,就只能用 0-127 ,所以就定义为 128 的长。根据我的使用经历, 128 色完全够用。

ImageSize 存储每一张图片的大小,例如:总共有 20 张图,那么 imageSize 的长度就起码为 20*2 = 40 。第 n 张图的尺寸宽度 =imageSize[n*2], 高度 = imageSize[n*2+1]

ImageDataFromIndex存储每一张图片在data数据中的开始位置。

data 存储图片的索引数据,存储为如下格式 :

图片 1 索引 1 ,图片 1 索引 2 ………. 图片 1 索引 n,

图片 2 索引 1 ,图片 2 索引 2 ………. 图片 2 索引 m,

.

.

.

图片 d 索引 1 ,图片 d 索引 2 ………. 图片 d 索引 g

  

C/ C++ 上实现如下 :

typedef unsigned char U8;//8位无符号整数

typedef unsigned short int U16;//16位无符号整数

typedef unsigned long int U32;//32位无符号整数

struct Size{

    int iWidth;

    int iHeight;

};

屏幕位图 :

struct RGBImage{

       Size iImageSize;

       U32 * iImageData;

}

调色板图片集合:

struct Pallette Images{

    U32* iPallette;//256色的调色板,C/C++支持使用256色调色板

    int iImageItemNumbers;//图片总数

    Size* iImageSize;//每张图片尺寸

    int* iImageFromIndex;//每张图片的开始索引

    U8* iImageData;//图片索引数据

};

posted on 2006-09-15 11:45 Marten Feng 阅读(134) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: