關卡數據
Replica Island的關卡數據記錄在以下兩個文件裏:
- res/xml/level_tree.xml
- res/xml/linear_level_tree.xml
其文件結構都是一樣的:
- 文件含有一個levelTree標籤,levelTree標籤囊括所有的關卡信息;
- levelTree標籤下包含一個或多個group標籤;
- group標籤下包含一個或多個level標籤;
- level標籤下不包含或者只包含一個dialog標籤,level標籤指定某個關卡的信息;
- dialog標籤下包含以下標籤中的任何組合,每個標籤最多出現一次:diary、character1、character2,dialog標籤指定關卡內的NPC對話信息。
各個標籤支持的屬性:
標籤 | 屬性 | |||||
---|---|---|---|---|---|---|
resource | time | title | restartable | waitmessage | past | |
levelTree | ||||||
group | ||||||
level | 關卡布局數據 | 通關時間記錄: in res/values/strings.xml: level_0_1_time ~ level_final_boss_time |
關卡標題/存檔: in res/values/strings.xml: level_0_1_sewer ~ level_final_boss_lab |
關卡是否可以重玩 默認值爲true 可設置爲false |
關卡開始前是否顯示等待對話框 默認值爲false 可設置爲true |
inThePast 默認值爲false 可設置爲true |
dialog | ||||||
diary | 日記數據: in res/values/strings.xml: Diary1 ~ Diary15 |
|||||
character1 | NPC對話信息 | |||||
character2 | NPC對話信息 |
NPC對話信息
以下文件記錄了各關卡里的NPC對話信息:
xml/level_0_1_dialog_wanda.xml
xml/level_0_2_dialog_kabocha_2.xml
......
xml/level_4_9_dialog_wanda.xml
xml/level_final_boss_dialog.xml
其文件結構都是一樣的:
- 文件含有一個dialog標籤,dialog標籤囊括關卡內的所有NPC對話信息;
- dialog標籤下包含一個或多個conversation標籤,conversation標籤指定某處NPC的對話信息。有幾個conversation標籤,該關卡內就有幾處NPC要對話。
- conversation標籤下包含一個或多個page標籤,page標籤指定某個NPC的一段對話。有幾個page標籤,該NPC就有幾段話要說。
除了通關對話level_final_boss_dialog.xml,其他的對話文件,都是每個文件裏只有一個NPC角色。page標籤支持以下三個屬性:
- image:NPC頭像,保存在res/drawable目錄下:
- res/drawable/kabocha_closeup_concern.png
- res/drawable/kabocha_closeup_lunatic.png
- res/drawable/kabocha_closeup_lunatic_02.png
- res/drawable/kabocha_closeup_normal.png
- res/drawable/kyle_closeup_angry.png
- res/drawable/kyle_closeup_neutral.png
- res/drawable/kyle_closeup_noglasses.png
- res/drawable/rokudou_closeup_mask.png
- res/drawable/rokudou_closeup_normal.png
- res/drawable/wanda_happy.png
- res/drawable/wanda_sad.png
- res/drawable/wanda_smile.png
- res/drawable/wanda_surprised.png
- text:NPC對話字符串,字符串內容保存在以下文件裏,每個NPC一個文件:
- res/values/kabocha.xml
- res/values/kyle.xml
- res/values/rokudou.xml
- res/values/wanda.xml
- title:NPC名字,保存在res/values/strings.xml裏:
<!-- names --> <string name="Wanda">Wanda</string> <string name="Kyle">Kyle</string> <string name="Kabocha">Dr. Kabochanomizu</string> <string name="Rokudou">Mr. Rokudou</string> <string name="Android">Android</string>
例如如下的NPC對話情景:
XML代碼 | 字符串資源 | 遊戲畫面 |
---|---|---|
res/xml/linear_level_tree.xml
|
res/values/strings.xml
|
|
res/xml/level_0_3_dialog_kabocha.xml
|
res/values/strings.xml
res/values/kabocha.xml
|
|
res/xml/level_0_3_dialog_kabocha.xml
|
res/values/strings.xml
res/values/kabocha.xml
|
|
res/xml/level_0_3_dialog_kabocha.xml
|
res/values/strings.xml
res/values/kabocha.xml
|
LevelTree.java
LevelTree負責管理所有的關卡信息,它提供方法loadLevelTree來加載所有的關卡信息:
public static final void loadLevelTree(int resource, Context context) {
...
}
方法get用於獲取指定關卡信息:
public static final Level get(int row, int index) {
return levels.get(row).levels.get(index);
}
方法get的參數row指定group標籤的下標,index指定group標籤內level標籤的下標。
方法loadAllDialog用於加載所有的NPC對話信息:
public final static void loadAllDialog(Context context) {
...
}
方法loadLevelTree和loadAllDialog共有兩處引用,且都是一同調用的:
// AndouKun.onCreate()
int levelTreeResource = R.xml.level_tree;
if (mLinearMode != 0) {
levelTreeResource = R.xml.linear_level_tree;
}
if (!LevelTree.isLoaded(levelTreeResource)) {
LevelTree.loadLevelTree(levelTreeResource, this);
LevelTree.loadAllDialog(this);
}
// MainMenuActivity.onCreate()
SharedPreferences prefs =
getSharedPreferences(PreferenceConstants.PREFERENCE_NAME, MODE_PRIVATE);
final int row = prefs.getInt(PreferenceConstants.PREFERENCE_LEVEL_ROW, 0);
final int index = prefs.getInt(PreferenceConstants.PREFERENCE_LEVEL_INDEX, 0);
int levelTreeResource = R.xml.level_tree;
if (row != 0 || index != 0) {
final int linear = prefs.getInt(PreferenceConstants.PREFERENCE_LINEAR_MODE, 0);
if (linear != 0) {
levelTreeResource = R.xml.linear_level_tree;
}
}
if (!LevelTree.isLoaded(levelTreeResource)) {
LevelTree.loadLevelTree(levelTreeResource, this);
LevelTree.loadAllDialog(this);
}
這兩處調用都是將所有的關卡信息、NPC對話信息一次性都加載入內存。這並不是最優化的處理,其實對於NPC對話信息,應該只加載玩家當前要玩的關卡和下一關卡的對話信息即可。不知道爲什麼Chris Pruett沒有這麼做,也許因爲Replica Island只是個教學產品?
關卡布局數據
關卡布局數據保存在以下文件中:
- raw/level_0_1_sewer_kyle.bin
- raw/level_0_1_sewer_wanda.bin
- ......
- raw/level_4_9_underground.bin
- raw/level_final_boss_lab.bin
關卡布局數據通過方法LevelSystem.loadLevel()來解析。分析該方法的代碼後,可以得知關卡布局數據文件的格式:
位移(字節) | 長度(字節) | 類型 | 說明 | |||
---|---|---|---|---|---|---|
0 | 1 | byte | 關卡布局數據文件的標識,值必須爲96。 | |||
1 | 1 | byte | 關卡地圖的層數 layerCount | |||
2 | 1 | byte | 關卡地圖背景層的索引,下標從1開始。 | |||
3 | layerSize1 | 1 | byte | 關卡地圖層1 | 地圖層類型 | |
4 | 1 | byte | 地圖磚塊索引 tileIndex 作用?下標起始值? | |||
5 | 4 | float, little endian | 地圖層捲動速度 scrollSpeed 單位? | |||
9 | 1 | byte | TiledWorld | 地圖層數據標識,值必須爲42。 | ||
10 | 4 | int, little endian | 地圖層的寬度(以磚塊數量計)layerWidth | |||
14 | 4 | int, little endian | 地圖層的寬度(以磚塊數量計)layerHeight | |||
18 | totalLayerTiles | byte array | 地圖層的磚塊索引數組 totalLayerTiles = layerWidth * layerHeight |
|||
layerSize2 | 關卡地圖層2 | |||||
...... | ...... | |||||
layerSizeN | 關卡地圖層N (N = layerCount) |