www.pudn.com > TXWW.rar > LevelLoader.java
package org.gamecollege.j2me.rpg;
import java.util.Hashtable;
import java.util.Vector;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.TiledLayer;
/**
*
* 关卡装载器
*/
public class LevelLoader implements Runnable {
//单例
public static final LevelLoader instance = new LevelLoader();
//需要装载数据的Level对象
private Level level;
//私有的构造函数。确保单例
private LevelLoader() {
}
/**
* 实现Runnable接口,开线程来装载关卡
* 这样,在装载关卡数据时,我们可以在屏幕上绘制动画
*/
public void run() {
//设置游戏状态
MyRPGGameMIDlet.mc.setGameStatus(MyGameCanvas.STATUS_LOADING_LEVEL);
//根据关卡号,查找相应的关卡文件,读取
int levelNo = level.levelNo;
String levelFile = "/level/level" + levelNo + ".lev";
String data = Tools.readFileToString(levelFile);
//去掉多行注释
data = Tools.delMutilLineComment(data);
//解析关卡文件中元数据段
int index1 = data.indexOf("{");
int index2 = data.indexOf("}", index1);
parseMetaData(data.substring(index1 + 1, index2), level);
System.out.println("parseMetaData:OK");
//解析关卡文件技能数据段
index1 = data.indexOf("{", index2 + 1);
index2 = data.indexOf("}", index1 + 1);
parseSkillsData(data.substring(index1 + 1, index2), level);
System.out.println("parseSkillsData:OK");
//解析关卡文件中道具数据段
index1 = data.indexOf("{", index2 + 1);
index2 = data.indexOf("}", index1 + 1);
parsePropertyData(data.substring(index1 + 1, index2), level);
System.out.println("parsePropertyData:OK");
//解析关卡文件中NPC数据段
index1 = data.indexOf("{", index2 + 1);
index2 = data.indexOf("}", index1 + 1);
parseNPCData(data.substring(index1 + 1, index2), level);
System.out.println("parseNPCData:OK");
//解析关卡文件中主角数据段
index1 = data.indexOf("{", index2 + 1);
index2 = data.indexOf("}", index1 + 1);
String palyerData = data.substring(index1 + 1, index2).trim();
parsePlayerData(palyerData, level);
System.out.println("parsePlayerData:OK");
//解析关卡文件中连接区数据段
index1 = data.indexOf("{", index2 + 1);
index2 = data.indexOf("}", index1 + 1);
parseLinkData(data.substring(index1 + 1, index2), level);
System.out.println("parseLinkData:OK");
//循环解析关卡文件中各个地图数据段
while (true) {
index1 = data.indexOf("{", index2 + 1);
if (index1 < 0) {
break;
}
index2 = data.indexOf("}", index1 + 1);
parseMapData(data.substring(index1 + 1, index2), level);
System.out.println("a map ok");
}
//通知canvas关卡装载完毕
MyRPGGameMIDlet.mc.handLevelLoaded();
}
/**
* 装载关卡数据,开线程进行
* @param level
*/
public void loadLevel(Level level) {
this.level = level;
if (MyRPGGameMIDlet.mc.getGameStatus() != MyGameCanvas.STATUS_LOADING_LEVEL) {
new Thread(this).start();
}
}
/**
* 解析主角数据段
* @param pd 主角数据
* @param level 待设置的关卡
*/
private void parsePlayerData(String pd, Level level) {
if (level.levelNo != 0) {
return;
}
StringTokenizer st = new StringTokenizer(pd, "|");
Player p = MyRPGGameMIDlet.mc.myPlayer;
//清空主角的护具,药品,技能,武器4个Vector
p.jacketVec.removeAllElements();
p.medicVec.removeAllElements();
p.skillVec.removeAllElements();
p.weaponVec.removeAllElements();
//读取主角属性数据,并设置,当这些属性值不为-1时,代表这些属性值已经在别处设置
//比如说读取存档
String item = st.nextToken();
if (p.rate == -1)
p.rate = Integer.parseInt(item);
item = st.nextToken();
if (p.money == -1)
p.money = Integer.parseInt(item);
item = st.nextToken();
if (p.hp == -1)
p.hp = Integer.parseInt(item);
item = st.nextToken();
if (p.mp == -1)
p.mp = Integer.parseInt(item);
item = st.nextToken();
if (p.exp == -1)
p.levelInitExp = p.exp = Integer.parseInt(item);
//升级公式,升级要达到的经验值为上一个级别的1.5倍
if (p.nextExp == -1)
p.nextExp = p.exp * 3 / 2;
item = st.nextToken();
if (p.rank == -1)
p.rank = Integer.parseInt(item);
item = st.nextToken();
if (p.attackPoint == -1)
p.attackPoint = Integer.parseInt(item);
item = st.nextToken();
if (p.defendPoint == -1)
p.defendPoint = Integer.parseInt(item);
//解析主角数据时,如果主角的propertyIDs和skillIDs属性已经设置,那么就初始化
//主角的护具,药品,技能,武器4个Vector
if (p.propertyIDs != null) {
StringTokenizer st2 = new StringTokenizer(p.propertyIDs, "|");
while (st2.hasMoreTokens()) {
String id = st2.nextToken().trim();
Property p2 = (Property) level.properties.get(Integer
.valueOf(id));
if (p2.type == 1) {
p.weaponVec.addElement(p2);
} else if (p2.type == 2) {
p.medicVec.addElement(p2);
} else if (p2.type == 3) {
p.jacketVec.addElement(p2);
}
}
}
System.out.println("p.skillIDs=" + p.skillIDs);
if (p.skillIDs != null) {
StringTokenizer st2 = new StringTokenizer(p.skillIDs, "|");
while (st2.hasMoreTokens()) {
String id = st2.nextToken().trim();
Skill p2 = (Skill) level.skills.get(Integer.valueOf(id));
p.skillVec.addElement(p2);
}
}
}
/**
* 解析连接区数据
* @param ld 连接区数据
* @param level 关卡
*/
private void parseLinkData(String ld, Level level) {
StringTokenizer st = new StringTokenizer(ld, "|");
Hashtable ht = new Hashtable();
while (st.hasMoreTokens()) {
String linkData = st.nextToken().trim();
linkData = linkData.substring(1, linkData.length() - 1);
StringTokenizer st2 = new StringTokenizer(linkData, ",");
Linker linker = new Linker();
String item = st2.nextToken().trim();
linker.ID = Integer.parseInt(item);
item = st2.nextToken().trim();
linker.belongMapID = Integer.parseInt(item);
item = st2.nextToken().trim();
linker.colNo = Integer.parseInt(item);
item = st2.nextToken().trim();
linker.rowNo = Integer.parseInt(item);
item = st2.nextToken().trim();
linker.nextLevelID = Integer.parseInt(item);
item = st2.nextToken().trim();
linker.nextMapID = Integer.parseInt(item);
item = st2.nextToken().trim();
linker.newHeroColNo = Integer.parseInt(item);
item = st2.nextToken().trim();
linker.newHeroRowNo = Integer.parseInt(item);
ht.put(new Integer(linker.ID), linker);
}
level.links = ht;
}
/**
* 解析地图区数据
* @param md
* @param level
*/
private void parseMapData(String md, Level level) {
StringTokenizer st = new StringTokenizer(md, "#");
Hashtable ht = level.maps;
if (level.maps == null) {
ht = new Hashtable();
}
String item = st.nextToken();
StringTokenizer st2 = new StringTokenizer(item, "|");
String item2 = st2.nextToken().trim();
Map map = new Map();
map.mapNo = Integer.parseInt(item2);
item2 = st2.nextToken();
map.description = item2;
item2 = st2.nextToken();
map.cols = Integer.parseInt(item2);
item2 = st2.nextToken();
map.rows = Integer.parseInt(item2);
item2 = st2.nextToken();
map.heroAppearCol = Integer.parseInt(item2);
item2 = st2.nextToken();
map.heroAppearRow = Integer.parseInt(item2);
item2 = st2.nextToken().trim();
//不是可能发生随机战斗的地图
if (item2.indexOf("-1") >= 0) {
map.isFightMap = false;
} else {
//是可能发生随机战斗的地图,设置地图的随机战斗背景图
map.isFightMap = true;
StringTokenizer st3 = new StringTokenizer(item2, ",");
map.randFightBgImages = new Vector();
while (st3.hasMoreTokens()) {
String temp = st3.nextToken().trim();
map.randFightBgImages.addElement(level.allImages.get(Integer
.valueOf(temp)));
}
}
item2 = st2.nextToken();
map.rpgObjects = new Vector();
//设置地图上npc,道具分布
String npcs = st.nextToken().trim();
st2 = new StringTokenizer(npcs, "|");
while (st2.hasMoreTokens()) {
String npc = st2.nextToken();
npc = npc.substring(1, npc.length() - 1);
int index1 = npc.indexOf(",");
int index2 = npc.indexOf(",", index1 + 1);
NPC Npc = (NPC) level.npcs.get(Integer.valueOf(npc.substring(0,
index1)));
Npc.colNo = Integer.parseInt(npc.substring(index1 + 1, index2));
Npc.rowNo = Integer.parseInt(npc.substring(index2 + 1));
map.rpgObjects.addElement(GameInnerThread.cloneNpc(Npc));
}
//地图所用材质图
Image material = (Image) level.allImages.get(Integer.valueOf(item2));
//碰撞区
String noWalkArea = st.nextToken();
st2 = new StringTokenizer(noWalkArea, "|");
TiledLayer tl = new TiledLayer(map.cols, map.cols, material,
level.tileWidth, level.tileHeight);
int count = 0;
while (st2.hasMoreTokens()) {
int column = count % map.cols;
int row = (count - column) / map.cols;
tl.setCell(column, row, Integer.parseInt(st2.nextToken().trim()));
count++;
}
map.collisionArea = tl;
map.walkableArea = new Vector();
//多个行走区
while (st.hasMoreElements()) {
String walkArea = st.nextToken().trim();
if (walkArea.length() == 0) {
break;
}
st2 = new StringTokenizer(walkArea, "|");
TiledLayer t2 = new TiledLayer(map.cols, map.cols, material,
level.tileWidth, level.tileHeight);
count = 0;
while (st2.hasMoreTokens()) {
int column = count % map.cols;
int row = (count - column) / map.cols;
t2.setCell(column, row, Integer
.parseInt(st2.nextToken().trim()));
count++;
}
map.walkableArea.addElement(t2);
}
ht.put(new Integer(map.mapNo), map);
level.maps = ht;
}
/**
* 解析NPC数据段
* @param nd
* @param level
*/
private void parseNPCData(String nd, Level level) {
StringTokenizer st = new StringTokenizer(nd, "#");
Hashtable ht = new Hashtable();
while (st.hasMoreTokens()) {
String npcData = st.nextToken();
if (npcData.trim().length() == 0) {
break;
}
NPC npc = new NPC();
StringTokenizer st2 = new StringTokenizer(npcData, "|");
String item = st2.nextToken().trim();
npc.ID = Integer.parseInt(item);
item = st2.nextToken().trim();
npc.name = item;
item = st2.nextToken().trim();
npc.type = Integer.parseInt(item);
item = st2.nextToken().trim();
npc.attackPoint = Integer.parseInt(item);
item = st2.nextToken().trim();
npc.defendPoint = Integer.parseInt(item);
item = st2.nextToken().trim();
int id = Integer.parseInt(item);
if (id >= 0) {
Image srcImage = (Image) level.allImages.get(new Integer(id));
int tw = Integer.parseInt(st2.nextToken().trim());
int th = Integer.parseInt(st2.nextToken().trim());
npc.sprite = new Sprite(srcImage, tw, th);
item = st2.nextToken().trim();
npc.startFrameIndex = Integer.parseInt(item);
// System.out.println("npc.startFrameIndex="+npc.startFrameIndex);
item = st2.nextToken().trim();
npc.endFrameIndex = Integer.parseInt(item);
// System.out.println("npc.endFrameIndex="+npc.endFrameIndex);
}
//对话类NPC
if (npc.type == 1) {
String talks = st2.nextToken().trim();
StringTokenizer st3 = new StringTokenizer(talks, "^");
Vector tv = new Vector();
while (st3.hasMoreTokens()) {
item = st3.nextToken();
tv.addElement(item.trim());
}
npc.talkContents = tv;
//武器贩卖类
} else if (npc.type == 2) {
npc.jacketVec = new Vector();
npc.weaponVec = new Vector();
item = st2.nextToken().trim();
item = item.substring(1, item.length() - 1);
StringTokenizer st3 = new StringTokenizer(item, "^");
Hashtable all = level.properties;
while (st3.hasMoreElements()) {
String temp = st3.nextToken();
Property p = (Property) all.get(Integer.valueOf(temp));
if (p.type == 1) {
npc.weaponVec.addElement(p);
} else if (p.type == 3) {
npc.jacketVec.addElement(p);
}
}
//药品贩卖类
} else if (npc.type == 3) {
npc.medicVec = new Vector();
item = st2.nextToken().trim();
item = item.substring(1, item.length() - 1);
StringTokenizer st3 = new StringTokenizer(item, "^");
Hashtable all = level.properties;
while (st3.hasMoreElements()) {
String temp = st3.nextToken();
Property p = (Property) all.get(Integer.valueOf(temp));
if (p.type == 2) {
npc.medicVec.addElement(p);
}
}
}
ht.put(new Integer(npc.ID), npc);
}
level.npcs = ht;
}
//解析道具数据
private void parsePropertyData(String pd, Level level) {
StringTokenizer st = new StringTokenizer(pd, "#");
Hashtable ht = new Hashtable();
while (st.hasMoreTokens()) {
String property = st.nextToken();
if (property.trim().length() == 0) {
break;
}
Property pro = new Property();
StringTokenizer st2 = new StringTokenizer(property, "|");
String item = st2.nextToken().trim();
pro.ID = Integer.parseInt(item);
item = st2.nextToken().trim();
pro.name = item;
item = st2.nextToken().trim();
pro.type = Integer.parseInt(item);
item = st2.nextToken().trim();
pro.description = item;
item = st2.nextToken().trim();
pro.price = Integer.parseInt(item);
item = st2.nextToken().trim();
pro.addHP = Integer.parseInt(item);
item = st2.nextToken().trim();
pro.addMP = Integer.parseInt(item);
item = st2.nextToken().trim();
pro.addAttackPoint = Integer.parseInt(item);
item = st2.nextToken().trim();
pro.addDefendPoint = Integer.parseInt(item);
item = st2.nextToken().trim();
int id = Integer.parseInt(item);
//有图片
if (id >= 0) {
Image srcImage = (Image) level.allImages.get(new Integer(id));
int tw = Integer.parseInt(st2.nextToken().trim());
int th = Integer.parseInt(st2.nextToken().trim());
pro.sprite = new Sprite(srcImage, tw, th);
item = st2.nextToken().trim();
pro.startFrameIndex = Integer.parseInt(item);
item = st2.nextToken().trim();
pro.endFrameIndex = Integer.parseInt(item);
}
ht.put(new Integer(pro.ID), pro);
}
level.properties = ht;
}
/**
* 解析技能数据段
* @param sd
* @param level
*/
private void parseSkillsData(String sd, Level level) {
StringTokenizer st = new StringTokenizer(sd, "#");
Hashtable ht = new Hashtable();
while (st.hasMoreTokens()) {
String skill = st.nextToken();
if (skill.trim().length() == 0) {
break;
}
Skill sk = new Skill();
StringTokenizer st2 = new StringTokenizer(skill, "|");
String item = st2.nextToken().trim();
sk.ID = Integer.parseInt(item);
item = st2.nextToken().trim();
sk.name = item;
item = st2.nextToken().trim();
sk.description = item;
item = st2.nextToken().trim();
sk.type = Integer.parseInt(item);
item = st2.nextToken().trim();
sk.requiredLevel = Integer.parseInt(item);
item = st2.nextToken().trim();
sk.price = Integer.parseInt(item);
item = st2.nextToken().trim();
sk.isPercent = Integer.parseInt(item) > 0 ? true : false;
item = st2.nextToken().trim();
sk.mpCost = Integer.parseInt(item);
item = st2.nextToken().trim();
sk.hpCost = Integer.parseInt(item);
item = st2.nextToken().trim();
sk.addAttackPoint = Integer.parseInt(item);
item = st2.nextToken().trim();
sk.addDefendPoint = Integer.parseInt(item);
item = st2.nextToken().trim();
int id = Integer.parseInt(item);
//有图片
if (id >= 0) {
Image srcImage = (Image) level.allImages.get(new Integer(id));
System.out.println("srcImage="+srcImage);
int tw = Integer.parseInt(st2.nextToken().trim());
int th = Integer.parseInt(st2.nextToken().trim());
sk.sprite = new Sprite(srcImage, tw, th);
item = st2.nextToken().trim();
sk.startFrameIndex = Integer.parseInt(item);
item = st2.nextToken().trim();
sk.endFrameIndex = Integer.parseInt(item);
}
ht.put(new Integer(sk.ID), sk);
}
System.out.println("skill ht=" + ht);
level.skills = ht;
}
/**
* 解析关卡元素据段
* @param metaData
* @param level
*/
private void parseMetaData(String metaData, Level level) {
int index1 = metaData.indexOf("[");
int index2 = metaData.indexOf("]", index1);
String s1 = metaData.substring(index1 + 1, index2);
StringTokenizer st = new StringTokenizer(s1, "|");
String item = st.nextToken();
level.name = item;
item = st.nextToken();
level.description = item;
item = st.nextToken();
level.tileWidth = (Integer.parseInt(item));
item = st.nextToken();
level.tileHeight = (Integer.parseInt(item));
index1 = metaData.indexOf("[", index2 + 1);
index2 = metaData.indexOf("]", index1 + 1);
s1 = metaData.substring(index1 + 1, index2);
st = new StringTokenizer(s1, "|");
level.missionDesc = st.nextToken();
level.missionType = Integer.parseInt(st.nextToken());
level.missionValue = Integer.parseInt(st.nextToken());
index1 = metaData.indexOf("[", index2 + 1);
index2 = metaData.indexOf("]", index1 + 1);
s1 = metaData.substring(index1 + 1, index2);
st = new StringTokenizer(s1, "|");
Hashtable ht = new Hashtable();
while (st.hasMoreTokens()) {
item = st.nextToken();
item = item.substring(1, item.length() - 1);
int index = item.indexOf(",");
int id = Integer.parseInt(item.substring(0, index));
String imageFile = item.substring(index + 1);
Image image = (Image)ResourceLoader.pngFiles.get(imageFile);
if (image != null) {
ht.put(new Integer(id), image);
}
}
level.allImages = (ht);
}
}