15.资源加载器,根据配置文件自动加载文件

前言

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

思路

设定两个配置文件,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

原文地址:https://www.cnblogs.com/tysk/p/10993115.html

时间: 2024-10-25 08:00:31

15.资源加载器,根据配置文件自动加载文件的相关文章

Android数据分批加载-滑动到底部自动加载列表

Android数据分批加载-滑动到底部自动加载列表 2014年5月9日 本博文介绍如何进行数据分批加载,在应用开发当中会经常使用到ListView,点击更多加载数据是我们经常简单,为了提供用户体验,当用户将列表滚动到底部自动加载数据,这样的形式用得比较多. 下面给大家提供的例子是,每次模拟20条数据,滑动到底部时再请求20条数据直到请求到限定页数为止 具体代码实现: /08_Datapageload/src/com/wwj/datapageload/MainActivity.java packa

[JS前端开发] js/jquery控制页面动态加载数据 滑动滚动条自动加载事件

页面滚动动态加载数据,页面下拉自动加载内容 相信很多人都见过瀑布流图片布局,那些图片是动态加载出来的,效果很好,对服务器的压力相对来说也小了很多 有手机的相信都见过这样的效果:进入qq空间,向下拉动空间,到底部时,会动态加载剩余的说说或者是日志 今天我们就来看看他们的实现思路和js控制动态加载的代码 下面的代码主要是控制滚动条下拉时的加载事件的 在下面代码说明出,写上你的操作即可,无论是加载图片还是加载记录数据  都可以 别忘了引用jquery类库 [JavaScript] 纯文本查看 复制代码

net core手动加载dll,无法自动加载其依赖项

用的net core版本是2.1,也许在后续的版本中已经修复了这个问题 今天在尝试用net core写demo的时候,发现了这个问题.因为都是使用DI,所以就没有我的网站项目里直接引用一些实现类库,而是放到了同一个目录下,在网站启动的时候用代码去加载进来.然而在实际的运行过程成中发现,指定的dll会自动加载,但是其依赖的nuget包里的dll不会被加载进来,在Google了很久,也发现了很多人提出过这个问题,在GitHub上也有人提过https://github.com/dotnet/coref

CI框架 -- 自动加载资源

CodeIgniter 的"自动加载"特性可以允许系统每次运行时自动初始化类库.辅助函数和模型. 如果你需要在整个应用程序中全局使用某些资源,为方便起见可以考虑自动加载它们. 支持自动加载的有下面这些: libraries/ 目录下的核心类 helpers/ 目录下的辅助函数 config/ 目录下的用户自定义配置文件 system/language/ 目录下的语言文件 models/ 目录下的模型类 要实现自动加载资源,你可以打开 application/config/autoloa

JavaScript AMD 模块加载器原理与实现

关于前端模块化,玉伯在其博文 前端模块化开发的价值 中有论述,有兴趣的同学可以去阅读一下. 1. 模块加载器 模块加载器目前比较流行的有 Requirejs 和 Seajs.前者遵循 AMD规范,后者遵循 CMD规范.前者的规范产出比较适合于浏览器异步环境的习惯,后者的规范产出对于写过 nodejs 的同学来说是比较爽的.关于两者的比较,有兴趣的同学请参看玉伯在知乎的回答 AMD和CMD的区别有哪些.本文希望能按照 AMD 规范来简单实现自己的一个模块加载器,以此来搞清楚模块加载器的工作原理.

Phalcon自动加载(PHP自动加载)

自动加载(phalcon\Loader) 转载请注明来源 一.php文件引入 通过 include() 或 require() 函数,可以在PHP程序执行之前在该文件中插入一个文件的内容. 区别:处理错误的方式不同.include() 函数会生成一个警告(但是脚本会继续执行),而 require() 函数会生成一个致命错误(fatal error)(在错误发生后脚本会停止执行) * 正因为在文件不存在或被重命名后脚本不会继续执行,因此我们推荐使用 require() 而不是 include().

final,类的自动加载,命名空间

final是干什么的一般是为了防止父类的一个方法被重写如果父类中的方法被声明为 final,则子类无法覆盖该方法.如果一个类被声明为 final,则不能被继承. Note: 属性不能被定义为 final,只有类和方法才能被定义为 final. 类的自动加载类的自动加载是指,在外面的页面中,并不需要去"引入"类文件,但是程序会在需要的时候动态加载需要的类文件. spl_autoload_register() 函数可以注册任意数量的自动加载器,当使用尚未被定义的类(class)和接口(in

C编译器、链接器、加载器详解

摘自http://blog.csdn.net/zzxian/article/details/16820035 C编译器.链接器.加载器详解 一.概述 C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接.编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程.链接是把目标文件.操作系统的启动代码和用到的库文件进行组织形成最终生成可加载.可执行代码的过程. 过程图解如下: 预处理器:将.c 文件转化成 .i文件,使用的gcc命令是

php 类的自动加载

在编写面向对象(OOP) 程序时,很多开发者为每个类新建一个 PHP 文件. 这会带来一个烦恼:每个脚本的开头,都需要包含(include)一个长长的列表(每个类都有个文件). 在 PHP 5 中,已经不再需要这样了. spl_autoload_register() 函数可以注册任意数量的自动加载器,当使用尚未被定义的类(class)和接口(interface)时自动去加载.通过注册自动加载器,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类. Tip 尽管 __autoload()