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); 
 
	} 
 
}