前言

以前我想自己写一个加载器,用的时候加载,不用的时候再去掉,结果发现这种方式可能因为资源不统一在安卓上可能出现问题,所以搜集资料,弄成根据配置文件加载

思路

设定两个配置文件,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);*/
        
    }
 
}
LoadingScreen

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);*/
       
    }
}
GameUtil
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;
    }


   


    
}
MainGame
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();
    }*/
    
    
    

    
    
}
GameFramework
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";

    }

    
    
}
ResConfig

 

posted on 2019-06-09 12:10  黑狱  阅读(426)  评论(0编辑  收藏  举报