Doja3.5(主要机型N900iG,原始版本S700)移植流程
1. 修改import部分
主要在每个包含import的代码文件中,将原来MIDP版本专有的class-path改成DoJa专有的,主要是添加如下代码在文件头:
import com.nttdocomo.io.*;
import com.nttdocomo.ui.*;
2. 入口类不同
在MIDP中主类是继承MIDlet,而Doja是继承Iapplication类。虽然本质上两个类功能几乎一样,但也有一些区别:
返回游戏时,MIDlet是调用startApp()(开始时也会被调用).而在Doja中resume()函数被调用以及一个Display.RESUME_VM_EVENT消息发送到当前Display对象.这在中断处理可能会需要用到.
3. 添加下载代码
DoJa3.5支持最大100K的Jar包和最大400K的scr(ScratchPad----草稿板),scr在被下载到设备上之前,是以每个大小不超过10K的raw文件组成,我们需要在程序中自己写代码来实现所有raw文件的下载和拼接功能。
主要的思路是:打开一个网络数据流,将对应的raw分块写入事先生成的空白scr中,并在scr末尾添加一个counter,每下载一个分块,counter+1。由程序判断counter值是否等于需要下载的分片数,相等则直接进入游戏。
4. 修改存储方式
MIDP中用到的是记录存储方式(recordStore),而DoJa3.5中没有对应的功能函数,游戏数据是直接写在scr里面的,所以在下载raw到scr中时,我们不能将scr全部填满,一定要预留足够的空间来存储游戏数据。草稿板的IO操作与变通文件操作一样,只有有点需要特别注意的地方就是不能使用skip函数.
5. 修改资源的读取方式
在草稿板中,详细记录了打包所用到的资源文件数,每个文件的大小(通过一个位移偏移量来标示),所以,在读取资源之前,首先要读取这些“预信息”,再根据这些偏移量找到相应得打包文件,这一点与MIDP是不一样的,需要注意。
将资源打入草稿板中的工具和方法有很多,我们通过列表来说明,各位可以根据需要来选择适合自己的工具:
工具 |
使用方法 |
CreateSP.exe
(批处理方式,省事,但要复杂一些) |
echo *** building ScratchPad...
set DATA_OUT_PATH=%PROJ_DIR%\data\#build\TRIPLETS_EN
del %PROJ_DIR%\sp\*.raw > NUL
del %PROJ_DIR%\sp\*.scr > NUL
set TOOLS_PATH = %PROJ_DIR%\tools
cd "%PROJ_DIR%\data\phone\%PHONE%\pack
Echo *** calling "_SPList.bat"
call _SPList.bat
"%PROJ_DIR%\tools\DojaTools\CreateSP.exe" ##ScratchPad.txt %PROJ_DIR%\sp\%PROJ_FULL_NAME%_%VERSION_NUMBER%.raw %PROJ_DIR%\sp\%PROJ_FULL_NAME%.scr 340
del sp.h > NUL
del %PROJ_DIR%\sp\%PROJ_FULL_NAME%_%VERSION_NUMBER%.raw > NUL
cd %BUILD_PATH% |
蓝色部分为批处理文件中的主要部分,340(单位是K)是用CreateSP.exe生成的草稿板的大小,如果实际数据块总大小小于这个数值,则以0补全。##ScratchPad.txt中需要将准备打入草稿板的数据块文件的名字及路径进行列表(由批处理文件_SPList.bat实现)。 |
Src文件格式:
4Bytes-> 所有raw文件大小
4Bytes无用
4Bytes-> 所有打包文件个数n
4Bytes无用
n个
{
4Bytes-> 打包文件的偏移量(offset)
4Bytes无用
} |
DaTool.exe
(手动方式,麻烦一点,简单) |
打开Datool.exe 按ALT+P打开资源列表文件ScratchPad.txt然后open既可.大小由列表文件中所指定文件大小而定. |
ScratchPad.txt 格式: (第一行为输入scr文件路径,从第二行开始为所有文件列表,可以为相对路径)
Output file name:..\sp\%PROJ_DIR%\sp\%PROJ_FULL_NAME%.scr
.\data\a.bin
.\data\c.bin
.\data\data0.bin
.\data\p.bin
.\data\s.bin
..\music\a0.mld
…. |
Src文件格式:
2Bytes -> 所有文件个数
4Bytes -> src文件大小
I = (0 … 文件总数 - 1 )
4Bytes -> 第(I)个文件的偏移 |
注 |
在用模拟器时,Doja3.5草稿板的命名与jam名一样,并且需要在后面加个0 |
6. 修改图片创建代码
在DoJa3.5中,图片对象的创建不是简单的createImage,我们的做法是:先将图片数据读入一个byte数组中,用这个数组来实现图片的创建。可以从下面的代码中看到,我们首先用getImage()从buff中得到一个MediaImage对象temp,用use()方法激活这个对象,然后用getImage()从这个对象得到我们需要的Image对象,最后,将temp置为null。
//示例代码
Image mImg[];
byte buff[]=new byte[headerSize+paletteSize+dataSize];
System.arraycopy(bufferImage, 0, buff, 0, headerSize+paletteSize+dataSize);
MediaImage temp = MediaManager.getImage(buff);
try{
temp.use();
}catch(ConnectionException ce){}
mImg[refImg]= temp.getImage();
temp=null;
DoJa3.5支持Gif和Jpeg格式的图片,但是不支持Png格式的图片,只要研究一下Gif图片和Png图片的文件格式 (见资源文档) ,我们可以找到其中有很多相似之处:都有一个文件头,一个或几个调色板,经过压缩的数据块。由于公司的许多游戏都要用到PngProcess.jar这个工具来处理调色板信息,所以我们写了类似的工具GifProcess.jar,把这个工具放到PngProcess.jar所在的目录下,接下来你所要做的工作就是:将批处理中所有提到PngProcess.jar的地方改成GifProcess.jar,将data目录下所有Png图片用PS的批处理功能转成Gif图片。不要进行optipng.exe处理。
7. 修改按键代码
DoJa3.5的键值可以在文档中查到,按照那个改了就可以了,需要特别说明的是,在MIDP中是通过keyPressed/keyRelease 函数响应按键事件, getKeyState()获得键值。而在DoJa3.5中只能通过processEvent函数响应按键事件,getKeypadState()获得键值,因此需要添加processEvent函数:
//示例代码
public void processEvent(int type, int param)
{ //update by doja
if(type == Display.KEY_PRESSED_EVENT)
{
keyPressed(param);
}
else if(type == Display.KEY_RELEASED_EVENT)
{
keyReleased(param);
}
else if(type == Display.RESUME_VM_EVENT)
{
System.gc();
}
}
对于按键检测,还有一点需要注意的是,在Doja中所以按键处理都是通过processEvent 来响应包括左,右功能键以及红键.
8. 修改画图接口
DoJa3.5中没有drawRegion方法,也找不到一个函数能够完全替代drawRegion的,其主要原因就在于DoJa3.5没有anchor这个概念,并且它的翻转方式是由专门的函数setFlipMode来决定的,我们可以从下面对MIDP和DoJa代码的对比中得到启示:
MIDP |
cGame.g.drawRegion(cGame.mImg[img],
module_X(moduleID),//scrX
module_Y(moduleID),//scrY
module_W(moduleID),//w
module_H(moduleID),//h
cGame.transform[refModuleFlag],
__i1,//desX
__i2,//desY
__i5); |
DoJa3.5 |
if((__i5&Graphics_RIGHT)!=0)
__i1-=module_W(moduleID);
cGame.g.setFlipMode(cGame.transform[refModuleFlag]);
cGame.g.drawImage(cGame.mImg[img],
__i1, //desX
__i2, //desY
module_X(moduleID), //scrX
module_Y(moduleID), //scrY
module_W(moduleID), //w
module_H(moduleID) //h
); |
以上只是一个简单的对比,实际操作会遇到很多复杂的东西,比如说DoJa3.5没有TRANS_MIRROR_ROT90和TRANS_MIRROR_ROT270两种翻转模式,如果游戏中要用到就自己实现这些功能吧。
9. 修改声音的相关接口
MIDP中是通过Player接口和Manager类来控制和播放声音。DoJa3.5中要用到是AudioPresenter和MediaSound类和MediaListener接口,还有就是Doja只支持mld音乐文件格式。我们可以从下面的这段代码中知道建立声音数组和播放控制的一般方法:
//示例代码
static com.nttdocomo.ui.AudioPresenter[] _musics;
_musics = new com.nttdocomo.ui.AudioPresenter [BGM_MAX];
MediaSound m_sound;
boolean isPlaying = false;
// Event Listener (manages playback state)
public void mediaAction(MediaPresenter source, int type, int param) {
if (type == AudioPresenter.AUDIO_PLAYING) {
isPlaying = true;
} else if (type == AudioPresenter.AUDIO_COMPLETE ||
type == AudioPresenter.AUDIO_STOPPED) {
isPlaying = false;
}
}
// Initialize sound
public void initSound() {
try {
cGame.packOpen("/BGM.pak",index);
m_sound = MediaManager.getSound(SCRACHPAD + (cGame.prv_file_offset[3] + cGame._pack_offset[index] + cGame._pack_start));
m_sound.use();
_musics[index] = AudioPresenter.getAudioPresenter();
_musics[index].setSound(m_sound);
m_sound = null;
cGame.packClose();
} catch (Exception e) {
// Error handling
}
}
// Play the sound depending on the current playback state
public void playSound() {
if (!isPlaying) {
audio.play();
}
}
10. 修改设置颜色的函数setColor()
DoJa3.5中只有setColor(int c)一种方式,而没有setColor(int r, int g, int b)这种模式,这一部分需要修改。而且N900iG是26万色(16位)的手机,全满的RGB值是24位的,超过了手机的颜色数,如果直接用setColor(int c)可能导致异常,正确的做法是自己写一个DoJaSetColor()方法:
static void DoJaSetColor(int col)
{
g.setColor(g.getColorOfRGB((col & 0xFF0000) >> 16,
(col & 0x00FF00) >> 8, col & 0x0000FF));
}
如果是setColor(int,int,int),方法同.
11. 背景灯光,振动
MIDP2.0中是Display.vibrate()和Display.flashBacklight()。Doja中是通过PhoneSystem. setAttribute()来检测开/关盖也是通过PhoneSystem.setAttribute()检测。具体可查API。
12. 对jam文件中AppParam属性的说明
我们可以通过在jam中设置AppParam参数(比如资源下载地址,版本号等),方便在程序中引用.下面我们就用个例子说明:
//示例
//jam中AppParam各个参数由空格隔开
AppParam = http://shop.ludiz.com/ato2test/jvuIgoUbc/Chessmaster_N900Gi_JP_1000 29 1.0.0
//程序中
String _launchParams[] = cMIDlet._theMIDlet.getArgs();
String _url = _ launchParams[0]; //资源下载地址
Int spSplites = Integer.parseInt(_launchParams[1]); //spSplites = 29
string _version = _ launchParams[2];//_version = “1.0.2”
posted on 2006-02-25 15:43
生活,在继续……勿要停! 阅读(940)
评论(1) 编辑 收藏 所属分类:
从MIDP向DOJA手机的移植