前言
以前我想自己写一个加载器,用的时候加载,不用的时候再去掉,结果发现这种方式可能因为资源不统一在安卓上可能出现问题,所以搜集资料,弄成根据配置文件加载
思路
设定两个配置文件,screen,res,不同场景对应不同的screen,不同screen使用的资源为res,当切换的screen的res相同时,不对资源处理,直接切换,否则进入load场景等待资源加载和卸载,然后再跳转场景
下图为场景screen配置文件和资源res配置文件,screen配置了加载的背景图(bgImage),随后做配置化ui时会换掉
<screens> <screen id="-1" name="error" resId="1" bgImage="bg_error"/> <screen id="0" name="start" resId="0" /> <screen id="1" name="main" resId="1" bgImage="bg_main"/> <screen id="2" name="load" resId="1" bgImage="bg_load"/> <screen id="3" name="empire" resId="1" bgImage="bg_empire"/> <screen id="4" name="conquest" resId="1" bgImage="bg_conquest"/> <screen id="5" name="commder" resId="1" bgImage="bg_commder"/> <screen id="6" name="option" resId="1" bgImage="bg_option"/> <screen id="7" name="map" resId="1" bgImage="bg_map"/> <screen id="71" name="mapEdit" resId="2" bgImage=""/> </screens>
<resources> <res id="0" name="common_res" bgImg="公共素材,不清空"> <xmlFile name="common_ui" res="image/ui_screen.png" type="textures"/> <xmlFile name="bg_load" res="image/bg_load.png" type="texture"/> </res> <!-- bg_start在开始界面直接应用 --> <res id="1" name="generalScreen" remark="主菜单素材"> <xmlFile name="bg_main" res="image/bg_main.png" type="texture"/> <xmlFile name="bg_empire" res="image/bg_empire.png" type="texture"/> <xmlFile name="bg_conquest" res="image/bg_conquest.png" type="texture"/> <xmlFile name="bg_commder" res="image/bg_commder.png" type="texture"/> <xmlFile name="bg_option" res="image/bg_option.png" type="texture"/> <xmlFile name="bg_map" res="image/bg_map.png" type="texture"/> <xmlFile name="bg_error" res="image/bg_error.png" type="texture"/> </res> <res id="2" name="mapEdit" bgImg="地图编辑器素材"> <xmlFile name="map_pt1" res="pixmap/pts/pt1.png" type="texture" remark="地图编辑器默认底图"/> <xmlFile name="pm_tiles" res="pixmap/tiles" type="atlas" remark="装饰图集"/> </res> </resources>
在MainGame中设置刚进来加载默认资源
assetManager=GameUtil.loadResByConfig(assetManager, 0);
assetManager=GameUtil.loadResByConfig(assetManager, 1);
//根据规则配置加载资源 config_res 仅仅在初始的时候加载相关资源 public static AssetManager loadResByConfig(AssetManager am,int resId) { Element root = ResConfig.ConfigRes; XmlReader reader = ResConfig.reader; int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id")==resId) { Element xmlFile=root.getChild(i); for(int j=0;j<xmlFile.getChildCount();j++) { if(xmlFile.getChild(j).get("type").equals("texture")||xmlFile.getChild(j).get("type").equals("textures")) { am.load(xmlFile.getChild(j).get("res"), Texture.class); Gdx.app.log("加载图片资源", xmlFile.getChild(j).get("res")); }else if(xmlFile.getChild(j).get("type").equals("atlas")) { Element altas = reader.parse(Gdx.files.internal(xmlFile.getChild(j).get("res")+"/" + xmlFile.getChild(j).get("name") + ".xml")); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = altas.getChildrenByNameRecursively("sprite"); for (Element image : images) { am.load(xmlFile.getChild(j).get("res")+"/" +image.get("n"), Texture.class); Gdx.app.log("加载图集资源", xmlFile.getChild(j).get("res")+"/" +image.get("n")); } } } break; } } return am; }
每次切换场景前都判断资源Id(resId)是否相同
//判断资源是否一样,是否需要加载场景 public static boolean ifNeedLoad(int beforeScreenId,int nowScreenId) { //1.先获得当前场景和之前场景对应的资源id Element root = ResConfig.ConfigScreen; int childNum = root.getChildCount(); int nowRsId=-1,befRsId=-1; int i; for ( i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id")==nowScreenId) { nowRsId=root.getChild(i).getInt("resId"); }else if(root.getChild(i).getInt("id")==beforeScreenId) { befRsId=root.getChild(i).getInt("resId"); } if(nowRsId!=-1&&befRsId!=-1&&befRsId!=0) { Gdx.app.log("资源切换", "nowRsId:"+nowRsId+" befRsId:"+befRsId); break; } } //2.判断前场景的资源值与要加载的场景资源值id是否相同,相同则返回 if(nowRsId==befRsId||befRsId==0) { return false; }else { return true; } }
如果相同,则直接切换场景,否则进入load界面加载
/** * 开始场景展示完毕后调用该方法切换到主游戏场景 */ public void showGameScreen(int beforeScreenId,int nextScreenId) { boolean needLoad= GameUtil.ifNeedLoad(beforeScreenId,nextScreenId); //清空之前的场景 disposeScreen(beforeScreenId); if(needLoad) { loadingScreen = new LoadingScreen(this, assetManager, beforeScreenId, nextScreenId); setScreen(loadingScreen); }else { toScreen(nextScreenId); } if (getStartScreen() != null) { // 由于 StartScreen 只有在游戏启动时展示一下, 之后都不需要展示, // 所以启动完 GameScreen 后手动调用 StartScreen 的 dispose() 方法销毁开始场景。 getStartScreen().dispose(); // 场景销毁后, 场景变量值空, 防止二次调用 dispose() 方法 setStartScreen(null); } }
load场景中可以加上进度条什么的,这里我暂时没加
package com.zhfy.game.screen; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Screen; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.InputListener; import com.badlogic.gdx.scenes.scene2d.Stage; import com.zhfy.game.MainGame; import com.zhfy.game.framework.GameUtil; public class LoadingScreen implements Screen { MainGame game; Stage stage; float percent; AssetManager manager; boolean isPlay = false; Texture texture; SpriteBatch batch; int nowScreenId; public LoadingScreen(MainGame game,AssetManager am,int beforeScreenId,int nowScreenId) { this.game = game; this.manager=am; batch = new SpriteBatch(); this.nowScreenId=nowScreenId; //资源管理器进行卸载旧资源,加新资源 manager=GameUtil.loadResByScreen(manager, beforeScreenId, nowScreenId); texture = GameUtil.getBgTextureByScreenId(2,manager); batch = new SpriteBatch(); } @Override public void dispose() { batch.dispose(); } @Override public void hide() { // TODO Auto-generated method stub } @Override public void pause() { // TODO Auto-generated method stub } @Override public void render(float arg0) { Gdx.gl.glClearColor( 0, 1, 1, 1 ); Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT ); if( !manager.update() ){ //绘制一些东西 TODO }else{ //跳转 game.toScreen(nowScreenId); dispose(); } /*Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); batch.begin(); batch.draw(texture,0,0); batch.end(); stage.act(); stage.draw();*/ } @Override public void resize(int arg0, int arg1) { // TODO Auto-generated method stub } @Override public void resume() { // TODO Auto-generated method stub } @Override public void show() { /*stage = new Stage(); texture = GameUtil.getBgTextureByScreenId(2,manager); batch = new SpriteBatch(); stage.addListener(new InputListener(){ @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { game.setScreen(game.getStartScreen()); return true; } }); Gdx.input.setInputProcessor(stage);*/ } }
loadResByScreen方法,根据场景配置,比对资源,剔除多余的,添加未加载的
//根据场景配置,比对资源,剔除多余的,添加未加载的 public static AssetManager loadResByScreen(AssetManager am,int beforeScreenId,int nowScreenId) { //1.先获得当前场景和之前场景对应的资源id Element root = ResConfig.ConfigScreen; XmlReader reader = ResConfig.reader; int childNum = root.getChildCount(); int nowRsId=-1,befRsId=-1; int i; for ( i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id")==nowScreenId) { nowRsId=root.getChild(i).getInt("resId"); }else if(root.getChild(i).getInt("id")==beforeScreenId) { befRsId=root.getChild(i).getInt("resId"); } if(nowRsId!=-1&&befRsId!=-1) { break; } } //2.判断前场景的资源值与要加载的场景资源值id是否相同,相同则返回 if(nowRsId==befRsId) { return am; }else { //3.如果不同,加载新资源,卸载旧资源 //unloadResByConfig(am,befRsId); //loadResByConfig(am,nowRsId); List<Element> load=getXmlEByResId(nowRsId); List<Element> unload=getXmlEByResId(befRsId); List<Element> loadc = new ArrayList<Element>();//拷贝元素 List<Element> unloadc = new ArrayList<Element>(); loadc.addAll(load); unloadc.addAll(unload); //旧的且没有用到的数据,卸载 差集 unload.removeAll(load); //旧的且用到的,不管 交集 //新的且没有加载的,加载 差集 load.removeAll(unload); //新的且在旧的已加载的,不管 交集 unload.removeAll(load); loadc.removeAll(unloadc); unloadResByXmlE(am,unload); loadResByXmlE(am,loadc); return am; } }
//通过resId获取xml的元素
public static List<Element> getXmlEByResId(int resId) {
List<Element> rs=new ArrayList<Element>();
Element root = ResConfig.ConfigRes;
int childNum = root.getChildCount();
for (int i = 0; i < childNum; i++) {
if (root.getChild(i).getInt("id")==resId) {
Element xmlFile=root.getChild(i);
for(int j=0;j<xmlFile.getChildCount();j++) {
rs.add(xmlFile.getChild(j));
}
break;
}
}
return rs;
}
还有就是以前直接使用internal加载资源的,都传入资源加载器,用路径从里面获取资源
除了个别资源,比如我刚进入的开始界面,只出现一次,所以就没用资源加载器了
还有读取配置文件时,根据type来对不同资源处理,比如texture为一张图片,textures为图集,需要同时加载它对应路径的xml文件解析,atlas为散图等等,这都可以根据自己的文件形式,从资源管理器取资源的时候做转化
下面为我修改的一些文件,可以做参考
package com.zhfy.game.framework; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture.TextureFilter; import com.badlogic.gdx.graphics.TextureData; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.g2d.PixmapPacker; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.XmlReader; import com.badlogic.gdx.utils.XmlReader.Element; import com.zhfy.game.config.ResConfig; import com.zhfy.game.model.framework.TextureDAO; import com.zhfy.game.model.framework.TextureListDAO; import com.zhfy.game.model.framework.TextureRegionDAO; import com.zhfy.game.model.framework.TextureRegionListDAO; public class GameUtil { //本工具类主要存储涉及到libgdx的类 //泛型方法 根据传入的类型,返回list类型 public static <T> List<T> getDaoListByClass(T item,String path) throws Exception{ List<T> ts=new ArrayList<T>(); Class clazz=item.getClass(); XmlReader reader = ResConfig.reader; Element root = reader.parse(Gdx.files.internal(path)); Array<Element> elements = root.getChildrenByNameRecursively(root.getChild(0).getName()); Field[] fieldName;Class clazs;Field f; //获得条目属性的数量,然后通过反射,把值给了类 for (Element element : elements) { fieldName = clazz.getDeclaredFields(); item = (T) clazz.newInstance(); clazs=item.getClass(); for(int i=0;i<fieldName.length;i++) { // 创建实例 f = clazs.getDeclaredField(fieldName[i].getName()); f.setAccessible(true); if (f.getType().getName().equals(String.class.getName())) { String str=element.get(fieldName[i].getName()); f.set(item, str); }else if (f.getType().getName().equals(int.class.getName())) { int str=element.getInt(fieldName[i].getName()); f.set(item, str); }else if (f.getType().getName().equals(float.class.getName())) { float str=element.getFloat(fieldName[i].getName()); f.set(item, str); }else if (f.getType().getName().equals(boolean.class.getName())) { boolean str=element.getBoolean(fieldName[i].getName()); f.set(item, str); } } ts.add(item); //ts.add(tempItem); } return ts; } public static Pixmap getPixMapFromRegion(TextureRegion region) { Texture texture = region.getTexture(); TextureData data = texture.getTextureData(); if (!data.isPrepared()) { data.prepare(); } Pixmap pixmap = data.consumePixmap(); int width = region.getRegionWidth(); int height = region.getRegionHeight(); Pixmap px = new Pixmap(width, height, Format.RGBA4444); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int colorInt = pixmap.getPixel(region.getRegionX() + x, region.getRegionY() + y); } } return px; } //获取颜色rgba public static int toIntColor (int r, int g, int b,int a) { return (r << 24) | (g << 16) | (b << 8) | a; } //根据一串数字随机生成一种颜色码值 public static int getColorByNum(int num) { int r=num % 255; int g=num / 255; int b=(r*g)% 255; int a=150; return toIntColor(r,g,b,a); } /*//资源管理器,根据文件路径打包散图,然后加载入资源管理器 path为一个文件夹位置 picLv打包等级 public static AssetManager loadSmallPicByPath(AssetManager am,String path,int picLv) { int picSide=ResConfig.Atlas.PACK_PIC_SIDE; boolean isDirectory = Gdx.files.external(path).isDirectory(); PixmapPacker packer = new PixmapPacker( picLv*picSide, picLv*picSide, Format.RGB565, 2, true ); if(isDirectory) { FileHandle[] files = Gdx.files.local(path).list(); for(FileHandle file : files) { packer.pack(file.name(),new Pixmap( Gdx.files.internal(file.path()))); } am.load(packer.generateTextureAtlas( TextureFilter.Nearest, TextureFilter.Nearest, false ),TextureAtlas.class); packer.dispose(); }else { Gdx.app.log("警告:资源加载", path+" 不是一个文件夹路径"); } return am; }*/ //根据文件路径打包散图 path为一个文件夹位置 picLv打包等级 public static TextureAtlas packPicByPath(String path,int picLv) { int picSide=ResConfig.Atlas.PACK_PIC_SIDE; boolean isDirectory = Gdx.files.external(path).isDirectory(); PixmapPacker packer = new PixmapPacker( picLv*picSide, picLv*picSide, Format.RGBA8888, 2, true ); TextureAtlas textureAtlas = null; if(isDirectory) { FileHandle[] files = Gdx.files.local(path).list(); for(FileHandle file : files) { packer.pack(file.name(),new Pixmap( Gdx.files.internal(file.path()))); } textureAtlas= packer.generateTextureAtlas( TextureFilter.Nearest, TextureFilter.Nearest, false ); //am.load(packer.generateTextureAtlas( TextureFilter.Nearest, TextureFilter.Nearest, false ),TextureAtlas.class); }else { Gdx.app.log("警告:资源加载", path+" 不是一个文件夹路径"); } return textureAtlas; } //根据文件路径从资源加载器打包散图 path为一个文件夹位置 picLv打包等级 TODO 待测试 public static TextureAtlas packPicByAssetManager(String path,int picLv,AssetManager am) { int picSide=ResConfig.Atlas.PACK_PIC_SIDE; boolean isDirectory = Gdx.files.external(path).isDirectory(); PixmapPacker packer = new PixmapPacker( picLv*picSide, picLv*picSide, Format.RGBA8888, 2, true ); TextureAtlas textureAtlas = null; if(isDirectory) { FileHandle[] files = Gdx.files.internal(path).list(); for(FileHandle file : files) { packer.pack(file.name(),am.get(file.name(),Texture.class).getTextureData().consumePixmap()); } textureAtlas= packer.generateTextureAtlas( TextureFilter.Nearest, TextureFilter.Nearest, false ); //am.load(packer.generateTextureAtlas( TextureFilter.Nearest, TextureFilter.Nearest, false ),TextureAtlas.class); }else { Gdx.app.log("警告:资源加载", path+" 不是一个文件夹路径"); } return textureAtlas; } //资源管理器根据文件夹路径批量加载文件 path为一个文件夹位置 filesuffix为文件后缀,type为文件加载类型 //作废 因为internal获取不了资源 /*public static <T> AssetManager loadPicByPath(AssetManager am,String path,String filesuffix,Class<T> type) { boolean isDirectory = Gdx.files.internal(path).isDirectory(); if(isDirectory) { FileHandle[] files = Gdx.files.internal(path).list(filesuffix); for(FileHandle file : files) { Gdx.app.log("加载资源:", file.name()); am.load(file.name(), type); } }else { Gdx.app.log("警告:资源加载", path+" 不是一个文件夹路径"); } return am; }*/ //根据规则配置加载资源 config_res 仅仅在初始的时候加载相关资源 public static AssetManager loadResByConfig(AssetManager am,int resId) { Element root = ResConfig.ConfigRes; XmlReader reader = ResConfig.reader; int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id")==resId) { Element xmlFile=root.getChild(i); for(int j=0;j<xmlFile.getChildCount();j++) { if(xmlFile.getChild(j).get("type").equals("texture")||xmlFile.getChild(j).get("type").equals("textures")) { am.load(xmlFile.getChild(j).get("res"), Texture.class); Gdx.app.log("加载图片资源", xmlFile.getChild(j).get("res")); }else if(xmlFile.getChild(j).get("type").equals("atlas")) { Element altas = reader.parse(Gdx.files.internal(xmlFile.getChild(j).get("res")+"/" + xmlFile.getChild(j).get("name") + ".xml")); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = altas.getChildrenByNameRecursively("sprite"); for (Element image : images) { am.load(xmlFile.getChild(j).get("res")+"/" +image.get("n"), Texture.class); Gdx.app.log("加载图集资源", xmlFile.getChild(j).get("res")+"/" +image.get("n")); } } } break; } } return am; } //通过resId获取xml的元素 public static List<Element> getXmlEByResId(int resId) { List<Element> rs=new ArrayList<Element>(); Element root = ResConfig.ConfigRes; int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id")==resId) { Element xmlFile=root.getChild(i); for(int j=0;j<xmlFile.getChildCount();j++) { rs.add(xmlFile.getChild(j)); } break; } } return rs; } //根据规则配置卸载资源 config_res /*public static AssetManager unloadResByConfig(AssetManager am,int resId) { Element root = ResConfig.ConfigRes; XmlReader reader = ResConfig.reader; int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id")==resId) { Element xmlFile=root.getChild(i); for(int j=0;j<xmlFile.getChildCount();j++) { if(xmlFile.getChild(j).get("type").equals("texture")||xmlFile.getChild(j).get("type").equals("textures")) { am.unload(xmlFile.getChild(j).get("res")); Gdx.app.log("卸载图片资源", xmlFile.getChild(j).get("res")); }else if(xmlFile.getChild(j).get("type").equals("atlas")) { Element altas = reader.parse(Gdx.files.internal(xmlFile.getChild(j).get("res")+"/" + xmlFile.getChild(j).get("name") + ".xml")); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = altas.getChildrenByNameRecursively("sprite"); for (Element image : images) { am.unload(xmlFile.getChild(j).get("res")+"/" +image.get("n")); Gdx.app.log("卸载图集资源", xmlFile.getChild(j).get("res")+"/" +image.get("n")); } } } break; } } return am; }*/ //根据xmlE来加载资源 public static void loadResByXmlE(AssetManager am,List<Element> e) { XmlReader reader = ResConfig.reader; for (Element xmlFile:e) { if(xmlFile.get("type").equals("texture")||xmlFile.get("type").equals("textures")) { am.load(xmlFile.get("res"), Texture.class); Gdx.app.log("加载图片资源", xmlFile.get("res")); }else if(xmlFile.get("type").equals("atlas")) { Element altas = reader.parse(Gdx.files.internal(xmlFile.get("res")+"/" + xmlFile.get("name") + ".xml")); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = altas.getChildrenByNameRecursively("sprite"); for (Element image : images) { am.load(xmlFile.get("res")+"/" +image.get("n"), Texture.class); Gdx.app.log("加载图集资源", xmlFile.get("res")+"/" +image.get("n")); } } } } //根据xmlE来卸载资源 public static void unloadResByXmlE(AssetManager am,List<Element> e) { XmlReader reader = ResConfig.reader; for (Element xmlFile:e) { if(xmlFile.get("type").equals("texture")||xmlFile.get("type").equals("textures")) { am.unload(xmlFile.get("res")); Gdx.app.log("卸载图片资源", xmlFile.get("res")); }else if(xmlFile.get("type").equals("atlas")) { Element altas = reader.parse(Gdx.files.internal(xmlFile.get("res")+"/" + xmlFile.get("name") + ".xml")); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = altas.getChildrenByNameRecursively("sprite"); for (Element image : images) { am.unload(xmlFile.get("res")+"/" +image.get("n")); Gdx.app.log("卸载图集资源", xmlFile.get("res")+"/" +image.get("n")); } } } } //根据场景配置,比对资源,剔除多余的,添加未加载的 public static AssetManager loadResByScreen(AssetManager am,int beforeScreenId,int nowScreenId) { //1.先获得当前场景和之前场景对应的资源id Element root = ResConfig.ConfigScreen; int childNum = root.getChildCount(); int nowRsId=-1,befRsId=-1; int i; for ( i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id")==nowScreenId) { nowRsId=root.getChild(i).getInt("resId"); }else if(root.getChild(i).getInt("id")==beforeScreenId) { befRsId=root.getChild(i).getInt("resId"); } if(nowRsId!=-1&&befRsId!=-1) { break; } } //2.判断前场景的资源值与要加载的场景资源值id是否相同,相同则返回 if(nowRsId==befRsId) { return am; }else { //3.如果不同,加载新资源,卸载旧资源 //unloadResByConfig(am,befRsId); //loadResByConfig(am,nowRsId); List<Element> load=getXmlEByResId(nowRsId); List<Element> unload=getXmlEByResId(befRsId); List<Element> loadc = new ArrayList<Element>();//拷贝元素 List<Element> unloadc = new ArrayList<Element>(); loadc.addAll(load); unloadc.addAll(unload); //旧的且没有用到的数据,卸载 差集 unload.removeAll(load); //旧的且用到的,不管 交集 //新的且没有加载的,加载 差集 load.removeAll(unload); //新的且在旧的已加载的,不管 交集 unload.removeAll(load); loadc.removeAll(unloadc); unloadResByXmlE(am,unload); loadResByXmlE(am,loadc); return am; } } //判断资源是否一样,是否需要加载场景 public static boolean ifNeedLoad(int beforeScreenId,int nowScreenId) { //1.先获得当前场景和之前场景对应的资源id Element root = ResConfig.ConfigScreen; int childNum = root.getChildCount(); int nowRsId=-1,befRsId=-1; int i; for ( i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id")==nowScreenId) { nowRsId=root.getChild(i).getInt("resId"); }else if(root.getChild(i).getInt("id")==beforeScreenId) { befRsId=root.getChild(i).getInt("resId"); } if(nowRsId!=-1&&befRsId!=-1&&befRsId!=0) { Gdx.app.log("资源切换", "nowRsId:"+nowRsId+" befRsId:"+befRsId); break; } } //2.判断前场景的资源值与要加载的场景资源值id是否相同,相同则返回 if(nowRsId==befRsId||befRsId==0) { return false; }else { return true; } } //根据screenId获取对应的resId public static int getResIdByScreenId(int screenId) { Element root = ResConfig.ConfigScreen; int childNum = root.getChildCount(); for ( int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id")==screenId) { return root.getChild(i).getInt("resId"); } } return -1; } // 根据screenid,获取要加载的图片资源 public static TextureRegionListDAO getTextureReigonByScreenId(int screenId,AssetManager am) { // 验证imgLists是否有东西 List<String> nameList = getTextureNameByScreenId(screenId,"textures"); TextureRegionListDAO imgList = new TextureRegionListDAO(); for (int i = 0; i < nameList.size(); i++) { XmlReader reader = ResConfig.reader; /** * root是整个xml文件从根节点算起,此处是指<Credits> </Credits> */ Element root = reader.parse( Gdx.files.internal(nameList.get(i).replace(".png", ".xml"))); String imgFile = root.getAttribute("imagePath"); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = root.getChildrenByNameRecursively("sprite"); for (Element image : images) { TextureRegion imgRegion = new TextureRegion( //imgLists.getName(nameList.get(i)).getTexture(), am.get(nameList.get(i),Texture.class), image.getInt("x"), image.getInt("y"), image.getInt("w"), image.getInt("h")); TextureRegionDAO imgRegionDAO = new TextureRegionDAO(); imgRegionDAO.setTextureRegion(imgRegion); imgRegionDAO.setRefx(image.getInt("refx")); imgRegionDAO.setRefy(image.getInt("refy")); imgRegionDAO.setName(image.get("n").replace(".png", "")); imgList.add(imgRegionDAO); // Gdx.app.log("getImgName",image.get("n").replace(".png", "")+" // x:"+image.getInt("refx")+" y:"+image.getInt("refy")); } } imgList.check(); return imgList; } // 通过screenId获取要读取的资源 private static List<String> getTextureNameByScreenId(int screenId,String type) { int resId=getResIdByScreenId(screenId); List<String> strs = new ArrayList<String>(); Element root = ResConfig.ConfigRes; int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id") == 0) {//加载默认通用资源 Array<Element> xmlFiles = root.getChild(i) .getChildrenByNameRecursively("xmlFile"); for (Element xmlFile : xmlFiles) { if(xmlFile.get("type").equals(type)) { strs.add(xmlFile.get("res")); } } } if (root.getChild(i).getInt("id") == resId) { Array<Element> xmlFiles = root.getChild(i) .getChildrenByNameRecursively("xmlFile"); for (Element xmlFile : xmlFiles) { if(xmlFile.get("type").equals(type)) { strs.add(xmlFile.get("res")); } } break; } } return strs; } public static Texture getBgTextureByScreenId(int screenId,AssetManager as) { String str = ""; Element root = ResConfig.ConfigScreen; int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id") == screenId) { //Gdx.app.log("", "screenId:"+screenId); str = root.getChild(i).get("bgImage"); //imgBg = new Texture(Gdx.files.internal("image/" + str + ".png")); return as.get("image/" + str + ".png", Texture.class); } } return null; } public static void main(String[] args) { /*int i,y=0,n=0;boolean rs; for(i=0;i<1000;i++) { if(ifGet(99)) { y++; }else { n++; } } System.out.println("y:"+y+" n:"+n);*/ } }
package com.zhfy.game; import java.util.List; import com.badlogic.gdx.Application; import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Game; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.PixmapPacker; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.zhfy.game.screen.CommderScreen; import com.zhfy.game.screen.ConquestScreen; import com.zhfy.game.screen.EmpireScreen; import com.zhfy.game.screen.ErrorScreen; import com.zhfy.game.screen.LoadingScreen; import com.zhfy.game.screen.MainScreen; import com.zhfy.game.screen.MapDetailScreen; import com.zhfy.game.screen.MapDetailScreenBF; import com.zhfy.game.screen.MapScreen; import com.zhfy.game.screen.OptionScreen; import com.zhfy.game.screen.StartScreen; import com.zhfy.game.config.ResConfig; import com.zhfy.game.framework.GameUtil; import com.zhfy.game.model.content.RuleBtlDAO; import com.zhfy.game.model.framework.TextureRegionDAO; public class MainGame extends Game { // 视口世界的宽高统使用 1024 * 768, 并统一使用伸展视口(StretchViewport) /*public final float WORLD_WIDTH = 1024; public final float WORLD_HEIGHT = 768;*/ /** 世界宽度 */ private float worldWidth; /** 世界高度 */ private float worldHeight; /** 资源管理器 */ private AssetManager assetManager; private StartScreen startScreen; private MainScreen mainScreen; private EmpireScreen empireScreen; private ConquestScreen conquestScreen; private CommderScreen commderScreen; private OptionScreen optionScreen; private ErrorScreen errorScreen; private LoadingScreen loadingScreen; private MapScreen mapScreen; private MapDetailScreen mapDetailScreen; Music music; private int mapId; @Override public void create () { worldWidth = ResConfig.FIX_WORLD_WIDTH; worldHeight = Gdx.graphics.getHeight() * worldWidth / Gdx.graphics.getWidth(); //资源加载器加载资源 assetManager = new AssetManager(); //加载资源 // assetManager=GameUtil.loadPicByPath(assetManager, ResConfig.Atlas.IMAGE_PATH, ".png", TextureAtlas.class); //获取加载图像 //通用资源 assetManager=GameUtil.loadResByConfig(assetManager, 0); assetManager=GameUtil.loadResByConfig(assetManager, 1); assetManager.finishLoading(); // 创建开始场景 setStartScreen(new StartScreen(this)); // 设置当前场景为开始场景 setScreen(getStartScreen()); } /** * 开始场景展示完毕后调用该方法切换到主游戏场景 */ public void showGameScreen(int beforeScreenId,int nextScreenId) { boolean needLoad= GameUtil.ifNeedLoad(beforeScreenId,nextScreenId); //清空之前的场景 disposeScreen(beforeScreenId); if(needLoad) { loadingScreen = new LoadingScreen(this, assetManager, beforeScreenId, nextScreenId); setScreen(loadingScreen); }else { toScreen(nextScreenId); } if (getStartScreen() != null) { // 由于 StartScreen 只有在游戏启动时展示一下, 之后都不需要展示, // 所以启动完 GameScreen 后手动调用 StartScreen 的 dispose() 方法销毁开始场景。 getStartScreen().dispose(); // 场景销毁后, 场景变量值空, 防止二次调用 dispose() 方法 setStartScreen(null); } } /** * 开始场景展示完毕后调用该方法切换到主游戏场景,针对地图场景 */ public void showGameScreen(int beforeScreenId,int nextScreenId,int mapId) { this.mapId=mapId; showGameScreen(beforeScreenId,nextScreenId); } public void toScreen(int nextScreenId) { if(nextScreenId==1) { mainScreen = new MainScreen(this); setScreen(mainScreen); }else if(nextScreenId==3) { empireScreen = new EmpireScreen(this); setScreen(empireScreen); }else if(nextScreenId==4) { conquestScreen = new ConquestScreen(this); setScreen(conquestScreen); }else if(nextScreenId==5) { commderScreen = new CommderScreen(this); setScreen(commderScreen); }else if(nextScreenId==6) { optionScreen = new OptionScreen(this); setScreen(optionScreen); }else if(nextScreenId==7) { mapScreen = new MapScreen(this); setScreen(mapScreen); }else if(nextScreenId==71) { mapDetailScreen = new MapDetailScreen(this); setScreen(mapDetailScreen); }else { errorScreen= new ErrorScreen(this); setScreen(errorScreen); } } public void disposeScreen(int beforeScreenId) { if(beforeScreenId==1) { if (mainScreen != null) { mainScreen.dispose(); mainScreen=null; } }else if(beforeScreenId==3) { if (empireScreen != null) { empireScreen.dispose(); empireScreen=null; } }else if(beforeScreenId==4) { if (conquestScreen != null) { conquestScreen.dispose(); conquestScreen=null; } }else if(beforeScreenId==5) { if (commderScreen != null) { commderScreen.dispose(); commderScreen=null; } }else if(beforeScreenId==6) { if (optionScreen != null) { optionScreen.dispose(); optionScreen=null; } }else if(beforeScreenId==7) { if (mapScreen != null) { mapScreen.dispose(); mapScreen=null; } }else if(beforeScreenId==71) { if (mapDetailScreen != null) { mapDetailScreen.dispose(); mapDetailScreen=null; } }else if(beforeScreenId==-1){//全部销毁 if (getStartScreen() != null) { getStartScreen().dispose(); setStartScreen(null); } if (mainScreen != null) { mainScreen.dispose(); mainScreen = null; } if (empireScreen != null) { empireScreen.dispose(); empireScreen = null; } if (conquestScreen != null) { conquestScreen.dispose(); conquestScreen = null; } if (optionScreen != null) { optionScreen.dispose(); optionScreen = null; } if (commderScreen != null) { commderScreen.dispose(); commderScreen = null; } if (mainScreen != null) { mapScreen.dispose(); mapScreen = null; } if (mapDetailScreen != null) { mapDetailScreen.dispose(); mapDetailScreen = null; } if (errorScreen != null) { errorScreen.dispose(); errorScreen = null; } }else { if (errorScreen != null) { errorScreen.dispose(); errorScreen=null; } } } @Override public void dispose() { super.dispose(); // super.dispose() 不能删除, 在父类中还有其他操作(调用当前场景的 hide 方法) // 应用退出时释放资源 if (assetManager != null) { assetManager.dispose(); } // 游戏程序退出时, 手动销毁还没有被销毁的场景 disposeScreen(-1); } public StartScreen getStartScreen() { return startScreen; } public void setStartScreen(StartScreen startScreen) { this.startScreen = startScreen; } public float getWorldWidth() { return worldWidth; } public void setWorldWidth(float worldWidth) { this.worldWidth = worldWidth; } public float getWorldHeight() { return worldHeight; } public void setWorldHeight(float worldHeight) { this.worldHeight = worldHeight; } public AssetManager getAssetManager() { return assetManager; } public void setAssetManager(AssetManager assetManager) { this.assetManager = assetManager; } public int getMapId() { return mapId; } public void setMapId(int mapId) { this.mapId = mapId; } }
package com.zhfy.game.framework; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.Properties; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.PixmapIO; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.TextureData; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.XmlReader; import com.badlogic.gdx.utils.XmlReader.Element; import com.badlogic.gdx.utils.viewport.StretchViewport; import com.zhfy.game.MainGame; import com.zhfy.game.config.ResConfig; import com.zhfy.game.framework.tool.FSearchTool; import com.zhfy.game.model.content.MapBinDAO; import com.zhfy.game.model.content.def.DefMap; import com.zhfy.game.model.content.def.DefPt; import com.zhfy.game.model.content.def.DefTerrainimg; import com.zhfy.game.model.framework.PixmapDAO; import com.zhfy.game.model.framework.PixmapListDAO; import com.zhfy.game.model.framework.TextureDAO; import com.zhfy.game.model.framework.TextureListDAO; import com.zhfy.game.model.framework.TextureRegionDAO; import com.zhfy.game.model.framework.TextureRegionListDAO; import com.zhfy.game.screen.actor.base.BaseActor; public class GameFramework { //private TextureListDAO imgLists; //private Texture imgBg; //private List<Stage> stages; private byte[] bt;// 等待清空 private MapBinDAO mapBinDao;// 等待清空 //private Pixmap pixmap;// 使用完就清空 //private PixmapListDAO pixmapLists;// 使用完就清空 private FSearchTool tool ;//哪个用到哪个初始化 /*//TODO // 通过使用场景来清理图片 public void textureDispose(int beforeScreenId,int nextScreenId) { Gdx.app.log("执行了内存销毁 " ," screenId:"+beforeScreenId); //获取当前场景,下一个场景要加载的资源图 //比对资源,把不用的资源清除掉 // 通过使用场景id获取图片名集合 List<String> nameList = getTextureNameByScreenId(beforeScreenId); // 根据图片名集合清理资源 imgLists.clearTexture(nameList); // 清理背景图 if (imgBg != null) { imgBg.dispose(); imgBg = null; } }*/ // 通过screenId获取要读取的图片资源 public List<String> getTextureNameByScreenId(int screenId) { List<String> strs = new ArrayList<String>(); XmlReader reader = ResConfig.reader; Element root = ResConfig.ConfigScreen; int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id") == screenId) { Array<Element> xmlFiles = root.getChild(i) .getChildrenByNameRecursively("xmlFile"); for (Element xmlFile : xmlFiles) { strs.add(xmlFile.get("name")); } break; } } return strs; } /*// 根据screenid,获取要加载的资源 public TextureRegionListDAO getTextureReigonByScreenId(int screenId) { // 验证imgLists是否有东西 List<String> nameList = getTextureNameByScreenId(screenId); TextureRegionListDAO imgList = new TextureRegionListDAO(); for (int i = 0; i < nameList.size(); i++) { XmlReader reader = ResConfig.reader; *//** * root是整个xml文件从根节点算起,此处是指<Credits> </Credits> *//* Element root = reader.parse( Gdx.files.internal("image/" + nameList.get(i) + ".xml")); String imgFile = root.getAttribute("imagePath"); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = root.getChildrenByNameRecursively("sprite"); for (Element image : images) { TextureRegion imgRegion = new TextureRegion( imgLists.getName(nameList.get(i)).getTexture(), image.getInt("x"), image.getInt("y"), image.getInt("w"), image.getInt("h")); TextureRegionDAO imgRegionDAO = new TextureRegionDAO(); imgRegionDAO.setTextureRegion(imgRegion); imgRegionDAO.setRefx(image.getInt("refx")); imgRegionDAO.setRefy(image.getInt("refy")); imgRegionDAO.setName(image.get("n").replace(".png", "")); imgList.add(imgRegionDAO); // Gdx.app.log("getImgName",image.get("n").replace(".png", "")+" // x:"+image.getInt("refx")+" y:"+image.getInt("refy")); } } imgList.check(); return imgList; }*/ /*// 根据imgName,获取要加载的资源 public TextureRegionListDAO getTextureReigonByImgFileName( String imgFileName) { // 验证imgLists是否有东西 TextureRegionListDAO imgList = new TextureRegionListDAO(); XmlReader reader = ResConfig.reader; Element root = reader .parse(Gdx.files.internal("image/" + imgFileName + ".xml")); String imgFile = root.getAttribute("imagePath"); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = root.getChildrenByNameRecursively("sprite"); for (Element image : images) { TextureRegion imgRegion = new TextureRegion( imgLists.getName(imgFileName).getTexture(), image.getInt("x"), image.getInt("y"), image.getInt("w"), image.getInt("h")); TextureRegionDAO imgRegionDAO = new TextureRegionDAO(); imgRegionDAO.setTextureRegion(imgRegion); imgRegionDAO.setRefx(image.getInt("refx")); imgRegionDAO.setRefy(image.getInt("refy")); imgRegionDAO.setName(image.get("n").replace(".png", "")); imgList.add(imgRegionDAO); // Gdx.app.log("getImgName",image.get("n").replace(".png", "")+" // x:"+image.getInt("refx")+" y:"+image.getInt("refy")); } imgList.check(); return imgList; }*/ // TODO 未验证 // 根据imgName,获取要加载的资源 /*public PixmapListDAO getPixmapByImgFileName(String fileName) { PixmapListDAO pixmapLists=new PixmapListDAO(); // 验证pixmapLists是否有东西 XmlReader reader = ResConfig.reader; Element root = reader .parse(Gdx.files.internal("pixmap/" + fileName + ".xml")); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = root.getChildrenByNameRecursively("sprite"); for (Element image : images) { PixmapDAO pixmapDAO = new PixmapDAO(); pixmapDAO.setPixmap( new Pixmap(Gdx.files.internal("pixmap/"+image.get("n"))));; pixmapDAO.setRefx(image.getInt("refx")); pixmapDAO.setRefy(image.getInt("refy")); pixmapDAO.setName(image.get("n").replace(".png", "")); pixmapLists.add(pixmapDAO); } pixmapLists.check(); return pixmapLists; }*/ /* // 根据screenId获取加载的背景图名称 public Texture getBgTextureByScreenId(int screenId,AssetManager as) { XmlReader reader = ResConfig.reader; String str = ""; Element root = ResConfig.ConfigScreen; int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id") == screenId) { str = root.getChild(i).get("bgImg"); //imgBg = new Texture(Gdx.files.internal("image/" + str + ".png")); imgBg =as.get("image/" + str + ".png", Texture.class); return imgBg; } } return null; }*/ // 根据screenId来把资源存入 getResourceByScreentId /*public void init(int screenId) { imgLists = new TextureListDAO(); List<String> nameList = getTextureNameByScreenId(screenId); //stages = new ArrayList<Stage>(); for (int i = 0; i < nameList.size(); i++) { XmlReader reader = ResConfig.reader; *//** * root是整个xml文件从根节点算起,此处是指<Credits> </Credits> *//* Element root = reader.parse( Gdx.files.internal("image/" + nameList.get(i) + ".xml")); String imgFile = root.getAttribute("imagePath"); // 加入临时文件 TextureDAO tempImgDao = new TextureDAO(); tempImgDao.setName(imgFile.toString().substring(0, imgFile.toString().lastIndexOf("."))); tempImgDao.setTexture( new Texture(Gdx.files.internal("image/" + imgFile))); imgLists.add(tempImgDao); // Gdx.app.log( "setImgName", imgFile.toString().substring(0, // imgFile.toString().lastIndexOf("."))); } }*/ // 根据配置文件生成相关stage对象并返回 // stage相当于一个窗口,一个游戏场景由一个或多个窗口组成 // 暂时废弃 /* public List<Stage> getStagesByScreenId(int screenId) { Stage stage = new Stage(new StretchViewport(ResConfig.FIX_WORLD_WIDTH, Gdx.graphics.getHeight() * ResConfig.FIX_WORLD_WIDTH / Gdx.graphics.getWidth())); GameFramework framework = new GameFramework(); // 根据screenId获取下级元素 XmlReader reader = ResConfig.reader; Element root = reader .parse(Gdx.files.internal("config/config_layout.xml")); int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("screenId") == screenId) { // 绘制背景图 imgBg = new Texture(Gdx.files.internal( "image/" + root.getChild(i).get("bg") + ".png")); BaseActor actor = new BaseActor(new TextureRegion(imgBg)); stage.addActor(actor); // 如果defaultWinId不为空,则查找对应win if (!root.getChild(i).get("defaultWinId").equals("")) { int childNum1 = root.getChild(i).getChildCount(); for (int i1 = 0; i1 < childNum1; i1++) { // 生成win下的各个组件 pixmap 拼合图 textures 装饰图 buttons 按钮 Element pixmaps = root.getChild(i).getChild(i1) .getChildByName("pixmaps"); // Gdx.app.log("imgs",imgs.size+""); // 临时-拼合图 { Array<Element> pixmapList = pixmaps .getChildrenByNameRecursively("pixmap"); for (Element pixmap : pixmapList) { Array<Element> imgs = pixmap .getChildrenByNameRecursively("img"); // Gdx.app.log("imgs",imgs.size+""); for (Element img : imgs) { } } } Element textures = root.getChild(i).getChild(i1) .getChildByName("textures"); // 装饰图 { } Element buttons = root.getChild(i).getChild(i1) .getChildByName("buttons"); // 按钮 { } if (stage != null) { //stages.add(stage); } // 打开默认窗口 } } } } return null; }*/ //TODO 随后增加根据 btl的x,y,w,h获取地图属性 // 根据mapid生成MapBinDAO类 public MapBinDAO getMapDaoByMapId(int mapId) { XmlReader reader = ResConfig.reader; String str = ""; Element root = reader.parse(Gdx.files.internal("config/def_map.xml")); int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id") == mapId) { str = root.getChild(i).get("name"); //TODO bt = Gdx.files.local("bin/" + str + ".bin").readBytes(); try { mapBinDao = GameMap.readMapBin(bt); } catch (IOException e) { e.printStackTrace(); } return mapBinDao; } } return mapBinDao; } //根据传入的地图编号保存地图 public void saveMapDaoByMapId(MapBinDAO mapbin,int mapId) { XmlReader reader = ResConfig.reader; String str = ""; Element root = reader.parse(Gdx.files.internal("config/def_map.xml")); int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id") == mapId) { str = root.getChild(i).get("name"); String path="bin/" + str + ".bin"; GameMap.saveMapBin(mapbin,path); } } } //根据MapId获得地图属性 public DefMap getDefMapByMapId(int id) { DefMap defMap = new DefMap(); List<DefMap> defMaps = new ArrayList<DefMap>(); try { defMaps = GameUtil.getDaoListByClass(defMap, "config/def_map.xml"); } catch (Exception e) { e.printStackTrace(); } if (defMaps != null) { /*for (int i = 0; i < defMaps.size(); i++) { if (defMaps.get(i).getId() == id) { return defMaps.get(i); } }*/ try { tool= new FSearchTool(defMaps, "id"); return (DefMap) tool.searchTask((id+"")); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } // 依据id画全图 public Texture getMapByMapId(int id) { // 2.1加载图片资源 一次性使用 用完就删 //TextureRegionListDAO mapRegionList = getTextureReigonByImgFileName("bt_tiles"); PixmapListDAO pixmapLists=getPixmapListByFileName("pm_tiles"); // 2.2加载地图属性 DefTerrainimg defTerrainimg = new DefTerrainimg(); DefMap defMap = new DefMap(); List<DefTerrainimg> defTerrainimgs = new ArrayList<DefTerrainimg>(); List<DefMap> defMaps = new ArrayList<DefMap>(); boolean state=false; try { defTerrainimgs = GameUtil.getDaoListByClass(defTerrainimg, "config/def_terrainimg.xml"); defMaps = GameUtil.getDaoListByClass(defMap, "config/def_map.xml"); } catch (Exception e) { e.printStackTrace(); } // 2.3加载bin mapBinDao = getMapDaoByMapId(id); // 2.4读取map.xml获取地图属性 if (defMaps != null) { /*for (int i = 0; i < defMaps.size(); i++) { if (defMaps.get(i).getId() == id) { defMap = defMaps.get(i); state=true; break; } }*/ try { tool= new FSearchTool(defMaps, "id"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } defMap =(DefMap) tool.searchTask((id+"")); if(defMap!=null) { state=true; } } if(state) { Gdx.app.log("存在地图:", "继续"); }else { Gdx.app.log("不存在地图:", "终止"); return null; } // 2.5生成Pixmap Pixmap pixmap=GameMap.createPixmapByDefMap(defMap); //绘制底纹 pixmap=GameMap.coverImgByPtimgId(pixmap,2); long startTime = System.currentTimeMillis(); //获取开始时间 //绘图 pixmap=GameMap.getPixmapByDao(mapBinDao,pixmap,pixmapLists,defTerrainimgs,0,mapBinDao.getMapbin().size()); long endTime = System.currentTimeMillis(); //获取结束时间 Gdx.app.log("地图构建", " 运行时间:"+(endTime - startTime) + "ms"); // 再由新的 Pixmap 对象生成一个新的 Texture 对象 Texture textureMap = new Texture(pixmap, Pixmap.Format.RGBA8888,false); if(pixmap!=null) { //这里输出截图进行测试 //PixmapIO.writePNG(Gdx.files.external(defMap.getName()+".png"), pixmap); pixmap.dispose(); //Gdx.app.log("地图图片保存", "成功"); } //clearPixmapListByFileName("pm_tiles"); return textureMap; } // 根据条件画图 public Pixmap getPixmapDecorateByDao(Pixmap pixmap,MapBinDAO mapBinDao,DefMap defMap) { // 2.1加载图片资源 一次性使用 用完就删 //TextureRegionListDAO mapRegionList = getTextureReigonByImgFileName("bt_tiles"); PixmapListDAO pixmapLists=getPixmapListByFileName("pm_tiles"); // 2.2加载地图属性 DefTerrainimg defTerrainimg = new DefTerrainimg(); List<DefTerrainimg> defTerrainimgs = new ArrayList<DefTerrainimg>(); try { defTerrainimgs = GameUtil.getDaoListByClass(defTerrainimg, "config/def_terrainimg.xml"); } catch (Exception e) { e.printStackTrace(); } long startTime = System.currentTimeMillis(); //获取开始时间 //绘图 pixmap=GameMap.getPixmapByDao(mapBinDao,pixmap,pixmapLists,defTerrainimgs,0,mapBinDao.getMapbin().size()); long endTime = System.currentTimeMillis(); //获取结束时间 Gdx.app.log("地图构建", " 运行时间:"+(endTime - startTime) + "ms"); //clearPixmapListByFileName("pm_tiles"); return pixmap; } //根据条件给陆地打孔 public Pixmap getLandByDAO(MapBinDAO mapBinDAO, Pixmap pixmap, int mapx, int mapy,int mapw,int maph) { //加载打孔图片 PixmapListDAO pixmapLists=getPixmapListByFileName("pm_shadow"); pixmap=GameMap.getLandByDAO(mapBinDAO,pixmap,pixmapLists,mapx,mapy,mapw,maph); //clearPixmapListByFileName("pm_shadow"); return pixmap; } //加载内存图片PixmapListDAO pixmapLists 目标pm_tiles 则传入pm_tiles TODO public PixmapListDAO getPixmapListByFileName(String fileName) { //1读取路径下说明文件 XmlReader reader = ResConfig.reader; Element root = reader .parse(Gdx.files.internal("pixmap/"+fileName.substring(3)+"/" + fileName + ".xml")); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = root.getChildrenByNameRecursively("sprite"); //验证pixmapLists是否有东西 PixmapListDAO pixmapLists=new PixmapListDAO(); //2根据说明文件添加到pixmapLists for (Element image : images) { PixmapDAO pixmapDAO = new PixmapDAO(); pixmapDAO.setPixmap( new Pixmap(Gdx.files.internal("pixmap/"+fileName.substring(3)+"/" +image.get("n"))));; pixmapDAO.setRefx(image.getInt("refx")); pixmapDAO.setRefy(image.getInt("refy")); pixmapDAO.setName(image.get("n").replace(".png", "")); pixmapLists.add(pixmapDAO); } pixmapLists.check(); return pixmapLists; } //清除内存图片PixmapListDAO pixmapLists /*public void clearPixmapListByFileName(String fileName) { //1读取路径下说明文件 //2根据说明文件移除pixmapLists的内容,并depose XmlReader reader = ResConfig.reader; Element root = reader .parse(Gdx.files.internal("pixmap/"+fileName.substring(3)+"/" + fileName + ".xml")); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = root.getChildrenByNameRecursively("sprite"); for (Element image : images) { pixmapLists.remove(image.get("n").replace(".png", "")); } pixmapLists.check(); }*/ }
package com.zhfy.game.config; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.utils.XmlReader; import com.badlogic.gdx.utils.XmlReader.Element; /** * 资源常量 * * @xietansheng */ public interface ResConfig { /** 固定世界宽度为1024, 高度根据实际屏幕比例换算 */ public static final float FIX_WORLD_WIDTH = 1024; public static final XmlReader reader = new XmlReader(); public static final Element ConfigRes = reader.parse(Gdx.files.internal("config/config_res.xml")); public static final Element ConfigScreen = reader.parse(Gdx.files.internal("config/config_screen.xml")); public static final Element ConfigLayout = reader.parse(Gdx.files.internal("config/config_layout.xml")); //TODO /** * 相关物理参数(调节物理参数可改变游戏难度) */ public static interface Physics { } //TODO /** * 纹理图集 */ public static interface Atlas { public static final int PACK_PIC_SIDE = 512; public static final String IMAGE_PATH = "image/"; } //TODO /** * 音效 */ public static interface Audios { } //TODO /** * Preferences 本地存储相关 */ public static interface Prefs { } //地图相关参数 public static interface Map { public static final int HEXAGON_WIDTH = 148; public static final int HEXAGON_HEIGHT = 128; public static final int GRID_WIDTH =112;//为六边形不重复的长 public static final float MAP_SCALE = 0.32f; } //rule规则 public static interface Rules { public static final String GG1_BTL_RULE = "src/resource/rule/rule_btl_gg1.xml"; public static final String WC4_BTL_RULE = "src/resource/rule/rule_btl_wc4.xml"; } //测试用btl public static interface Btls { public static final String GG1_BTL = "src/resource/btl/gg1.btl"; public static final String WC4_BTL = "src/resource/btl/wc4.btl"; } }