Doja3.5(主要機(jī)型N900iG,原始版本S700)移植流程
1. 修改import部分
主要在每個(gè)包含import的代碼文件中,將原來(lái)MIDP版本專有的class-path改成DoJa專有的,主要是添加如下代碼在文件頭:
import com.nttdocomo.io.*;
import com.nttdocomo.ui.*;
2. 入口類不同
在MIDP中主類是繼承MIDlet,而Doja是繼承Iapplication類。雖然本質(zhì)上兩個(gè)類功能幾乎一樣,但也有一些區(qū)別:
返回游戲時(shí),MIDlet是調(diào)用startApp()(開始時(shí)也會(huì)被調(diào)用).而在Doja中resume()函數(shù)被調(diào)用以及一個(gè)Display.RESUME_VM_EVENT消息發(fā)送到當(dāng)前Display對(duì)象.這在中斷處理可能會(huì)需要用到.
3. 添加下載代碼
DoJa3.5支持最大100K的Jar包和最大400K的scr(ScratchPad----草稿板),scr在被下載到設(shè)備上之前,是以每個(gè)大小不超過(guò)10K的raw文件組成,我們需要在程序中自己寫代碼來(lái)實(shí)現(xiàn)所有raw文件的下載和拼接功能。
主要的思路是:打開一個(gè)網(wǎng)絡(luò)數(shù)據(jù)流,將對(duì)應(yīng)的raw分塊寫入事先生成的空白scr中,并在scr末尾添加一個(gè)counter,每下載一個(gè)分塊,counter+1。由程序判斷counter值是否等于需要下載的分片數(shù),相等則直接進(jìn)入游戲。
4. 修改存儲(chǔ)方式
MIDP中用到的是記錄存儲(chǔ)方式(recordStore),而DoJa3.5中沒(méi)有對(duì)應(yīng)的功能函數(shù),游戲數(shù)據(jù)是直接寫在scr里面的,所以在下載raw到scr中時(shí),我們不能將scr全部填滿,一定要預(yù)留足夠的空間來(lái)存儲(chǔ)游戲數(shù)據(jù)。草稿板的IO操作與變通文件操作一樣,只有有點(diǎn)需要特別注意的地方就是不能使用skip函數(shù).
5. 修改資源的讀取方式
在草稿板中,詳細(xì)記錄了打包所用到的資源文件數(shù),每個(gè)文件的大小(通過(guò)一個(gè)位移偏移量來(lái)標(biāo)示),所以,在讀取資源之前,首先要讀取這些“預(yù)信息”,再根據(jù)這些偏移量找到相應(yīng)得打包文件,這一點(diǎn)與MIDP是不一樣的,需要注意。
將資源打入草稿板中的工具和方法有很多,我們通過(guò)列表來(lái)說(shuō)明,各位可以根據(jù)需要來(lái)選擇適合自己的工具:
工具 |
使用方法 |
CreateSP.exe (批處理方式,省事,但要復(fù)雜一些) |
echo *** building ScratchPad... set DATA_OUT_PATH=%PROJ_DIR%\data\#build\TRIPLETS_EN 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 cd %BUILD_PATH% |
藍(lán)色部分為批處理文件中的主要部分,340(單位是K)是用CreateSP.exe生成的草稿板的大小,如果實(shí)際數(shù)據(jù)塊總大小小于這個(gè)數(shù)值,則以0補(bǔ)全。##ScratchPad.txt中需要將準(zhǔn)備打入草稿板的數(shù)據(jù)塊文件的名字及路徑進(jìn)行列表(由批處理文件_SPList.bat實(shí)現(xiàn))。 | |
Src文件格式: 4Bytes-> 所有raw文件大小 4Bytes無(wú)用 4Bytes-> 所有打包文件個(gè)數(shù)n 4Bytes無(wú)用 n個(gè) { 4Bytes-> 打包文件的偏移量(offset) 4Bytes無(wú)用 } | |
DaTool.exe (手動(dòng)方式,麻煩一點(diǎn),簡(jiǎn)單) |
打開Datool.exe 按ALT+P打開資源列表文件ScratchPad.txt然后open既可.大小由列表文件中所指定文件大小而定. |
ScratchPad.txt 格式: (第一行為輸入scr文件路徑,從第二行開始為所有文件列表,可以為相對(duì)路徑) 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 -> 所有文件個(gè)數(shù) 4Bytes -> src文件大小 I = (0 … 文件總數(shù) - 1 ) 4Bytes -> 第(I)個(gè)文件的偏移 | |
注 |
在用模擬器時(shí),Doja3.5草稿板的命名與jam名一樣,并且需要在后面加個(gè)0 |
6. 修改圖片創(chuàng)建代碼
在DoJa3.5中,圖片對(duì)象的創(chuàng)建不是簡(jiǎn)單的createImage,我們的做法是:先將圖片數(shù)據(jù)讀入一個(gè)byte數(shù)組中,用這個(gè)數(shù)組來(lái)實(shí)現(xiàn)圖片的創(chuàng)建。可以從下面的代碼中看到,我們首先用getImage()從buff中得到一個(gè)MediaImage對(duì)象temp,用use()方法激活這個(gè)對(duì)象,然后用getImage()從這個(gè)對(duì)象得到我們需要的Image對(duì)象,最后,將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圖片的文件格式 (見資源文檔) ,我們可以找到其中有很多相似之處:都有一個(gè)文件頭,一個(gè)或幾個(gè)調(diào)色板,經(jīng)過(guò)壓縮的數(shù)據(jù)塊。由于公司的許多游戲都要用到PngProcess.jar這個(gè)工具來(lái)處理調(diào)色板信息,所以我們寫了類似的工具GifProcess.jar,把這個(gè)工具放到PngProcess.jar所在的目錄下,接下來(lái)你所要做的工作就是:將批處理中所有提到PngProcess.jar的地方改成GifProcess.jar,將data目錄下所有Png圖片用PS的批處理功能轉(zhuǎn)成Gif圖片。不要進(jìn)行optipng.exe處理。
7. 修改按鍵代碼
DoJa3.5的鍵值可以在文檔中查到,按照那個(gè)改了就可以了,需要特別說(shuō)明的是,在MIDP中是通過(guò)keyPressed/keyRelease 函數(shù)響應(yīng)按鍵事件, getKeyState()獲得鍵值。而在DoJa3.5中只能通過(guò)processEvent函數(shù)響應(yīng)按鍵事件,getKeypadState()獲得鍵值,因此需要添加processEvent函數(shù):
//示例代碼
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();
}
}
對(duì)于按鍵檢測(cè),還有一點(diǎn)需要注意的是,在Doja中所以按鍵處理都是通過(guò)processEvent 來(lái)響應(yīng)包括左,右功能鍵以及紅鍵.
8. 修改畫圖接口
DoJa3.5中沒(méi)有drawRegion方法,也找不到一個(gè)函數(shù)能夠完全替代drawRegion的,其主要原因就在于DoJa3.5沒(méi)有anchor這個(gè)概念,并且它的翻轉(zhuǎn)方式是由專門的函數(shù)setFlipMode來(lái)決定的,我們可以從下面對(duì)MIDP和DoJa代碼的對(duì)比中得到啟示:
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 ); |
以上只是一個(gè)簡(jiǎn)單的對(duì)比,實(shí)際操作會(huì)遇到很多復(fù)雜的東西,比如說(shuō)DoJa3.5沒(méi)有TRANS_MIRROR_ROT90和TRANS_MIRROR_ROT270兩種翻轉(zhuǎn)模式,如果游戲中要用到就自己實(shí)現(xiàn)這些功能吧。
9. 修改聲音的相關(guān)接口
MIDP中是通過(guò)Player接口和Manager類來(lái)控制和播放聲音。DoJa3.5中要用到是AudioPresenter和MediaSound類和MediaListener接口,還有就是Doja只支持mld音樂(lè)文件格式。我們可以從下面的這段代碼中知道建立聲音數(shù)組和播放控制的一般方法:
//示例代碼
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. 修改設(shè)置顏色的函數(shù)setColor()
DoJa3.5中只有setColor(int c)一種方式,而沒(méi)有setColor(int r, int g, int b)這種模式,這一部分需要修改。而且N900iG是26萬(wàn)色(16位)的手機(jī),全滿的RGB值是24位的,超過(guò)了手機(jī)的顏色數(shù),如果直接用setColor(int c)可能導(dǎo)致異常,正確的做法是自己寫一個(gè)DoJaSetColor()方法:
static void DoJaSetColor(int col)
{
g.setColor(g.getColorOfRGB((col & 0xFF0000) >> 16,
(col & 0x00FF00) >> 8, col & 0x0000FF));
}
如果是setColor(int,int,int),方法同.
11. 背景燈光,振動(dòng)
MIDP2.0中是Display.vibrate()和Display.flashBacklight()。Doja中是通過(guò)PhoneSystem. setAttribute()來(lái)檢測(cè)開/關(guān)蓋也是通過(guò)PhoneSystem.setAttribute()檢測(cè)。具體可查API。
12. 對(duì)jam文件中AppParam屬性的說(shuō)明
我們可以通過(guò)在jam中設(shè)置AppParam參數(shù)(比如資源下載地址,版本號(hào)等),方便在程序中引用.下面我們就用個(gè)例子說(shuō)明:
//示例
//jam中AppParam各個(gè)參數(shù)由空格隔開
AppParam = http://shop.ludiz.com/ato2test/jvuIgoUbc/Chessmaster_N900Gi_JP_1000 29
//程序中
String _launchParams[] = cMIDlet._theMIDlet.getArgs();
String _url = _ launchParams[0]; //資源下載地址
Int spSplites = Integer.parseInt(_launchParams[1]); //spSplites = 29
string _version = _ launchParams[2];//_version = “