19.关于游戏设计的一点感悟

在这之前我并没有怎么接触过libgdx,仔细研究的也只是libgdx的一个飞翔的小鸟示例

导致我之前写的时候都是先自定义一个actor,然后把所有东西都写道actor里.其他stage的东西基本没用到

最近我遇到个需求

在指定位置生成标志,点击显示预览图等界面,然后操作

都在一个actor中写的我不得不考虑其他方案.

最后参照小鸟示例.通过自定义stage将坐标,以及游戏数据从原来的actor剥离.

根据提取的坐标就可以在stage里随意使用

之前试用过group方案,但是感觉group还是没stage这种自由

记录以备忘

package com.zhfy.game.screen;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.ScreenAdapter;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.profiling.GLProfiler;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.input.GestureDetector.GestureListener;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
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.GameLayout;
import com.zhfy.game.framework.GameUtil;
import com.zhfy.game.model.framework.TextureRegionListDAO;
import com.zhfy.game.screen.actor.SMapHistoryActor;
import com.zhfy.game.screen.stage.SMapStage;

/**
 * 主游戏场景(游戏主界面), 实现 Screen 接口 或者 继承 ScreenAdapter 类 <br/>
 * 这里就展示一张图片代表游戏主界面
 */
public class SMapScreen extends ScreenAdapter  {

    private MainGame game;


    private SMapStage gameStage;



    private TextureRegionListDAO imgLists;


    private ImageButton button;
    //使用场景
    private int screenId=81;


    private int stageId;


    InputProcessorEvent processorEvent;
    MapListener mapListener;
    InputMultiplexer multiplexer;

    boolean isTouching;
    float touchBaseX;
    float touchBaseY;
    float touch_X;
    float touch_Y;
    float moveX;
    float moveY;
    Label label;

    Label gameTimeLabel;
    //中心点位置
    float cx;
    float cy;
    float javaHeap;
    float javaMaxHeap;
    boolean ifLoop;

    //游戏舞台的基本宽高
    static  float GAMESTAGE_WIDTH;
    static  float GAMESTAGE_HEIGHT;
    //GLProfile  gp = new GrayFilter();
    GLProfiler  gp;



    //ui
    private Element uiR;
    private List<Element> ui;
    private XmlReader reader ;
    private String bgTexture;
    private float tempX,tempY,tempW,tempH;
    private com.badlogic.gdx.utils.Array<Element> buttonEs;
    private Map tempMap;

    private int i;//function的计数标志,从1开始
   // private SMapHistoryActor mapActor;



    public SMapScreen(MainGame mainGame)  {


        this.game=mainGame;

        GAMESTAGE_WIDTH=game.getWorldWidth();
        GAMESTAGE_HEIGHT=game.getWorldHeight();

        //ui
        {
            reader = ResConfig.reader;
            uiR=GameLayout.getXmlERootByScreenId(screenId);
            ui=GameUtil.getXmlEByRootE(uiR);
        }


        setStageId(mainGame.getStageId());


        //1根据mapid读取地图DAO
        //2加载地图图片,生成图片作为背景
        /*textureMap=framework.getMapByMapId(mapId);
        defMap=framework.getDefMapByMapId(mapId);
        mapW=defMap.getWidth();
        mapH=defMap.getHeight();
        mapSprite = new Sprite(textureMap);*/

        //3增加拖动等功能,可以拖动地图
        //4替换地图dao的地图素材
        //5保存地图


        gp =new GLProfiler(Gdx. graphics);
        gp.enable();

        isTouching=false;
        multiplexer = new InputMultiplexer();

        //根据screenId初始化资源
        //获取对应图片
        imgLists=GameUtil.getTextureReigonByScreenId( screenId,mainGame.getAssetManager());

        // 使用伸展视口创建舞台
        gameStage = new SMapStage(mainGame,new StretchViewport(GAMESTAGE_WIDTH, GAMESTAGE_HEIGHT),screenId,imgLists);
        // 将输入处理设置到舞台(必须设置, 否则点击按钮没效果)

        multiplexer.addProcessor(gameStage);




        // 创建游戏人物演员
        //mapActor = new mapActor(new TextureRegion(mapSprite),0,0,mapW,mapH,GAMESTAGE_WIDTH, GAMESTAGE_HEIGHT);


        //mapActor = new MapActor(stageId,GAMESTAGE_WIDTH, GAMESTAGE_HEIGHT,mainGame.getAssetManager(),screenId);

        // 添加演员到舞台
        // gameStage.addActor(mapActor);
        //stageId不对,应从中获取对应的mapId,ifLoop也是 TODO
        ifLoop=true;
       // mapActor  = new SMapHistoryActor(stageId,GAMESTAGE_WIDTH, GAMESTAGE_HEIGHT,mainGame.getAssetManager(),screenId,imgLists);
       // gameStage.addActor(mapActor);
        //将来以玩家选择国家首都为位置标准 TODO





        i=1;
        for  (Element window:ui) {
            tempX=window.getInt("x");tempY=window.getInt("y");tempW=window.getInt("w");tempH=window.getInt("h");

            //遍历window的buttons按钮
            buttonEs = window.getChildByName("buttons").getChildrenByNameRecursively("button");  // 递归遍历,否则的话返回null
            for (Element buttonE : buttonEs) {
                //Gdx.app.log("ui测试", button.get("remark"));

                button = new ImageButton(new TextureRegionDrawable(imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion()),new TextureRegionDrawable(imgLists.getTextureByName(buttonE.get("imgDownName")).getTextureRegion()),new TextureRegionDrawable(imgLists.getTextureByName(buttonE.get("imgDownName")).getTextureRegion()));
                button.setSize(buttonE.getInt("w")==0?imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion().getRegionWidth():buttonE.getInt("w")*imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion().getRegionWidth()/100, buttonE.getInt("h")==0?imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion().getRegionHeight():buttonE.getInt("h")*imgLists.getTextureByName(buttonE.get("imgUpName")).getTextureRegion().getRegionHeight()/100);
                button.setPosition(
                        buttonE.getInt("x")*gameStage.getWidth()/100+button.getWidth()/2>gameStage.getWidth()?gameStage.getWidth()-button.getWidth():buttonE.getInt("x")*gameStage.getWidth()/100-button.getWidth()/2<0?0:buttonE.getInt("x")*gameStage.getWidth()/100-button.getWidth()/2,
                        buttonE.getInt("y")*gameStage.getWidth()/100+button.getHeight()/2>gameStage.getHeight()?gameStage.getHeight()-button.getHeight():buttonE.getInt("y")*gameStage.getHeight()/100-button.getHeight()/2<0?0:buttonE.getInt("y")*gameStage.getHeight()/100-button.getHeight()/2);
                tempMap=new HashMap();
                tempMap.put("FUNCTION_ID", buttonE.get("functionId"));
                tempMap.put("ID", i);
                i++;
                function(tempMap);
                gameStage.addActor(button);
                Gdx.input.setInputProcessor(gameStage);
            }
        }
        //文字示例
        label=new Label("FPS:"+Gdx.graphics.getFramesPerSecond(),new LabelStyle(mainGame.getFont(), null));

        label.setWidth(200);//设置每行的宽度
        label.setWrap(true);//开启换行
        label.setPosition(20, 40);


        gameTimeLabel=new Label(gameStage.getsMapDAO().getTime().getTime(),new LabelStyle(mainGame.getFont(), null));
        gameTimeLabel.setPosition(GAMESTAGE_WIDTH/2, GAMESTAGE_HEIGHT*0.95f);

        gameStage.addActor(label);
        gameStage.addActor(gameTimeLabel);



        processorEvent = new InputProcessorEvent();
        mapListener=new MapListener();

        Gdx.app.log("平台", Gdx.app.getType()+"");
        switch (Gdx.app.getType()) {
            case Desktop:// Code for Desktop applicationbreak;
                multiplexer.addProcessor(processorEvent);
            case Android:// Code for Android applicationbreak;
                multiplexer.addProcessor(new GestureDetector(mapListener));
            case WebGL:// Code for WebGL applicationbreak;
                multiplexer.addProcessor(processorEvent);
            default:// Unhandled (new?) platform applicationbreak;
                multiplexer.addProcessor(processorEvent);
                multiplexer.addProcessor(new GestureDetector(mapListener));
        }
        Gdx.input.setInputProcessor(multiplexer);


    }

    @Override
    public void render(float delta) {

        handleInput();
        gameStage.draw();
        gameStage.act();
        //Gdx.app.log("FPS:", Gdx.graphics.getFramesPerSecond()+"");

        javaHeap=(Math.round(Gdx.app.getJavaHeap()/1024/1024*10)/10);
        if(javaHeap>javaMaxHeap) {
            javaMaxHeap=javaHeap;
        }

        label.setText("FPS:"+Gdx.graphics.getFramesPerSecond());
        label.getText().appendLine("");
        label.getText().appendLine("javaHeap:"+javaHeap+"m/"+javaMaxHeap+"m");
        label.getText().appendLine("drawCalls:"+gp.getDrawCalls());
        label.getText().appendLine("nativeHeap:"+Math.round(Gdx.app.getNativeHeap()/1024/1024*10)/10+"m");
        gameTimeLabel.setText(gameStage.getsMapDAO().getTime().getTime());
        //label.getText().appendLine("inputKeyMode:"+mapActor.getKeyMode());//快捷键模式
        gp.reset();
    }

    public void dispose() {
        super.dispose();
        // 场景被销毁时释放资源
        if (gameStage != null) {
            gameStage.dispose();
            gameStage=null;
        }
    }

    //实现的功能
    public void function(Map map){
        int i=Integer.parseInt(map.get("FUNCTION_ID").toString());
        switch(i) {
            case 0://返回
                button.addListener(new ClickListener() {
                    public void clicked(InputEvent event, float x, float y) {
                        //Gdx.app.log("点击了第1个按钮", "x:" + x+" y:" + y);
                        if(game!=null) {
                            game.showGameScreen(screenId,1);
                        }
                    }
                });
                break;
            case 1://加载
                button.addListener(new ClickListener() {
                    public void clicked(InputEvent event, float x, float y) {
                        Gdx.app.log("点击了第2个按钮1", "x:" + x+" y:" + y+" stageId:"+stageId);


                    }
                });
                break;
            case 2://save
                button.addListener(new ClickListener() {
                    public void clicked(InputEvent event, float x, float y) {
                        Gdx.app.log("点击了第3个按钮", "x:" + x+" y:" + y+" stageId:"+stageId);

                    }
                });
                break;
            case 3://上一个时间
                button.addListener(new ClickListener() {
                    public void clicked(InputEvent event, float x, float y) {
                        gameStage.getsMapDAO().getTime().lastTime();
                        Gdx.app.log("点击了第4个按钮", "x:" + x+" y:" + y+" time:"+gameStage.getsMapDAO().getTime().getTime());
                    }
                });
                break;
            case 4://下一个时间
                button.addListener(new ClickListener() {
                    public void clicked(InputEvent event, float x, float y) {
                        gameStage.getsMapDAO().getTime().nextTime();
                        Gdx.app.log("点击了第5个按钮", "x:" + x+" y:" + y+" time:"+gameStage.getsMapDAO().getTime().getTime());
                    }
                });
                break;
            case 5:
                button.addListener(new ClickListener() {
                    public void clicked(InputEvent event, float x, float y) {
                        Gdx.app.log("点击了第6个按钮", "x:" + x+" y:" + y+" stageId:"+stageId);
                    }
                });
                break;
            case 6:
                button.addListener(new ClickListener() {
                    public void clicked(InputEvent event, float x, float y) {
                        Gdx.app.log("点击了第7个按钮", "x:" + x+" y:" + y+" stageId:"+stageId);


                    }
                });
                break;
            default://查询绘制省区
                button.addListener(new ClickListener() {
                    public void clicked(InputEvent event, float x, float y) {
                        Gdx.app.log("点击了默认按钮", "x:" + x+" y:" + y);
                    }
                });
                break;
        }
    }

    public void resize(int width, int height) {
        // use true here to center the camera
        // that's what you probably want in case of a UI
        gameStage.getViewport().update(width, height, false);
    }


    //电脑
    class InputProcessorEvent implements InputProcessor {

        @Override
        public boolean keyDown(int keycode) {
            /*if (keycode == Keys.BACK) {
                // 处理返回事件
            } else if (keycode == Keys.MENU) {
                // 处理菜单事件
            }*/
            return true;  // 如果此处设置为false那么不会执行key up
        }

        @Override
        public boolean keyUp(int keycode) {
            return true;
        }
        @Override
        public boolean keyTyped(char character) {  // 可以输出按键的字母和数字,不过貌似不好使
            return true;
        }

        @Override
        public boolean touchDown(int screenX, int screenY, int pointer, int button) {
            return true;
        }

        @Override
        public boolean touchUp(int screenX, int screenY, int pointer, int button) {
            return true;
        }

        @Override
        public boolean touchDragged(int screenX, int screenY, int pointer) {
            return true;
        }

        @Override
        public boolean mouseMoved(int screenX, int screenY) {
            cx=screenX;
            cy=screenY;
            return true;
        }

        @Override
        public boolean scrolled(int amount) {

            if(amount>0) {
                gameStage.setZoom(gameStage.getZoom()+0.01f,cx,cy);
            }else {
                gameStage.setZoom(gameStage.getZoom()-0.01f,cx,cy);
            }
            //Gdx.app.log("", mapActor.getZoom()+"");
            return true;
        }

    }
    //触摸屏


    class MapListener implements GestureListener{

        @Override
        public boolean touchDown(float x, float y, int pointer, int button) {
            Gdx.app.log("touchDown", "x:" + x+" y:" + y);
            return false;
        }

        @Override
        public boolean tap(float x, float y, int count, int button) {
            Gdx.app.log("tap", "x:" + x+" y:" + y);
            return false;
        }

        @Override
        public boolean longPress(float x, float y) {
            Gdx.app.log("longPress", "x:" + x+" y:" + y);
            return false;
        }

        @Override
        public boolean fling(float velocityX, float velocityY, int button) {
            Gdx.app.log("fling", "velocityX:" + velocityX+" velocityY:" + velocityY);
            return false;
        }

        @Override
        public boolean pan(float x, float y, float deltaX, float deltaY) {
            Gdx.app.log("touchDown", "x:" + x+" y:" + y);
            return false;
        }

        @Override
        public boolean panStop(float x, float y, int pointer, int button) {
            Gdx.app.log("touchDown", "x:" + x+" y:" + y);
            return false;
        }

        @Override
        public boolean zoom (float originalDistance, float currentDistance){
            Gdx.app.log("zoom", "originalDistance:" + originalDistance+" currentDistance:" + currentDistance);
            //TODO 触摸缩放事件
            return false;
        }

        @Override
        public boolean pinch (Vector2 initialFirstPointer, Vector2 initialSecondPointer, Vector2 firstPointer, Vector2 secondPointer){
            Gdx.app.log("pinch", "");
            return false;
        }
        @Override
        public void pinchStop () {
            Gdx.app.log("pinchStop", "");
        }

    }

    private void handleInput() {

        // justTouched 是开始按下手指的第一个点。
        if (Gdx.input.justTouched() && isTouching == false) {
            isTouching = true;
            touchBaseX = Gdx.input.getX(0);
            touchBaseY = Gdx.input.getY(0);
            //touchBaseX += cam.position.x - GAMESTAGE_WIDTH / 2;
            //Gdx.app.log("触摸", "1");

            // isTouched 是结束时,手指按下的点。
        } else if (Gdx.input.isTouched(0) && isTouching == true) {
            touch_X = Gdx.input.getX(0);
            touch_Y = Gdx.input.getY(0);
            moveX=(touchBaseX-touch_X)/20;
            moveY=(touch_Y-touchBaseY)/20;
            if(moveX>50) {
                moveX=50;
            }
            if(moveX<-50) {
                moveX=-50;
            }
            if(moveY>50) {
                moveY=50;
            }
            if(moveY<-50) {
                moveY=-50;
            }
            gameStage.setX(gameStage.getX()-moveX);
            gameStage.setY(gameStage.getY()-moveY);

            //Gdx.app.log("移动","x:"+mapActor.getX()+" y:"+mapActor.getY());
        }else {
            isTouching =false;
        }
           /*
           if (Gdx.input.isKeyPressed(Input.Keys.A)) {
             mapActor.setZoom(mapActor.getZoom()+0.0001f,cx,cy);
           }
           if (Gdx.input.isKeyPressed(Input.Keys.Q)) {
               mapActor.setZoom(mapActor.getZoom()-0.0001f,cx,cy);
           }*/

        if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
            gameStage.setX(gameStage.getX()+1);
        }
        if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
            gameStage.setX(gameStage.getX()-1);
        }
        if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
            gameStage.setY(gameStage.getY()+1);
        }
        if (Gdx.input.isKeyPressed(Input.Keys.UP)) {
            gameStage.setY(gameStage.getY()-1);
        }
    }

    public int getStageId() {
        return stageId;
    }

    public void setStageId(int stageId) {
        this.stageId = stageId;
    }
}
SMapScreen
package com.zhfy.game.screen.stage;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.zhfy.game.MainGame;
import com.zhfy.game.config.ResConfig;
import com.zhfy.game.framework.GameFramework;
import com.zhfy.game.framework.tool.BTLTooL;
import com.zhfy.game.model.content.BTLDAO;
import com.zhfy.game.model.content.DefDAO;
import com.zhfy.game.model.content.MapBinDAO;
import com.zhfy.game.model.content.SMapDAO;
import com.zhfy.game.model.content.def.DefHistory;
import com.zhfy.game.model.content.def.DefStage;
import com.zhfy.game.model.framework.TextureRegionListDAO;
import com.zhfy.game.screen.actor.SMapHistoryActor;
import com.zhfy.game.screen.stage.base.BaseStage;

import java.util.HashMap;
import java.util.List;

public class SMapStage extends BaseStage {

    //实现功能
    //地图对象与stage分离

    SMapHistoryActor smapBg;
    SMapDAO sMapDAO;
    BTLDAO sMapBin;
    int screenId;
    private List<Integer> coastGrid;
    private List<Integer> regionGrid;
    private List<Color> legionColors;
    TextureRegionListDAO imgLists;

    private boolean ifLoop;// 是否循环
    private boolean drawLoop;
    private float x;//玩家起始位置
    private float y;

    private float zoom;
    private float zoomMax;
    private float zoomMin;
    private float xMin;
    private float yMin;
    private float xMax;
    private float yMax;
    private int mapW_px;
    private int mapH_px;
    private MapBinDAO mapBinDAO;
    private java.util.Map regionColors;

    private HashMap playerMap;
    private DefStage defStage;
    private DefHistory defHistory;

    private GameFramework gameFramework;

    public SMapStage(MainGame mainGame, Viewport viewport, int screenId, TextureRegionListDAO imgLists) {
        super(mainGame, viewport);
        this.screenId=screenId;
        this.imgLists=imgLists;
        init();
    }


    private void init() {

        this.gameFramework=new GameFramework();
        defStage = gameFramework.getDefStageByStageId(getMainGame().getStageId());
        ifLoop = defStage.getIfLoop();

        playerMap=new HashMap();//TODO
        playerMap.put("playerCountry",0);
        playerMap.put("playerScore",0);
        playerMap.put("gameMode",0);
        playerMap.put("eventType",0);
        playerMap.put("age",0);


        boolean ifInit = Gdx.files.local("sav/"+defStage.getName()+".bin").exists();
        if(!ifInit){//如果不存在则生成
            defHistory = gameFramework.getDefHistoryByHistoryId(defStage.getId());
            BTLDAO historyDao = gameFramework.getBinDaoById(defHistory.getName(), ResConfig.Rules.RULE_FB1_HISTORY);
            mapBinDAO = gameFramework.getMapDaoByMapId(historyDao.getBm0().getBm0_2());
            sMapDAO=new SMapDAO(historyDao,mapBinDAO,defHistory.getMapId(),playerMap,defStage.getYear(),defStage.getName());
            sMapBin=sMapDAO.getSmapBin();

            historyDao=null;
        }else{
            try {
                sMapBin = BTLTooL.LoadBtl(ResConfig.Rules.RULE_FB1_SMAP,Gdx.files.local("sav/" + defStage.getName() + ".bin").readBytes());
            } catch (Exception e) {
                e.printStackTrace();
            }
            mapBinDAO = gameFramework.getMapDaoByMapId(sMapBin.getBm0().getBm0_2());
            //BTLDAO smapBin,MapBinDAO mapBin,,Map map
            sMapDAO=new SMapDAO(sMapBin,playerMap);
        }
        Gdx.app.log("ifInit",defStage.getName()+":"+ifInit);




        regionColors = sMapDAO.getRegionColors();
        coastGrid=mapBinDAO.getIdsByAround(12);
        regionGrid=mapBinDAO.getAllRegionIds();
        legionColors= DefDAO.getAllCountryColorByXml();


        smapBg=new SMapHistoryActor(getMainGame().getStageId(),getMainGame().getAssetManager(),screenId,imgLists,sMapDAO,mapBinDAO,coastGrid,legionColors,regionColors);
        addActor(smapBg);

        //TODO 玩家起始位置
        this.x=0;
        this.y=0;
        this.zoom = 1f;
        this.zoomMax = 1.2f;
        this.zoomMin = 0.5f;
        // 实际宽高
        this.mapW_px = smapBg.gettextureMain().getWidth();
        this.mapH_px = smapBg.gettextureMain().getHeight();
        this.xMax = mapW_px*this.zoom-getMainGame().getWorldWidth();;
        this.yMax = mapH_px*this.zoom-getMainGame().getWorldHeight();
        this.yMin = 0;
        this.xMin = 0;
        smapBg.setIfLoop(ifLoop);
        drawLoop=false;
        smapBg.init(getX(),getY(),getZoom(),drawLoop);
    }

    @Override
    public void dispose() {
        super.dispose();

        if(smapBg!=null){
            smapBg.dispose();
            smapBg=null;
        }

    }

    public SMapHistoryActor getSmapBg() {
        return smapBg;
    }

    public void setSmapBg(SMapHistoryActor smapBg) {
        this.smapBg = smapBg;
    }


    public float getX() {
        return x;
    }
    public void setX(float x) {
        if(ifLoop){////判断当前坐标是否需要循环显示右边
            if(x<=xMin&&x >= (-xMax * zoom + getMainGame().getWorldWidth())){
                drawLoop=false;
                //Gdx.app.log("x","1");
            }else if(x>xMin){//从起点向左
                drawLoop=true;
                x=(-xMax  -getMainGame().getWorldWidth())+x;
                // Gdx.app.log("x","2");
            }else if(x < (-xMax  + getMainGame().getWorldWidth())&&x>(-xMax )){//划入右边,接近循环
                drawLoop=true;
                // Gdx.app.log("x","3");
            }else if(x<=(-xMax -getMainGame().getWorldWidth())) {//划出并还原
                drawLoop=false;
                x = x + xMax +getMainGame().getWorldWidth();
                //  Gdx.app.log("x","4");
            }/**/
        }else {
            if (x > xMin) {
                x = xMin;
            } else if (x < -(xMax)) {
                x = -(xMax);
            }
        }
        this.x = x;
        smapBg.init(getX(),getY(),getZoom(),drawLoop);
    }

    public float getZoomMax() {
        return zoomMax;
    }

    public void setZoomMax(float zoomMax) {
        this.zoomMax = zoomMax;
    }

    public float getZoom() {
        return zoom;
    }



    public void setZoom(float zoom,float cx,float cy) {

        if(zoom < zoomMax&&zoom > zoomMin){
            this.xMax = mapW_px*zoom-getMainGame().getWorldWidth();;
            this.yMax = mapH_px*zoom-getMainGame().getWorldHeight();
            this.xMin = 0;
            this.yMin = 0;
        }


        if (zoom > zoomMax) {
            zoom = zoomMax;

        } else if (zoom < zoomMin) {
            zoom = zoomMin;

        } else {
            setX( x + ((x - cx) * (zoom-this.zoom)) / zoom);
            setY( y + ((y - (getMainGame().getWorldHeight()-cy)) * (zoom-this.zoom)) / zoom);
            this.zoom = zoom;
        }
        smapBg.init(getX(),getY(),getZoom(),drawLoop);
    }

    public float getY() {
        return y;
    }
    public void setY(float y) {
        if (y > yMin) {
            y = yMin;
            //Gdx.app.log("y","1");
        } else if (y < -yMax) {
            y = -yMax;
            //Gdx.app.log("y","2");
        }
        this.y = y;
        smapBg.init(getX(),getY(),getZoom(),drawLoop);
        //Gdx.app.log("y","Y"+y+" yMax:"+yMax+" zoom:"+zoom);
    }


    public SMapDAO getsMapDAO() {
        return sMapDAO;
    }

    public void setsMapDAO(SMapDAO sMapDAO) {
        this.sMapDAO = sMapDAO;
    }

    public BTLDAO getsMapBin() {
        return sMapBin;
    }

    public void setsMapBin(BTLDAO sMapBin) {
        this.sMapBin = sMapBin;
    }
}
SMapStage
package com.zhfy.game.screen.actor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.PixmapIO;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.zhfy.game.config.ResConfig;
import com.zhfy.game.framework.GameFramework;
import com.zhfy.game.framework.GameMap;
import com.zhfy.game.framework.GameUtil;
import com.zhfy.game.framework.tool.BTLTooL;
import com.zhfy.game.model.content.BTLDAO;
import com.zhfy.game.model.content.DefDAO;
import com.zhfy.game.model.content.MapBinDAO;
import com.zhfy.game.model.content.SMapDAO;
import com.zhfy.game.model.content.def.DefHistory;
import com.zhfy.game.model.content.def.DefStage;
import com.zhfy.game.model.framework.Coord;
import com.zhfy.game.model.framework.DrawDAO;
import com.zhfy.game.model.framework.DrawGridDAO;
import com.zhfy.game.model.framework.DrawGridListDAO;
import com.zhfy.game.model.framework.DrawListDAO;
import com.zhfy.game.model.framework.SpriteDAO;
import com.zhfy.game.model.framework.SpriteListDAO;
import com.zhfy.game.model.framework.TextureRegionDAO;
import com.zhfy.game.model.framework.TextureRegionListDAO;

public class SMapHistoryActor extends Actor {
    //加载history来生成剧本


    // 本类用来存放背景地图,获取地图范围,移动,缩放背景地图,确定点击位置等,以及环状地图
    //private DefMap defMap;
    private Pixmap pixmap;// 临时画布
    //private MapBinDAO mapBinDAO;

    private SMapDAO sMapDAO;
    private MapBinDAO mapBinDAO;

    private Texture textureMain;// 主图
    private Texture textureCountry;
    private Pixmap pixmapCountry;

    private List<Integer> coastGrid;
    //private List<Integer> regionGrid;
    private List<Color> legionColors;
    private java.util.Map regionColors;

    private Sprite spriteMain;// 主图
    private Sprite spriteCountry;

    private int w;
    private int h;

    private int mapId;

    private float x;
    private float y;
    private float zoom;
    private int mapW_px;
    private int mapH_px;
    private boolean ifLoop;
    private boolean drawLoop;


    private float vx;
    private float vy;

    private Coord coord;
    private Coord gridCoord;
    private AssetManager am;
    Color oldColor;
    private int screenId;
    private boolean ifNeedUnload;//是否需要卸载,在资源加载完后卸载,如果未加载完退出,在退出时顺带清理资源

    private int mapTimeMax;

    public float getVx() {
        return vx;
    }

    public void setVx(float vx) {
        this.vx = vx;
    }

    public float getVy() {
        return vy;
    }

    public void setVy(float vy) {
        this.vy = vy;
    }

    //private DrawListDAO drawBattleList;
    //private DrawDAO drawBattle;
    private int drawX,drawY;
    private int drawI;
    // 颜色层
    //private Texture textureGrid;
    private SpriteDAO spriteGrid;
    private SpriteListDAO spriteGrids;
    private int gw;
    private int gh;
    private TextureRegionListDAO imgLists;
    //private TextureRegionDAO battleTaskTR;

    public SMapHistoryActor(int stageId,  AssetManager am, int screenId, TextureRegionListDAO imgLists,SMapDAO sMapDAO,MapBinDAO mapBinDAO,List<Integer> coastGrid, List<Color> legionColors, Map regionColors) {
        super();
        this.am=am;
        ifNeedUnload=false;
        this.imgLists=imgLists;
        this.sMapDAO=sMapDAO;
        this.mapBinDAO=mapBinDAO;
        this.screenId=screenId;

        this.coastGrid=coastGrid;
        //this.regionGrid=regionGrid;
        this.legionColors=legionColors;
        this.regionColors=regionColors;
        drawLoop=false;







        {
            // 绘制主要图
            textureMain=  new Texture(GameMap.drawSmallMapAndClearPixmap(stageId,am));
            spriteMain= new Sprite(textureMain);
        }
        this.mapW_px = textureMain.getWidth();
        this.mapH_px = textureMain.getHeight();
        this.w = mapBinDAO.getMapWidth();
        this.h = mapBinDAO.getMapHeight();



        /**/{//绘制一个区域图
            // 绘制画布转为装饰
            long startTime = System.currentTimeMillis();
            pixmapCountry = GameMap.createPixmap((int)(w*ResConfig.Map.SMALLMAP_SCALE),(int)(h*ResConfig.Map.SMALLMAP_SCALE));

            GameMap.getPixmapByHistoryForLegionColor(mapBinDAO,pixmapCountry,ResConfig.Map.SMALLMAP_SCALE,coastGrid,legionColors,regionColors);

            //PixmapIO.writePNG(Gdx.files.external("textureColor.png"), pixmapCountry);
            textureCountry=new Texture(pixmapCountry);
            long endTime = System.currentTimeMillis();    //获取结束时间
            Gdx.app.log("色图构建", " 运行时间:"+(endTime - startTime) + "ms");
            spriteCountry= new Sprite(textureCountry);
            spriteCountry.setSize(textureMain.getWidth(),textureMain.getHeight());
        }

        //pixmapCountry=GameMap.updateColorByRegion(mapBinDAO,pixmapCountry, ResConfig.Map.SMALLMAP_SCALE,sMapDAO.getBattleRegions(),coastGrid,legionColors,sMapDAO.getRegionColors());
        //textureCountry.draw(pixmapCountry,0,0);


        /*{
            // 绘制画布转为装饰
            pixmap = GameMap.createPixmap((int)(w*ResConfig.Map.SMALLMAP_SCALE),(int)(h*ResConfig.Map.SMALLMAP_SCALE));
            pixmap=GameMap.coverImgByPtimgId(pixmap, 2);
            gameFramework.getPixmapDecorateByDao(pixmap, mapBinDAO,am,ResConfig.Map.SMALLMAP_SCALE);
            PixmapIO.writePNG(Gdx.files.external("textureDecorate.png"), pixmap);
            pixmap.dispose();
        }*/


        setSize(spriteMain.getWidth(), spriteMain.getHeight());
        /*
        addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                // 点击图片,图片隐藏![这里写图片描述](https://img-blog.csdn.net/20160425220710777)
                // super.clicked(event, x, y);
                //                // Gdx.app.log("点击的精灵位置1", "x:" + (getX()/getZoom()+x)+" y:"
                //                // +(getY()/getZoom()+ y));
                //
                //                // 由于要在actor等中使用坐标绘图,所以采用libgdx的actor坐标系
                //                // 左下为0,0,向右上方向负数扩展
                //
                //                // Gdx.app.log("点击背景位置1", "bgx:" + getX()+" bgy:" + getY()+"
                //                // zoom:" + getZoom()+" x:" + x+" y:" + y+" rgw:" +
                //                // getRegion().getRegionWidth()+" rgh:" +
                //                // getRegion().getRegionHeight());
                //                // Gdx.app.log("点击背景位置2", "actX:" + (getX()-x)/getZoom()+"
                //                // actY:"+ (getY()-y)/getZoom());

                //coord = GameMap.getHotCell(getImgXCoordByActX((getX() - x) / getZoom()), getImgYCoordByActY((getY() - y) / getZoom()),zoom);

                //Gdx.app.log("点击背景位置3", "imgX:" + getImgXCoordByActX((getX() - x) / getZoom()) + " imgY:" + getImgYCoordByActY((getY() - y) / getZoom()));
                //Gdx.app.log("点击背景位置4", "imgX:" + coord.getX() + " imgY:" + coord.getY());
                *//*pixmapCountry.drawLine(200, (int)x, 50, (int)y);
                textureCountry.draw(pixmapCountry, 0, 0);*//*
               // MapBinDAO mapBinDAO, Pixmap pixmap,float scale,List<Integer> regionIds,List<Integer> coastGrid,List<Color> legionColors,Map regionColors


                {//随机绘图
                    //pixmapCountry=GameMap.updateColorByRegion(mapBinDAO,pixmapCountry, Map.SMALLMAP_SCALE,ComUtil.getNByListRand(regionGrid,3),coastGrid,legionColors,sMapDAO.getRegionColors());
                    //                                    textureCountry.draw(pixmapCountry,0,0);
                }
            }
        });*/
        //battleTaskTR=imgLists.getTextureByName("task_battle");
        //drawBattleList=new DrawListDAO();
        //createBattle();
    }

    @Override
    public void act(float delta) {
        super.act(delta);
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        super.draw(batch, parentAlpha);
        if (spriteMain == null || !isVisible()) {
            return;
        }

        {
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
            //oldColor=batch.getColor();
            batch.draw(spriteMain, getX(), getY(), getOriginX(), getOriginY(), getWidth(), getHeight(),
                    getZoom(), getZoom(), getRotation());
            batch.draw(spriteCountry, getX(), getY(), getOriginX(), getOriginY(), getWidth(), getHeight(),
                    getZoom(), getZoom(), getRotation());

            //batch.setColor(Color.RED);
            if(drawLoop){
                batch.draw(spriteMain, getX()+mapW_px*this.zoom, getY(), getOriginX(), getOriginY(), getWidth(), getHeight(),
                        getZoom(), getZoom(), getRotation());
                batch.draw(spriteCountry, getX()+mapW_px*this.zoom, getY(), getOriginX(), getOriginY(), getWidth(), getHeight(),
                        getZoom(), getZoom(), getRotation());
            }
            //batch.setColor(oldColor);

            /*if(drawBattleList.size()>0){
                for(drawI=0;drawI<drawBattleList.size();drawI++) {
                    batch.draw(battleTaskTR.getTextureRegion(), getX() - drawBattleList.get(drawI).getLx_px() * this.zoom, getY()- drawBattleList.get(drawI).getLy_px() * this.zoom, getOriginX(), getOriginY(), battleTaskTR.getTextureRegion().getRegionWidth(), battleTaskTR.getTextureRegion().getRegionHeight(),
                            getZoom(), getZoom(), getRotation());
                }
            }*/


        }

    }


    @Override
    public float getX() {
        return x;
    }

    @Override
    public void setX(float x) {
        this.x = x;
    }

    @Override
    public float getY() {
        return y;
    }

    @Override
    public void setY(float y) {
        this.y = y;
    }

    public float getZoom() {
        return zoom;
    }

    public void setZoom(float zoom) {
        this.zoom = zoom;
    }

    public int getW() {
        return w;
    }

    public void setW(int w) {
        this.w = w;
    }

    public int getH() {
        return h;
    }

    public void setH(int h) {
        this.h = h;
    }



    // 将↓→坐标(左上角为0,0,越向右下越大)转为←↓act坐标(左下角为0,0,越向右上越小)
    public float getActXCoordByImgX(float print_x) {
        return (-print_x);
    }

    public float getActYCoordByImgY(float print_y) {
        return (print_y - spriteMain.getHeight());
    }

    // 将←↓act坐标(左下角为0,0,越向右上越小)转化为↓→坐标(左上角为0,0,越向右下越大)
    // 将↓→坐标(左上角为0,0,越向右下越大)转为←↓act坐标(左下角为0,0,越向右上越小)
    public float getImgXCoordByActX(float print_x) {
        if(print_x!=0f) {
            return (-print_x);
        }else {
            return 0f;
        }
    }

    public float getImgYCoordByActY(float print_y) {
        return (spriteMain.getHeight() + print_y);
    }


    // 清理5张图层
    public void dispose() {
        if(pixmapCountry!=null){
            pixmapCountry.dispose();
            pixmapCountry=null;
        }
        if (textureMain != null) {
            textureMain.dispose();
            textureMain=null;
        }
        if (textureCountry!=null){
            textureCountry.dispose();
            textureCountry=null;
        }
        if (ifNeedUnload) {
            GameUtil.unloadSingleResByScreenId(am, screenId);
        }


    }

    public Pixmap getPixmap() {
        return pixmap;
    }

    public void setPixmap(Pixmap pixmap) {
        this.pixmap = pixmap;
    }


    public Texture gettextureMain() {
        return textureMain;
    }

    public void settextureMain(Texture textureMain) {
        this.textureMain = textureMain;
    }


    public Sprite getspriteMain() {
        return spriteMain;
    }

    public void setspriteMain(Sprite spriteMain) {
        this.spriteMain = spriteMain;
    }


    public SpriteDAO getSpriteGrid() {
        return spriteGrid;
    }

    public void setSpriteGrid(SpriteDAO spriteGrid) {
        this.spriteGrid = spriteGrid;
    }



    public int getGw() {
        return gw;
    }

    public void setGw(int gw) {
        this.gw = gw;
    }

    public int getGh() {
        return gh;
    }

    public void setGh(int gh) {
        this.gh = gh;
    }

    public SpriteListDAO getSpriteGrids() {
        return spriteGrids;
    }

    public void setSpriteGrids(SpriteListDAO spriteGrids) {
        this.spriteGrids = spriteGrids;
    }



    /*public void createBattle(){
        drawBattleList.clear();
        for(int i: sMapDAO.getBattleRegions()){
            drawBattle=new DrawDAO();
            drawBattle.setTextureName("task_battle");
            GameMap.getCenterPotionById(mapBinDAO,drawX,drawY,ResConfig.Map.SMALLMAP_SCALE,mapBinDAO.getIdByRegionId(i));

            drawBattle.setLx_px(drawX);
            drawBattle.setLx_px(drawY);
            drawBattleList.add(drawBattle);
        }
    }*/

    public void setIfLoop(boolean ifLoop) {
        this.ifLoop=ifLoop;
    }

    public boolean isDrawLoop() {
        return drawLoop;
    }

    public void init(float x, float y, float zoom,boolean drawLoop){
        this.x=x;
        this.y=y;
        this.zoom=zoom;
        this.drawLoop=drawLoop;
    }

}
SMapHistoryActor
package com.zhfy.game.model.content;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.XmlReader;
import com.zhfy.game.config.ResConfig;
import com.zhfy.game.framework.ComUtil;
import com.zhfy.game.framework.tool.BTLTooL;
import com.zhfy.game.model.content.btl.BtlModule0;
import com.zhfy.game.model.content.btl.BtlModule1;
import com.zhfy.game.model.content.btl.BtlModule2;
import com.zhfy.game.model.content.btl.BtlModule3;
import com.zhfy.game.model.content.btl.BtlModule4;
import com.zhfy.game.model.content.btl.BtlModule5;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SMapDAO {
    //本类用来编辑战役来使用
    private BTLDAO smapBin;
    private TimeDAO time;
    private Map regionSortMap;//存放id所在的顺序位置,直接从第一个取 region:i
    private int regionCount;//地区总数
    private int yearCount;//记录年条数
    private int mapId;
    private Map regionColors;//修改地区时需要修改此项
    private int gameMode;//0默认历史 1自由
    private List<Integer> battleRegions;
    private int eventIdNow;

    //本类用来操作预览图,存储时间,前进,或倒退,生成逐月显示步骤,修改预览图,
    //根据history生成相关信息
    public SMapDAO(BTLDAO historyBin, MapBinDAO mapBin, int mapId, Map map, int year, String stageName) {
        time = new TimeDAO(historyBin.getBm0().getBm0_3(), historyBin.getBm0().getBm0_3(), historyBin.getBm0().getBm0_5());
        time.setYear(year);
        this.regionCount = historyBin.getBm0().getBm0_4();
        this.yearCount = historyBin.getBm0().getBm0_5();
        this.regionSortMap = getRegionSortMapByHistoryBIn(historyBin);
        this.mapId = mapId;
        this.smapBin = createSMapBin();
        initSmap(historyBin, map, year,mapBin);//初始化玩家数据
        initMonth(historyBin);//初始化事件,国家变更等数据
        saveSmapBin(stageName);
        this.regionColors = getRegionColor();
        this.gameMode = smapBin.getBm0().getBm0_14();
        initBattleRegions();
        executeThisRround();
    }

    //根据smap生成相关信息
    public SMapDAO(BTLDAO smapBin,  Map map) {
        time = new TimeDAO(smapBin.getBm0().getBm0_4(), smapBin.getBm0().getBm0_5(), smapBin.getBm0().getBm0_3(), smapBin.getBm0().getBm0_6());
        this.regionCount = smapBin.getBm0().getBm0_7();
        this.yearCount = smapBin.getBm0().getBm0_6();
        this.regionSortMap = getRegionSortMapBySMapBIn(smapBin);
        this.mapId = smapBin.getBm0().getBm0_2();
        this.smapBin = smapBin;
        this.regionColors = getRegionColor();
        this.gameMode = smapBin.getBm0().getBm0_14();
        initBattleRegions();
        executeThisRround();
    }


    //根据年信息生成smap内容
    private BTLDAO createSMapBin() {
        BTLDAO smapBin = new BTLDAO();
        BtlModule0 bm0 = new BtlModule0();
        List<BtlModule1> bm1 = new ArrayList<BtlModule1>();
        List<BtlModule2> bm2 = new ArrayList<BtlModule2>();
        List<BtlModule3> bm3 = new ArrayList<BtlModule3>();
        List<BtlModule4> bm4 = new ArrayList<BtlModule4>();
        {
            bm0.setBm0_1(ResConfig.version);
            bm0.setBm0_2(mapId);
            bm0.setBm0_3(time.getYear());
            bm0.setBm0_4(time.getYear());
            bm0.setBm0_5(time.getMonth());
            bm0.setBm0_6(yearCount);
        }
        smapBin.setBm0(bm0);
        smapBin.setBm1(bm1);
        smapBin.setBm2(bm2);
        smapBin.setBm3(bm3);
        smapBin.setBm4(bm4);
        return smapBin;
    }

    //初始化预览图bin,根据配置
    public void initSmap(BTLDAO historyBin, Map map, int year,MapBinDAO mapBin) {
        //1.根据配置初始化数据
        smapBin.getBm0().setBm0_12(Integer.parseInt(map.get("playerCountry").toString()));//
        smapBin.getBm0().setBm0_13(Integer.parseInt(map.get("playerScore").toString()));//
        smapBin.getBm0().setBm0_14(Integer.parseInt(map.get("gameMode").toString()));//
        smapBin.getBm0().setBm0_15(Integer.parseInt(map.get("eventType").toString()));//
        smapBin.getBm0().setBm0_16(Integer.parseInt(map.get("age").toString()));//

        Map regionMap=mapBin.getRegionMap();

        //2.根据配置历史
        int cityLv,cityType,cityHp;
        for (int i = 0; i < regionCount; i++) {
            BtlModule1 bm1 = new BtlModule1();
            int id = getHistoryIndex(year, historyBin.getBm1().get(i).getBm1_3());
            bm1.setBm1_1(0);
            bm1.setBm1_2(year);
            bm1.setBm1_3(historyBin.getBm1().get(i).getBm1_3());
            bm1.setBm1_4(historyBin.getBm1().get(i).getBm1_4());
            bm1.setBm1_5(historyBin.getBm1().get(i).getBm1_5());
            bm1.setBm1_6(0);
            bm1.setBm1_7(historyBin.getBm1().get(i).getBm1_7());


            //Gdx.app.log("initSmap",bm1.getBm1_3()+"");
            if(regionMap.containsKey(bm1.getBm1_3())&&mapBin.getMapbin().get(Integer.parseInt(regionMap.get(bm1.getBm1_3()).toString())).getBuildLv()!=0){
                cityLv=mapBin.getMapbin().get(Integer.parseInt(regionMap.get(bm1.getBm1_3()).toString())).getBuildLv();
            }else{
                cityLv=ComUtil.getRandom(0,2);
            }
            if(cityLv>4){
                cityType=2;
            }else if(cityLv>2){
                if(ComUtil.ifGet(70)){
                    cityType=1;
                }else if(ComUtil.ifGet(10)){
                    cityType=2;
                }else{
                    cityType=3;
                }
            }else{
                cityType=0;
            }
            if(cityType==3){
                cityHp=2*ResConfig.Game.cityBaseHp*cityLv;
            }else {
                cityHp=ResConfig.Game.cityBaseHp*cityLv;
            }
            bm1.setBm1_8(cityLv);
            bm1.setBm1_9(cityType);
            bm1.setBm1_10(cityHp);
            bm1.setBm1_11(cityHp);
            smapBin.getBm1().add(bm1);
        }
    }

    //在初始化执行, 添加月数据,事件数据,国家变更等命令
    public void initMonth(BTLDAO historyBin) {
        XmlReader reader = ResConfig.reader;

        {//如果是初始年,则添加全部事件和国家变更
            {//事件数据
                XmlReader.Element root = reader.parse(Gdx.files.internal("config/def_event.xml"));
                Array<XmlReader.Element> events = root.getChildrenByName("event");
                for (XmlReader.Element event : events) {
                    if (event.getInt("year") >= time.getYear()) {
                        BtlModule3 bm3 = new BtlModule3();
                        bm3.setBm3_1(event.getInt("year"));
                        bm3.setBm3_2(event.getInt("month") == 0 ? ComUtil.getRandom(1, 12) : event.getInt("month"));
                        bm3.setBm3_3(event.getInt("id"));
                        bm3.setBm3_4(0);
                        smapBin.getBm3().add(bm3);

                    }
                }
            }
            Map countryChangeMap = new HashMap();//{oldCountryId,NewCountryId}
            {//国家变更
                XmlReader.Element root = reader.parse(Gdx.files.internal("config/def_country.xml"));
                Array<XmlReader.Element> countrys = root.getChildrenByName("country");

                for (XmlReader.Element country : countrys) {
                    if (country.getInt("nextId") != -1 && country.getInt("nextTime") != -1 && country.getInt("nextTime") >= time.getYear()) {
                        BtlModule4 bm4 = new BtlModule4();
                        bm4.setBm4_1(country.getInt("nextTime"));
                        bm4.setBm4_2(1);
                        bm4.setBm4_3(country.getInt("id"));
                        bm4.setBm4_4(country.getInt("nextId"));
                        smapBin.getBm4().add(bm4);
                        countryChangeMap.put(bm4.getBm4_3(), bm4.getBm4_4());
                        //countryChangeMap2.put(bm4.getBm4_4(),bm4.getBm4_3());
                    }
                }
            }
            int bm2Size = historyBin.getBm0().getBm0_6() - historyBin.getBm0().getBm0_4();
            int changeCountry;
            {//月数据,因为要考虑国家变更,所以放到后面
                for (int i = time.getPage() * regionCount; i < bm2Size; i++) {
                    //与下年数据比对,如果归属(bm1_4)变化,获得方式非0,战斗id非0
                    if (historyBin.getBm1().get(i).getBm1_6() == 2) {//协议优先
                        BtlModule2 bm2 = new BtlModule2();
                        //必然第一月
                        bm2.setBm2_1(historyBin.getBm1().get(i).getBm1_2());
                        bm2.setBm2_2(1);
                        bm2.setBm2_3(historyBin.getBm1().get(i).getBm1_3());
                        bm2.setBm2_4(historyBin.getBm1().get(i).getBm1_4());
                        bm2.setBm2_5(historyBin.getBm1().get(i + regionCount).getBm1_4());
                        bm2.setBm2_6(2);
                        bm2.setBm2_7(historyBin.getBm1().get(i).getBm1_7());
                        bm2.setBm2_8(0);
                        smapBin.getBm2().add(bm2);

                    } else if (historyBin.getBm1().get(i).getBm1_7() != 0) {
                        //月份不确定,等待事件解锁
                        BtlModule2 bm2 = new BtlModule2();
                        bm2.setBm2_1(historyBin.getBm1().get(i).getBm1_2());
                        bm2.setBm2_2(0);
                        bm2.setBm2_3(historyBin.getBm1().get(i).getBm1_3());
                        bm2.setBm2_4(historyBin.getBm1().get(i).getBm1_4());
                        bm2.setBm2_5(historyBin.getBm1().get(i + regionCount).getBm1_4());
                        bm2.setBm2_6(2);
                        bm2.setBm2_7(historyBin.getBm1().get(i).getBm1_7());
                        bm2.setBm2_8(0);
                        smapBin.getBm2().add(bm2);

                    } else if (countryChangeMap.containsKey(historyBin.getBm1().get(i).getBm1_4())&&historyBin.getBm1().get(i).getBm1_4() == Integer.parseInt(countryChangeMap.get(historyBin.getBm1().get(i).getBm1_4()).toString())) {
                        //如果是国家变化,则不变

                    } else if ((historyBin.getBm1().get(i).getBm1_4() != historyBin.getBm1().get(i + regionCount).getBm1_4()) || (historyBin.getBm1().get(i).getBm1_6() != 0 && historyBin.getBm1().get(i).getBm1_6() != 2)) {
                        BtlModule2 bm2 = new BtlModule2();
                        bm2.setBm2_1(historyBin.getBm1().get(i).getBm1_2());
                        bm2.setBm2_2(ComUtil.getRandom(1, 12));
                        bm2.setBm2_3(historyBin.getBm1().get(i).getBm1_3());
                        bm2.setBm2_4(historyBin.getBm1().get(i).getBm1_4());
                        bm2.setBm2_5(historyBin.getBm1().get(i + regionCount).getBm1_4());
                        //bm2.setBm2_5(Integer.parseInt(countryChangeMap2.get(historyBin.getBm1().get(i+regionCount).getBm1_4()).toString()));
                        bm2.setBm2_6(historyBin.getBm1().get(i).getBm1_6());
                        bm2.setBm2_7(historyBin.getBm1().get(i).getBm1_7());
                        bm2.setBm2_8(0);
                        smapBin.getBm2().add(bm2);
                    }
                }
            }
        }
        //进行排序
        Collections.sort(smapBin.getBm2(), new Comparator<BtlModule2>() {
            @Override
            public int compare(BtlModule2 u1, BtlModule2 u2) {

                if (u1.getBm2_1() > u2.getBm2_1()) {
                    return 1;
                }
                if (u1.getBm2_1() == u2.getBm2_1()) {
                    if (u1.getBm2_2() > u2.getBm2_2()) {
                        return 1;
                    } else if (u1.getBm2_2() < u2.getBm2_2()) {
                        return -1;
                    }
                    return 0;
                }
                return -1;
            }
        });
        Collections.sort(smapBin.getBm3(), new Comparator<BtlModule3>() {
            @Override
            public int compare(BtlModule3 u1, BtlModule3 u2) {
                if (u1.getBm3_1() > u2.getBm3_1()) {
                    return 1;
                }
                if (u1.getBm3_1() == u2.getBm3_1()) {
                    if (u1.getBm3_2() > u2.getBm3_2()) {
                        return 1;
                    } else if (u1.getBm3_2() < u2.getBm3_2()) {
                        return -1;
                    }
                    return 0;
                }
                return -1;
            }
        });
        Collections.sort(smapBin.getBm4(), new Comparator<BtlModule4>() {
            @Override
            public int compare(BtlModule4 u1, BtlModule4 u2) {
                if (u1.getBm4_1() > u2.getBm4_1()) {
                    return 1;
                }
                if (u1.getBm4_1() == u2.getBm4_1()) {
                    if (u1.getBm4_2() > u2.getBm4_2()) {
                        return 1;
                    } else if (u1.getBm4_2() < u2.getBm4_2()) {
                        return -1;
                    }
                    return 0;
                }
                return -1;
            }
        });

    }


    //执行本回合  生成相关战役
    public void executeThisRround() {
        List<Integer> events = new ArrayList<Integer>();
        int i,iMax;
        if (time.getMonth() == 1) {
            for (BtlModule4 bm4 : smapBin.getBm4()) {
                if (bm4.getBm4_1() == time.getYear() - 1) {//0.国家修订
                    //在预测本月事件的时候先检测下年是否有国家改变,把bm2 的bm2_5的战斗后的归属国家进行修正
                    for (BtlModule2 bm2 : smapBin.getBm2()) {
                        if (bm2.getBm2_5() == bm4.getBm4_4()) {
                            bm2.setBm2_5(bm4.getBm4_3());
                        } else if (bm2.getBm2_1() > time.getYear() - 1) {
                            break;
                        }
                    }
                } else if (bm4.getBm4_1() == time.getYear()) { //1.国家变更
                    for (BtlModule1 bm1 : smapBin.getBm1()) {
                        if (bm1.getBm1_4() == bm4.getBm4_3()) {
                            bm1.setBm1_4(bm4.getBm4_3());
                        }
                    }

                    //TODO 修改绘制颜色
                }
            }
        }
        //2.解锁月数据,播放事件
        for (BtlModule3 bm3 : smapBin.getBm3()) {
            if (bm3.getBm3_1() == time.getYear() && bm3.getBm3_2() == time.getMonth()) {
                events.add(bm3.getBm3_3());
            } else if (bm3.getBm3_1() == time.getYear() && bm3.getBm3_2() >= time.getMonth()) {
                if(events.size()>0){
                    eventIdNow=events.get(events.size()-1);
                }
                break;
            }
        }
        //3.遍历相关月事件
        iMax=smapBin.getBm2().size();

        for (i=0;i<iMax;i++) {
            if(events.contains(smapBin.getBm2().get(i).getBm2_7())||eventIdNow>smapBin.getBm2().get(i).getBm2_7()) {//事件解锁 事件触发,或有事件的id>
                smapBin.getBm2().get(i).setBm2_2(time.getMonth());
                smapBin.getBm2().get(i).setBm2_8(0);
            }
            if (smapBin.getBm2().get(i).getBm2_1() == time.getYear() && smapBin.getBm2().get(i).getBm2_2() == time.getMonth()&&smapBin.getBm2().get(i).getBm2_8()==0) {
               //协议 直接转让土地所有权
                if(smapBin.getBm2().get(i).getBm2_6()==2&&smapBin.getBm2().get(i).getBm2_4()==smapBin.getBm1().get(i).getBm1_4()){
                    smapBin.getBm1().get(i).setBm1_4(smapBin.getBm2().get(i).getBm2_5());
                    smapBin.getBm1().get(i).setBm1_5(0);
                    smapBin.getBm1().get(i).setBm1_6(0);
               }else{
                   //添加战斗记录
                   battleRegions.add(smapBin.getBm2().get(i).getBm2_3());
                   //同时改变地块状态 TODO
                   smapBin.getBm1().get(i).setBm1_5(smapBin.getBm2().get(i).getBm2_5());
                   smapBin.getBm1().get(i).setBm1_6(0);
               }
            }


        }
    }

    //进入下一回合() 自动生成其他数据
    public void executeNextRround() {
        //随机执行结果

        //删除过期数据

        //变更时间
        time.nextTime();
        //执行国家变更
        //执行月数据
        //检测月数据,解锁战役

        //执行完其他数据,执行本回合数据
        executeThisRround();
    }


    public int getHistoryIndex(int historyPage, int RegionId) {
        int rs = 0;
        try {
            rs = Integer.parseInt(regionSortMap.get(RegionId).toString()) + historyPage * regionCount;
        } catch (Exception e) {
            Gdx.app.error("获取historyId出错", "historyPage:" + historyPage + " RegionId:" + RegionId);
        }

        return rs;
    }

    //保存
    public void saveSmapBin(String stageName) {
        try {
            BTLTooL.saveBtl(smapBin, ResConfig.Rules.RULE_FB1_SMAP, "sav/" + stageName + ".bin"); //BTLDAO btl,String rulePath,  String filePath
        } catch (IOException e) {
            e.printStackTrace();
            Gdx.app.error("history", "保存失败:" + stageName);
        }
    }


    private Map getRegionSortMapByHistoryBIn(BTLDAO historyBin) {
        Map rs = new HashMap();
        for (int i = 0; i < regionCount; i++) {
            rs.put(historyBin.getBm1().get(i).getBm1_3(), i);
            //Gdx.app.log("RegionSortMap",bin.getBm1().get(i).getBm1_3()+":"+i);
        }
        return rs;
    }

    private Map getRegionSortMapBySMapBIn(BTLDAO smapBin) {
        Map rs = new HashMap();
        for (int i = 0; i < regionCount; i++) {
            rs.put(smapBin.getBm1().get(i).getBm1_3(), i);
            //Gdx.app.log("RegionSortMap",bin.getBm1().get(i).getBm1_3()+":"+i);
        }
        return rs;
    }

    public Map getRegionColor() {
        Map rs = new HashMap();
        for (BtlModule1 bm1 : smapBin.getBm1()) {
            rs.put(bm1.getBm1_3(), bm1.getBm1_4());
        }
        return rs;
    }

    public TimeDAO getTime() {
        return time;
    }

    public void setTime(TimeDAO time) {
        this.time = time;
    }


    public BTLDAO getSmapBin() {
        return smapBin;
    }

    public void setSmapBin(BTLDAO smapBin) {
        this.smapBin = smapBin;
    }

    public Map getRegionSortMap() {
        return regionSortMap;
    }

    public void setRegionSortMap(Map regionSortMap) {
        this.regionSortMap = regionSortMap;
    }

    public Map getRegionColors() {
        return regionColors;
    }

    public void setRegionColors(Map regionColors) {
        this.regionColors = regionColors;
    }
    //初始化战斗数据
    public void initBattleRegions(){
        if(battleRegions==null){
            battleRegions=new ArrayList<Integer>();
        }
        for(BtlModule1 bm1:smapBin.getBm1()){
            if(bm1.getBm1_6()==1){
                battleRegions.add(bm1.getBm1_3());
            }
        }
    }

    public List<Integer> getBattleRegions() {
        return battleRegions;
    }

    public void setBattleRegions(List<Integer> battleRegions) {
        this.battleRegions = battleRegions;
    }
}
SMapDAO
package com.zhfy.game.model.content;

import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Pixmap;
import com.zhfy.game.framework.ComUtil;
import com.zhfy.game.framework.GameMap;
import com.zhfy.game.framework.GameUtil;
import com.zhfy.game.model.content.btl.BtlModule1;
import com.zhfy.game.model.content.def.DefMap;
import com.zhfy.game.model.content.def.DefTerrainimg;
import com.zhfy.game.model.framework.Coord;

public class MapBinDAO {
    
    public int mapVersion;// 2-地图版本
    public int mapWidth;// 4-长
    public int mapHeight;// 4-宽
    public List<MapBin> MapBin;//
    public Map regionMap;//{region:i}
    
    //写死了
    public MapBinDAO(BTLDAO btlDao){
        if(btlDao!=null) {
            mapVersion=1;
            mapWidth=btlDao.getBm0().getBm0_13();
            mapHeight=btlDao.getBm0().getBm0_14();
            MapBin=new ArrayList<MapBin>();
            MapBin mapBin;
            int i=0;
            regionMap=new HashMap();
            for(BtlModule1 bm1:btlDao.getBm1()) {
                mapBin=new MapBin();
                mapBin.setBlockType(bm1.getBm1_1());
                mapBin.setBackTile(bm1.getBm1_2());
                mapBin.setBackIdx(bm1.getBm1_3());
                mapBin.setBackRefX(bm1.getBm1_4());
                mapBin.setBackRefY(bm1.getBm1_5());
                mapBin.setWaterPass(bm1.getBm1_6());
                mapBin.setLandPass(bm1.getBm1_7());
                mapBin.setRegionId(bm1.getBm1_8());
                mapBin.setClimateId(bm1.getBm1_9());
                mapBin.setBuildId(bm1.getBm1_10());
                mapBin.setBuildLv(bm1.getBm1_11());
                mapBin.setFacility(bm1.getBm1_12());
                mapBin.setAreaId(bm1.getBm1_13());
                MapBin.add(mapBin);
                if(bm1.getBm1_8() != 0 && bm1.getBm1_8() == i){
                    regionMap.put(bm1.getBm1_8(),i);
                    i=i+1;
                }
            }
        }
    }
    
    public int getMapVersion() {
        return mapVersion;
    }
    
    public void setMapVersion(int mapVersion) {
        this.mapVersion = mapVersion;
    }
    
    public int getMapWidth() {
        return mapWidth;
    }
    
    public void setMapWidth(int mapWidth) {
        this.mapWidth = mapWidth;
    }
    
    public int getMapHeight() {
        return mapHeight;
    }
    
    public void setMapHeight(int mapHeight) {
        this.mapHeight = mapHeight;
    }
    
    public List<MapBin> getMapbin() {
        return MapBin;
    }
    
    public void setMapbin(List<MapBin> MapBin) {
        this.MapBin = MapBin;
    }
    
    public void initRegionId() {
        int i, iMax;
        iMax = MapBin.size();
        for (i = 0; i < iMax; i++) {
            MapBin.get(i).setRegionId(i);
        }
    }
    
    //随机装饰(除特殊装饰,以及ref有值的外)  
    public void randomAllDecoration() {
        Random rand = new Random();
        //储存地块最高范围
        Map map = GameMap.getDecorateRandMaxMap(); //Map(id_type+"_min",idx_min) Map(id_type+"_max",idx_max)
        //循环遍历所有地块
        int i;
        int iLength = MapBin.size();
        int vMin, vMax;
        for (i = 0; i < iLength; i++) {
            /*
             * if(MapBin.get(i).getBackTile()==5) { Gdx.app.log("MapBin.i:",
             * "imin:"+(MapBin.get(i).getBackTile()+"_"+MapBin.get(i).
             * getBlockType()+"_min")+" imax:"+(MapBin.get(i).getBackTile()+"_"+
             * MapBin.get(i).getBlockType()+"_max")); }
             */
            if (map.containsKey(MapBin.get(i).getBackTile() + "_" + MapBin.get(i).getBlockType() + "_min") && map.containsKey(MapBin.get(i).getBackTile() + "_" + MapBin.get(i).getBlockType() + "_max") && MapBin.get(i).getBackRefX() == 0 && MapBin.get(i).getBackRefY() == 0) {
                
                vMin = (Integer) map.get(MapBin.get(i).getBackTile() + "_" + MapBin.get(i).getBlockType() + "_min");
                vMax = (Integer) map.get(MapBin.get(i).getBackTile() + "_" + MapBin.get(i).getBlockType() + "_max");
                //Gdx.app.log("", " backTile:"+MapBin.get(i).getBackTile()+" type:"+MapBin.get(i).getBackTile()+" max:"+map.get(MapBin.get(i).getBackTile()+"_"+MapBin.get(i).getBlockType()+"_max")+" min:"+map.get(MapBin.get(i).getBackTile()+"_"+MapBin.get(i).getBlockType()+"_min")+" backIdx:"+backIdx);
                MapBin.get(i).setBackIdx(rand.nextInt(vMax - vMin + 1) + vMin);
            }
            if (map.containsKey(MapBin.get(i).getForeTile() + "_" + MapBin.get(i).getBlockType() + "_min") && map.containsKey(MapBin.get(i).getForeTile() + "_" + MapBin.get(i).getBlockType() + "_max") && MapBin.get(i).getForeRefX() == 0 && MapBin.get(i).getForeRefY() == 0) {
                vMin = (Integer) map.get(MapBin.get(i).getForeTile() + "_" + MapBin.get(i).getBlockType() + "_min");
                vMax = (Integer) map.get(MapBin.get(i).getForeTile() + "_" + MapBin.get(i).getBlockType() + "_max");
                //Gdx.app.log("", " backTile:"+MapBin.get(i).getBackTile()+" type:"+MapBin.get(i).getBackTile()+" max:"+map.get(MapBin.get(i).getBackTile()+"_"+MapBin.get(i).getBlockType()+"_max")+" min:"+map.get(MapBin.get(i).getBackTile()+"_"+MapBin.get(i).getBlockType()+"_min")+" backIdx:"+backIdx);
                MapBin.get(i).setForeIdx(rand.nextInt(vMax - vMin + 1) + vMin);
            }
        }
    }
    
    //随机增加2层装饰
    public void randomForeDecoration() {
        int foreId, vMin, vMax;
        Random rand = new Random();
        //储存地块最高范围
        Map map = GameMap.getDecorateRandMaxMap();
        //循环遍历所有地块
        int i;
        int iLength = MapBin.size();
        Object o1;
        
        for (i = 0; i < iLength; i++) {
            //配对规则
            //4丘陵 4 5 6
            //5山地 4 5 6
            //6森林 4 5 6
            if (rand.nextInt(100) < 31 && map.containsKey(MapBin.get(i).getBackTile() + "_" + MapBin.get(i).getBlockType() + "_min") && map.containsKey(MapBin.get(i).getBackTile() + "_" + MapBin.get(i).getBlockType() + "_max") && MapBin.get(i).getBackTile() > 3 && MapBin.get(i).getBackTile() < 7) {
                foreId = 4 + rand.nextInt(3);
                MapBin.get(i).setForeTile(foreId);
                o1 = map.get(foreId + "_" + MapBin.get(i).getBlockType() + "_min");
                if (o1 != null && MapBin.get(i).getForeRefX() == 0 && MapBin.get(i).getForeRefY() == 0) {
                    vMin = (Integer) map.get(foreId + "_" + MapBin.get(i).getBlockType() + "_min");
                    vMax = (Integer) map.get(foreId + "_" + MapBin.get(i).getBlockType() + "_max");
                    //Gdx.app.log("", " backTile:"+MapBin.get(i).getBackTile()+" type:"+MapBin.get(i).getBackTile()+" max:"+map.get(MapBin.get(i).getBackTile()+"_"+MapBin.get(i).getBlockType()+"_max")+" min:"+map.get(MapBin.get(i).getBackTile()+"_"+MapBin.get(i).getBlockType()+"_min")+" backIdx:"+backIdx);
                    MapBin.get(i).setForeIdx(rand.nextInt(vMax - vMin + 1) + vMin);
                }
            } else {
                MapBin.get(i).setForeTile(0);
                MapBin.get(i).setForeIdx(0);
            }
        }
    }
    
    //规则 有建筑或有地名的区块=id 否则为0
    public void resetRegionId() {
        int i;
        int iMax = MapBin.size();
        for (i = 0; i < iMax; i++) {
            if (MapBin.get(i).getAreaId() == 0 && MapBin.get(i).getBuildId() == 0) {
                MapBin.get(i).setRegionId(0);
            } else {
                MapBin.get(i).setRegionId(i);
            }
        }
    }
    
    //根据纬度生成随机气候 TODO
    public void randomClimate() {
        
    }
    
    //随机海岸河流 TODO
    public void randomCoastRever() {
        
    }
    
    //完全随机地图 TODO
    public void randomAll(int i) {
        
    }
    
    //重新切割省区 TODO
    public void cutRegion() {
        Random rand = new Random();
        int tempId, exct = 0, i = 0, iMax = 0, j, jMax, rsct, riSize;
        List<Integer> regions = null;
        List<Integer> temps = null;
        Map regionCountMap = new HashMap();
        Boolean ifSea =false;
        
        for (j = 0; j < 5; j++) {
            exct=0;
            regions = getRegions(j);
            Gdx.app.log("阶段1", "核心地块数" + regions.size()+"获得地块类:"+j); //循环 挨个对核心地块进行循环 
            while (exct < 20-j && regions.size() != 0) {
                for (i = regions.size() - 1; i >= 0; i--) {
                    tempId = getRegionId(regions.get(i));
                    if(!ifSea){//判断海洋,移除
                        if(tempId>=0&&MapBin.get(tempId).getBlockType()==1){
                            tempId=-1;
                        }
                    }
                    if (tempId >= 0) {
                        riSize = getIdByRegion(tempId).size();
                        if (riSize > (13 + Math.random() * 5)) {
                            regions.remove(i);
                        } else {
                            MapBin.get(tempId).setRegionId(regions.get(i));
                        }
                    } else {
                        regions.remove(i);
                    }
                }
                Gdx.app.log("阶段2", "核心地块数" + regions.size() + " 循环次数:" + exct);
                exct++;
            }
        }
        //循环2 自定义随机地块 // 随机一定条件取核心值
        //循环挨个核心地块循环 //如果核心地块周围有非核心地块的空地且面积不超过一定值,则染色(条件可放宽),否则移除,直到移除全部地块
        {
            regions = getRegionIdsByChance((int) 5,ifSea);
            rsct = getRegionForIdIs0();
            Gdx.app.log("阶段3", "剩余绘制数" + rsct);
            for (Integer rg : regions) {
                if(!ifSea&&MapBin.get(rg).getBlockType()==1){

                }else{
                    MapBin.get(rg).setRegionId(rg);
                }

            }
        }



        int rgc = 0;//可用地块
        while (rsct > 0) {//空白地块不能等于0
            jMax = regions.size();
            if(jMax==0) {
                break;
            }
            for (j = jMax - 1; j >= 0; j--) {//regions.get(j)为当前地块值
                //定义当前地块为特定地块 //循环填充周围地块
                iMax=(int)(10 + Math.random() * 10);
                for (i = 0; i < iMax; i++) {
                    rgc = getRegionId(regions.get(j));
                    if (rgc == -1) {
                        regions.remove(regions.get(j));
                        break;
                    } else {
                        MapBin.get(rgc).setRegionId(regions.get(j));
                    }
                }
            }
            rsct = getRegionForIdIs0();
            Gdx.app.log("阶段3", "剩余绘制数" + rsct + " 核心地块数:" + regions.size());
        }

        /* 自检,合并不规范地块 */
        {
            //0查看所有region为0的地块并合并到周围地块
            {
                regions = getIdsForBlankRegion();
                for (Integer region : regions) {//rsCoords.size()  rand.nextInt(
                    temps = getAroundIdById(region, 9);
                    if (temps.size() != 0) {
                        MapBin.get(region).setRegionId(temps.get(rand.nextInt(temps.size())));
                    } else {
                        //此时剩下的应该是碎小的岛屿或水洞
                        temps = getAroundIdById(region, 0);
                        if (temps.size() != 0) {
                            MapBin.get(region).setRegionId(temps.get(rand.nextInt(temps.size())));
                        } else {
                            Gdx.app.log("警告:有空白地块无法合并到周围地块:", region + "");
                        }

                    }
                }
            }
            //对所有region数量进行检查
            //Map.Entry entry;
            int rgct, argId;
            List<Integer> argIds, regionCounts;
            {
                checkRegion();

                regionCountMap = getRegionCountMap();
                regionCounts = ComUtil.getKeyByMap(regionCountMap);
                for (Integer rgId : regionCounts) {
                    if (regionCountMap.containsKey(rgId) && regionCountMap.get(rgId) != null) {
                        rgct = Integer.parseInt(regionCountMap.get(rgId).toString());
                        if (rgct < 7) {
                            if (MapBin.get(rgId).getBuildId() == 1) {
                                //0:低于5的城市合并周围的最低地块普通或建筑地块(小于5)
                                argIds = getAroundRegionId(rgId);//获取周围地块
                                for (Integer tarId : argIds) {
                                    if (Integer.parseInt(regionCountMap.get(tarId).toString()) < 6 && MapBin.get(tarId).getBuildId() != 1 && MapBin.get(tarId).getBlockType() != 1) {
                                        updateRegionIds(rgId, tarId);
                                        regionCountMap.put(rgId, (Integer.parseInt(regionCountMap.get(tarId).toString()) + Integer.parseInt(regionCountMap.get(rgId).toString())));
                                        regionCountMap.remove(tarId);
                                        break;
                                    }
                                }
                            } else if (MapBin.get(rgId).getBuildId() == 4) {
                                if(ifSea) {//如果容许海洋,则合并
                                    //1:低于5的海港合并周围的最低海洋地块(小于5)
                                    argIds = getAroundRegionId(rgId);//获取周围地块
                                    for (Integer tarId : argIds) {
                                        if (Integer.parseInt(regionCountMap.get(tarId).toString()) < 6 && MapBin.get(tarId).getBuildId() != 4 && MapBin.get(tarId).getBlockType() == 1) {
                                            updateRegionIds(rgId, tarId);
                                            regionCountMap.put(rgId, (Integer.parseInt(regionCountMap.get(tarId).toString()) + Integer.parseInt(regionCountMap.get(rgId).toString())));
                                            regionCountMap.remove(tarId);
                                            break;
                                        }
                                    }
                                }else{
                                    //否则把海港归到最近的地块
                                    updHabourForE();
                                }
                            } else if (MapBin.get(rgId).getBlockType() != 1 && MapBin.get(rgId).getBuildId() == 0) {
                                //2:低于5的陆地地块合并到周围地块数量最低的陆地地块
                                argIds = getAroundRegionId(rgId);//获取周围地块
                                for (Integer tarId : argIds) {
                                    if (Integer.parseInt(regionCountMap.get(tarId).toString()) < 6 && MapBin.get(tarId).getBuildId() != 4 && MapBin.get(tarId).getBlockType() != 1) {
                                        updateRegionIds(rgId, tarId);
                                        regionCountMap.put(rgId, (Integer.parseInt(regionCountMap.get(tarId).toString()) + Integer.parseInt(regionCountMap.get(rgId).toString())));
                                        regionCountMap.remove(tarId);
                                        break;
                                    }
                                }

                            } else if (MapBin.get(rgId).getBlockType() == 1&&ifSea) {
                                //3:低于5的海洋地块合并到周围地块数量最低的海洋地块

                                argIds = getAroundRegionId(rgId);//获取周围地块
                                for (Integer tarId : argIds) {
                                    if (Integer.parseInt(regionCountMap.get(tarId).toString()) < 6 && MapBin.get(tarId).getBuildId() != 4 && MapBin.get(tarId).getBlockType() == 1) {
                                        updateRegionIds(rgId, tarId);
                                        regionCountMap.put(rgId, (Integer.parseInt(regionCountMap.get(tarId).toString()) + Integer.parseInt(regionCountMap.get(rgId).toString())));
                                        regionCountMap.remove(tarId);
                                        break;
                                    }
                                }
                            } else if (MapBin.get(rgId).getBlockType() != 1 && MapBin.get(rgId).getBuildId() != 1) {
                                //4:低于5的非城市建筑陆地地块合并到最近的城市地块

                                argIds = getAroundRegionId(rgId);//获取周围地块
                                for (Integer tarId : argIds) {
                                    if (Integer.parseInt(regionCountMap.get(tarId).toString()) < 6 && MapBin.get(tarId).getBuildId() != 4 && MapBin.get(tarId).getBlockType() != 1) {
                                        updateRegionIds(rgId, tarId);
                                        regionCountMap.put(rgId, (Integer.parseInt(regionCountMap.get(tarId).toString()) + Integer.parseInt(regionCountMap.get(rgId).toString())));
                                        regionCountMap.remove(tarId);
                                        break;
                                    }
                                }

                            } else {
                                Gdx.app.log("警告:未检测到的地块:", rgId + "");
                            }
                        }
                    }
                }
            }



            //0查看所有孤岛类地块并合并到周围地块
            {
                //自动合并孤岛类地块
                mergeIslandGridByRegion();
                regions = getIdsForBlankRegion();
                for (Integer region : regions) {//rsCoords.size()  rand.nextInt(
                    if (MapBin.get(region).getBlockType() == 1) {
                        temps = getAroundIdById(region, 3);
                    } else {
                        temps = getAroundIdById(region, 4);
                    }
                    if (temps.size() != 0) {
                        MapBin.get(region).setRegionId(temps.get(rand.nextInt(temps.size())));
                    } else {
                        Gdx.app.log("警告:有空白地块无法合并到周围地块:", region + "");
                    }
                }
            }
            {//如果不需要海则清除
                if(!ifSea){
                    for(MapBin mapbin:MapBin){
                        if(mapbin.getBlockType()==1&&mapbin.getBuildId()!=4){
                            mapbin.setRegionId(0);
                        }
                    }
                }
            }
            Gdx.app.log("执行完成", "");
        }
    }
    

    //重新切割省区 
      public void cutRegionForE(int maxC) {
          Random rand = new Random();
          int tempId, exct = 0, i = 0, iMax = 0, j, jMax, rsct, riSize;
          List<Integer> regions = null;
          List<Integer> temps = null;
          Map regionCountMap = new HashMap();
          
         {
              exct=0;
              regions = getRegions(1);
              Gdx.app.log("阶段1", "核心地块数" + regions.size()+"获得地块类:"+1); //循环 挨个对核心地块进行循环 
              while (exct < maxC && regions.size() != 0) {
                  for (i = regions.size() - 1; i >= 0; i--) {
                      tempId = getRegionIdForE(regions.get(i));
                      if (tempId >= 0) {
                          MapBin.get(tempId).setRegionId(regions.get(i));
                      } else {
                          regions.remove(i);
                      }
                  }
                  Gdx.app.log("阶段2", "核心地块数" + regions.size() + " 循环次数:" + exct);
                  exct++;
              }
          }


         
         
         
         //打印空白陆地地块和海洋有港口的地块
            // logBlankGrid();
      }
    
    //把region是target的修改为 rgId
    private void updateRegionIds(Integer rgId, Integer targetId) {
        //交换前检查合不合法
        if(MapBin.get(MapBin.get(rgId).getRegionId()).getRegionId()!=MapBin.get(rgId).getRegionId()) {
            Gdx.app.log("警告:不合法,修正前", "rgId:"+rgId+" targetId:"+targetId);
            rgId=MapBin.get(MapBin.get(rgId).getRegionId()).getRegionId();
            Gdx.app.log("警告:不合法,修正后", "rgId:"+rgId+" targetId:"+targetId);
        }
        for (MapBin mapBin : MapBin) {
            if (mapBin.getRegionId() == targetId) {
                mapBin.setRegionId(rgId);
            }
        }
        
    }
    
    public List<Integer> getAroundRegionId(int rgId) {
        List<Integer> regions = new ArrayList<Integer>();
        List<Integer> tempId;
        int i, iMax = MapBin.size();
        int blockType = MapBin.get(rgId).getBlockType();
        for (i = 0; i < iMax; i++) {
            if (MapBin.get(i).getRegionId() == rgId) {
                if (blockType != 1) {
                    //陆地
                    tempId = getAroundIdById(i, 4);
                } else {
                    //海洋
                    tempId = getAroundIdById(i, 3);
                }
                for (Integer id : tempId) {
                    if (MapBin.get(id).getRegionId() != rgId) {
                        regions.add(MapBin.get(id).getRegionId());
                    }
                }
            }
        }
        tempId = new ArrayList<Integer>();//去重
        for (Integer in : regions) {
            if (!tempId.contains(in)) {
                tempId.add(in);
            }
        }
        return tempId;
    }
    
    //根据条件获得核心地块
    private List<Integer> getRegions(int i) {
        
        //0 全部核心地块 只限城市和海港
        //1 只限于陆地的核心地块 只限城市
        //2 只限于陆地的核心地块 只限工厂且未被覆盖
        //3 只限于陆地的核心地块 只限机场且未被覆盖
        //4 只限于陆地的核心地块 只限油库且未被覆盖
        //5 只限于海洋的核心地块 只限海港
        //6 全部核心地块,不限类型
        int m;
        int mMax = MapBin.size();
        List<Integer> regions = new ArrayList<Integer>();
        if (i == 0) {
            for (m = 0; m < mMax; m++) {
                if (MapBin.get(m).getAreaId() != 0 || (MapBin.get(m).getBuildId() == 1 || MapBin.get(m).getBuildId() == 4)) {
                    regions.add(m);
                }
            }
        } else if (i == 1) {
            for (m = 0; m < mMax; m++) {
                if (MapBin.get(m).getBlockType() != 1 && (MapBin.get(m).getAreaId() != 0 || (MapBin.get(m).getBuildId() == 1))) {
                    regions.add(m);
                }
            }
        } else if (i == 2) {
            for (m = 0; m < mMax; m++) {
                if (MapBin.get(m).getBlockType() != 1 && (MapBin.get(m).getRegionId() == m || MapBin.get(m).getRegionId() == 0) && (MapBin.get(m).getAreaId() != 0 || (MapBin.get(m).getBuildId() == 2))) {
                    regions.add(m);
                }
            }
        } else if (i == 3) {
            for (m = 0; m < mMax; m++) {
                if (MapBin.get(m).getBlockType() != 1 && (MapBin.get(m).getRegionId() == m || MapBin.get(m).getRegionId() == 0) && (MapBin.get(m).getAreaId() != 0 || (MapBin.get(m).getBuildId() == 3))) {
                    regions.add(m);
                }
            }
        } else if (i == 4) {
            for (m = 0; m < mMax; m++) {
                if (MapBin.get(m).getBlockType() != 1 && (MapBin.get(m).getRegionId() == m || MapBin.get(m).getRegionId() == 0) && (MapBin.get(m).getAreaId() != 0 || (MapBin.get(m).getBuildId() == 5))) {
                    regions.add(m);
                }
            }
        } else if (i == 5) {
            for (m = 0; m < mMax; m++) {
                if (MapBin.get(m).getBlockType() == 1 && (MapBin.get(m).getAreaId() != 0 || (MapBin.get(m).getBuildId() == 4))) {
                    regions.add(m);
                }
            }
        } else if (i == 6) {
            for (m = 0; m < mMax; m++) {
                if(!regions.contains(MapBin.get(m).getRegionId())) {
                    regions.add(m);
                }
            }
        }
        return regions;
    }
    
    //根据id获得周围6边的地块id
    /*
     * type 0全部 1获取region为0的地块 3获取周围的有region的海洋地块 4获取周围的有region的陆地地块
     * 5只获取region为0的海洋地块 6只获取region为0的陆地地块 7只获取region为0的陆地平原地块
     * 8只获取region为0的陆地非平原地块 9根据id区分海洋陆地,获取region为0的地块
     * 10 获取周围是陆地的地块 11获取周围是海洋的地块
     * 12获取沿海陆地地块
     */
    public List<Integer> getAroundIdById(int id, int type) {
        List<Integer> ids = new ArrayList<Integer>();
        List<Integer> rsIds = new ArrayList<Integer>();
        boolean top = false;
        boolean foot = false;
        boolean left = false;
        boolean right = false;
        //判断处于哪个边
        int y = (int) id / mapWidth;
        int x = id - y * mapWidth;
        int t1, t2, t3, t4, t5, t6;
        
        if ((x&1) == 1) {
            t1 = id - 1;
            t2 = id - mapWidth;
            t3 = id + 1;
            t4 = id + mapWidth - 1;
            t5 = id + mapWidth;
            t6 = id + mapWidth + 1;
        } else {
            t1 = id - mapWidth - 1;
            t2 = id - mapWidth;
            t3 = id - mapWidth + 1;
            t4 = id - 1;
            t5 = id + mapWidth;
            t6 = id + 1;
        }
        if (x == 0) {
            left = true;
        }
        if (x == mapWidth - 1) {
            right = true;
        }
        if (y == 0) {
            top = true;
        }
        if (y == mapHeight - 1) {
            foot = true;
        }
        
        if (!top && !left) {
            ids.add(t1);
        }
        if (!top) {
            ids.add(t2);
        }
        if (!top && !right) {
            ids.add(t3);
        }
        if (!foot && !left) {
            ids.add(t4);
        }
        if (!foot) {
            ids.add(t5);
        }
        if (!foot && !right) {
            ids.add(t6);
        }
        
        //type 0全部 1只读取region为0的值  5只获取region为0的海洋地块 6只获取region为0的陆地地块
        //7只获取region为0的陆地平原地块  8只获取region为0的陆地非平原地块  
        //10 获取周围是陆地的地块 11获取周围是海洋的地块
        if (type == 0) {
            return ids;
        } else {
            for (Integer id2 : ids) {
                if (type == 1 && MapBin.get(id2).getRegionId() == 0) {
                    rsIds.add(id2);
                } else if (type == 6 && MapBin.get(id2).getRegionId() == 0 && MapBin.get(id2).getBlockType() != 1) {
                    rsIds.add(id2);
                } else if (type == 5 && MapBin.get(id2).getRegionId() == 0 && (MapBin.get(id2).getBlockType() == 1 || MapBin.get(id2).getBackTile() == 1)) {
                    rsIds.add(id2);
                } else if (type == 7 && MapBin.get(id2).getRegionId() == 0 && MapBin.get(id2).getBlockType() != 1 && MapBin.get(id2).getBackTile() == 0) {
                    rsIds.add(id2);
                } else if (type == 8 && MapBin.get(id2).getRegionId() == 0 && MapBin.get(id2).getBlockType() != 1 && MapBin.get(id2).getBackTile() != 0) {
                    rsIds.add(id2);
                } else if (type == 3 && MapBin.get(id2).getRegionId() != 0 && (MapBin.get(id2).getBlockType() == 1)) {
                    rsIds.add(id2);
                } else if (type == 4 && MapBin.get(id2).getRegionId() != 0 && (MapBin.get(id2).getBlockType() != 1)) {
                    rsIds.add(id2);
                } else if (type == 9 && ((MapBin.get(id).getBlockType()!=1) ==(MapBin.get(id2).getBlockType() != 1))) {
                    rsIds.add(id2);
                }  else if (type == 10 && (MapBin.get(id2).getBlockType() != 1)) {
                    rsIds.add(id2);
                }  else if (type == 11 && (MapBin.get(id2).getBlockType() == 1)) {
                    rsIds.add(id2);
                }else if (type == 12 && (MapBin.get(id2).getBlockType() == 1)&& (MapBin.get(id).getBlockType() != 1)) {
                    rsIds.add(id2);
                }
            }
            return rsIds;
        }
    }
    
    public List<Integer> getAroundIdByIds(List<Integer> ids, int type) {
        List<Integer> rss = new ArrayList<Integer>();
        for (Integer id : ids) {
            List<Integer> rs = getAroundIdById(id, type);
            rss.addAll(rs);
        }
        return rss;
    }
    
    private List<Integer> getIdByRegion(int regionId) {
        int m;
        int mMax = MapBin.size();
        List<Integer> rs = new ArrayList<Integer>();
        
        for (m = 0; m < mMax; m++) {
            if (MapBin.get(m).getRegionId() == regionId) {
                int s=m;
                rs.add(s);
            }
        }
        return rs;
    }
    
    //-1找不到
    //获得要扩展的id
    public int getRegionId(int r) {
        List<Integer> rsIds;
        //1判断自身是海洋还是陆地
        if (MapBin.get(r).getBlockType() == 1) {////获取周边的海洋地块
            rsIds = getAroundIdById(r, 5);
            if (rsIds.size() == 0) {
                rsIds = getAroundIdByIds(getIdByRegion(r), 5);
                if (rsIds == null || rsIds.size() == 0) {
                    //如果周围没有空余地块,则使用相邻的相邻地块判断
                    return -1;
                }
            }
            //根据条件随机获取其中一个地块id
            //return(rsIds.get(rand.nextInt(rsIds.size())));
            return getShortAroundId(rsIds,  MapBin.get(r).getRegionId());
        } else {////获取周边陆地地块
            rsIds = getAroundIdById(r, 7);
            if (rsIds.size() != 0&&ComUtil.ifGet(30)) {
                return getShortAroundId(rsIds,  MapBin.get(r).getRegionId());
            } else {
                rsIds = getAroundIdById(r, 8);
                if (rsIds.size() != 0&&ComUtil.ifGet(30)) {
                    return getShortAroundId(rsIds,  MapBin.get(r).getRegionId());
                } else {
                    rsIds = getAroundIdById(r, 6);
                    if (rsIds.size() != 0&&ComUtil.ifGet(30)) {
                        return getShortAroundId(rsIds,  MapBin.get(r).getRegionId());
                    } else {
                        rsIds = getAroundIdByIds(getIdByRegion(r), 6);
                        if (rsIds != null && rsIds.size() == 0&&ComUtil.ifGet(50)) {
                            //如果周围没有空余地块,则使用相邻的相邻地块判断
                            rsIds = getAroundIdByIds(getIdByRegion(r), 7);
                            if (rsIds != null && rsIds.size() == 0) {
                                //如果周围没有空余地块,则使用相邻的相邻地块判断
                                rsIds = getAroundIdByIds(getIdByRegion(r), 8);
                                if (rsIds != null && rsIds.size() == 0) {
                                            return -1;
                                }
                            }
                        }
                        if (rsIds == null) {
                            return -1;
                        }
                        return getShortAroundId(rsIds,  MapBin.get(r).getRegionId());
                    }
                }
            }
        }
    }
    
    
    
  //-1找不到
    //获得要扩展的id
    public int getRegionIdForE(int r) {
        List<Integer> rsIds;
        List<Integer> tempIds;
        //1判断自身是海洋还是陆地
        if (MapBin.get(r).getBlockType() == 1) {////获取周边的海洋地块
            rsIds = getAroundIdById(r, 5);
            if (rsIds.size() == 0) {
                rsIds = getAroundIdByIds(getIdByRegion(r), 5);
                if (rsIds == null || rsIds.size() == 0) {
                    //如果周围没有空余地块,则使用相邻的相邻地块判断
                    return -1;
                }
            }
            //根据条件随机获取其中一个地块id
            //return(rsIds.get(rand.nextInt(rsIds.size())));
            return getShortAroundId(rsIds,  MapBin.get(r).getRegionId());
        } else {////获取周边陆地地块
            rsIds = getAroundIdById(r, 6);
            if (rsIds.size() == 0) {
                tempIds= getIdByRegion(r);
                rsIds = getAroundIdByIds(tempIds, 6);
                if (rsIds == null || rsIds.size() <3) {
                    //如果周围没有空余地块,则使用相邻的相邻地块判断
                    //Gdx.app.log("清除核心", r+"");
                    return -1;
                }
            }
            int id= getShortAroundId(rsIds, MapBin.get(r).getRegionId());
             return id;
        }
    }



    //chance 最高获取概率,最低默认为10 如果不容许有海洋地块,则多抽0.1
    private List<Integer> getRegionIdsByChance(int chance,boolean ifSea) {
        if(!ifSea){
            chance= (int) (chance*1.2);
        }


        int cutSide = 5;
        Random rand = new Random();
        
        int i, j, m,rsMax,rpMax;
        int mMax = MapBin.size();//chance<(int)(Math.random()*(100)
        List<Integer> rs = new ArrayList<Integer>();
        List<Integer> result = new ArrayList<Integer>();
        //获取全部为空的地块
        for (m = 0; m < mMax; m++) {
            if (MapBin.get(m).getRegionId() == 0) {
                if(ifSea){
                    rs.add(m);
                }else if(!ifSea&&MapBin.get(m).getBlockType()!=1){
                    rs.add(m);
                }
            }
        }
        if (rs.size() == 0) {
            return rs;
        }
        rsMax=rs.size();
        rpMax=rsMax*chance/100;
        /*List<Coord> coords = converCoords(rs);
        List<Coord> rsCoords = new ArrayList<Coord>();
        rs = new ArrayList<Integer>();
        for (i = mapWidth; i >= 0; i = i - cutSide) {
            for (j = mapHeight; j >= 0; j = j - cutSide) {
                for (m = coords.size() - 1; m >= 0; m--) {
                    if (coords.get(m).getX() > i && coords.get(m).getY() > j) {
                        rsCoords.add(coords.get(m));
                        coords.remove(m);
                    }
                    if (rsCoords.size()>0) {
                        rs.add(rsCoords.get(rand.nextInt(rsCoords.size())).getId());
                        rsCoords.clear();
                        rs=ComUtil.getNewList(rs);
                    }
                    if(rs.size()>rsMax*chance/100){
                        break;
                    }
                    if (coords.size() == 0) {
                        break;
                    }
                }
            }
        }*/
        int tempId;
        for(i = 0;i<rpMax;i++){
            //显示数字并将其从列表中删除,从而实现不重复.
            tempId=new Random().nextInt(rs.size());
            rs.remove(tempId);
            result.add(tempId);
            }


        Gdx.app.log("获得随机核心", rsMax+":"+result.size());
        return result;
    }
    
    //获取空白值
    private int getRegionForIdIs0() {
        int ct = 0, m, mMax = MapBin.size();
        for (m = 0; m < mMax; m++) {
            if (MapBin.get(m).getRegionId() == 0) {
                ct++;
            }
        }
        return ct;
    }
    
    //获得空白地块
    private List<Integer> getIdsForBlankRegion() {
        int m;
        int mMax = MapBin.size();
        List<Integer> rs = new ArrayList<Integer>();
        for (m = 0; m < mMax; m++) {
            if (MapBin.get(m).getRegionId() == 0) {
                rs.add(m);
            }
        }
        return rs;
    }
    
    //将id转为coord(x,y,id,regionId) 
    private Coord converCoord(int id) {
        int y = (int) id / mapWidth;
        int x = id - y * mapWidth;
        return new Coord(x, y, id, MapBin.get(id).getRegionId());
    }
    
    //将id转为coord
    private List<Coord> converCoords(List<Integer> ids) {
        int m;
        int mMax = ids.size();
        List<Coord> rsIds = new ArrayList<Coord>();
        for (m = 0; m < mMax; m++) {
            int s=m;
            rsIds.add(converCoord(ids.get(s)));
        }
        return rsIds;
    }
    
    //获得最近的地块
    public int getShortAroundId(List<Integer> ids, int regionId) {
       // Gdx.app.log("求最近的地块,regionId", regionId+"");
        List<Coord> coords = converCoords(ids);
        int i, j, iMax = coords.size(), tempId = -1;double jl,jl2;
        Coord coord = converCoord(regionId);
        for (i = 0; i < iMax; i++) {
            for (j = 0; j < iMax; j++) {
                 jl=Math.pow((coords.get(i).getX() - coord.getX()),2) + Math.pow((coords.get(i).getY() - coord.getY()),2);
                 jl2=(Math.pow((coords.get(j).getX() - coord.getX()),2) + Math.pow((coords.get(j).getY() - coord.getY()),2));
                //Gdx.app.log("求最近的地块,交换前", "i:"+coords.get(i).getId()+" 距离系数:"+jl);
               // Gdx.app.log("求最近的地块,交换前", "j:"+coords.get(i).getId()+" 距离系数:"+jl2);
                
                if (jl<jl2) { // 交换两数的位置   
                    //Gdx.app.log("求最近的地块,交换前", "i:"+coords.get(i).getId()+" j:"+coords.get(j).getId());
                    ComUtil.swap(coords, i, j);
                    //Gdx.app.log("求最近的地块,交换后", "i:"+coords.get(i).getId()+" j:"+coords.get(j).getId());
                }
            }
        }
        //Gdx.app.log("求最近的地块,最前", coords.get(0).getId()+"");
        //Gdx.app.log("求最近的地块,最后", coords.get(coords.size()-1).getId()+"");
        Random rand = new Random();
        {//去除非同一势力 TODO
            for (i = coords.size() - 1; i >= 0; i--) {
                if(!ifComLegion(coords.get(i).getId(),coord.getId())) {
                    coords.remove(i);
                }
            }
        }
        
        
        if (coords.size() > 2) {
            tempId = coords.get(rand.nextInt(2)).getId();
        } else if (coords.size() == 0) {
            return -1;
        } else {
            tempId = coords.get(0).getId();
        }
        // 1.8的写法  取出List中的对象的属性值
        //List<Integer> xs = coords.stream().map(Coord::getX).collect(Collectors.toList());
        //List<Integer> ys = coords.stream().map(Coord::getY).collect(Collectors.toList());

        List<Integer> xs=new ArrayList<Integer>();
        List<Integer> ys=new ArrayList<Integer>();

        for(Coord cd:coords){
            xs.add(cd.getX());
            ys.add(cd.getY());
        }

        int maxX=Collections.max(xs);
        int minX=Collections.min(xs);
        int maxY=Collections.max(ys);
        int minY=Collections.min(ys);
        
        if((maxX-minX)>3||(maxY-minY)>3) {
            if((maxY-minY)!=0&&(maxX-minX)!=0&&((maxX-minX)/(maxY-minY)>2||(maxY-minY)/(maxX-minX)>2)||getRegionCountByRegionId(regionId)<((maxX-minX)*(maxY-minY)/3)) {
                return -1;
            }
        }
        /*if(getRegionCountByRegionId(regionId)>(10 + Math.random() * 5)) {
            return -1;
        }*/
        return tempId;
    }
    
    //获取各region的数量记录为map
    private Map getRegionCountMap() {
        Map rsMap = new HashMap();
        for (MapBin mapBin : MapBin) {
            if (!rsMap.containsKey(mapBin.getRegionId())) {
                rsMap.put(mapBin.getRegionId(), 1);
            } else {
                rsMap.put(mapBin.getRegionId(), Integer.parseInt(rsMap.get(mapBin.getRegionId()).toString()) + 1);
            }
        }
        return rsMap;
    }
    
    //获取通过region获取region的数量
    private int getRegionCountByRegionId(int regionId) {
        int c=0;
        for (MapBin mapBin : MapBin) {
            if (mapBin.getRegionId()==regionId) {
                c++;
            }
        }
        return c;
    }

    //通过多个region获取ids
    public List<Integer> getIdsByRegionIds(List<Integer> regionIds){
        List<Integer> rs= new ArrayList<Integer>();
        int c=0;
        for (MapBin mapBin : MapBin) {
            if (regionIds.contains(mapBin.getRegionId())) {
                rs.add(c);
            }
            c++;
        }
        return rs;
    }

    //通过region获取ids
    public List<Integer> getIdsByRegionId(int regionId){
        List<Integer> rs= new ArrayList<Integer>();
        int c=0;
        for (MapBin mapBin : MapBin) {
            if (mapBin.getRegionId()==regionId) {
                rs.add(c);
            }
            c++;
        }
        return rs;
    }
    //获取所有region
    public List<Integer> getAllRegionIds(){
        List<Integer> rs = new ArrayList<Integer>();
        for (MapBin mapBin : MapBin) {
            if (mapBin.getRegionId()!=0&&!rs.contains(mapBin.getRegionId())) {
                rs.add(mapBin.getRegionId());
            }
        }
        return rs;
    }
    
    //合并孤岛类地块
    private void mergeIslandGridByRegion() {
        int i,iMax=MapBin.size(),rsI=0;
        String rz;
        List<Integer> rs;
        int tempRegionId;
        for (i=0;i<iMax;i++) {
            //获得结果值
            rs= getAroundIdById(i,9);
            Collections.sort(rs);
            rsI=0;
            //判断是否是孤岛
            for(Integer id:rs) {
                if(MapBin.get(id).getRegionId()!=MapBin.get(i).getRegionId()) {
                    rsI++;
                }
            }
            if(rsI>4) {
                rz= ComUtil.getListMostRepeatData(rs);
                //updateRegionIds(MapBin.get(Integer.parseInt(rz)).getRegionId(),i);
                MapBin.get(i).setRegionId(MapBin.get(Integer.parseInt(rz)).getRegionId());
            }
            
        }
    }
    
    
    
    public static void main(String[] args) {
        int i;
        
        for (i = 0; i < 30; i++) {
            System.out.println("sj:" + (int) (10 + Math.random() * 15));
        }
        
    }
    
    //检查所属的区块是不是合法的region,如果不是给周围的地块 TODO测试
    private void checkRegion() {
        int i,iMax=MapBin.size();String rsI;
        List<Integer> rs;
        for (i=0;i<iMax;i++) {
            //获得结果值
            rs= getAroundIdById(i,9);
            Collections.sort(rs);
            if(MapBin.get(MapBin.get(i).getRegionId()).getRegionId()!=MapBin.get(i).getRegionId()) {
                rsI=ComUtil.getListMostRepeatData(rs);
                if(rsI!=null&&rsI!="") {
                    //Gdx.app.log("所属区域region不合法:", "i:"+i);
                    updateRegionIds(MapBin.get(Integer.parseInt(rsI)).getRegionId(),MapBin.get(i).getRegionId());
                }
            }
        }
    }
    
  //打印空白的非海洋地块(包括港口)
    private  void logBlankGrid() {
       int i=0;
        for (MapBin mapBin : MapBin) {
            if (mapBin.getRegionId()==0&&(mapBin.getBackTile()!=1&&mapBin.getBackTile()!=2)) {
                Gdx.app.log("空白地块", i+"");
            }
            i++;
        }
    }
    
  //验证势力是否一致   r源id  i目标id
   private boolean ifComLegion(int r,int i) {
       int sourceLegion=MapBin.get(r).getFacility();
       int regionLegion=MapBin.get(i).getFacility();
       if(sourceLegion==regionLegion) {
           return true;
       }else if(sourceLegion==255) {
           return true;
       }else {
           return false;
       }
       
   }
    
   //将海港城市归为最近的陆地城市
    private void updHabourRegionForE() {
        List<Integer> habour= getRegions(5);
        List<Integer> rsIds,tempIds;int id;
        Random rand = new Random();
        for(Integer r:habour) {
            rsIds = getAroundIdById(r, 4);
            if (rsIds.size() == 0) {
               Gdx.app.log("警告", r+":海港周围为空");
            }else {
                id= rsIds.get(rand.nextInt(rsIds.size()));
                if(id!=-1&&MapBin.get(r).getRegionId()==r) {
                    MapBin.get(r).setRegionId(MapBin.get(id).getRegionId());
                }
            }
        }
    }
    
    public void updHabourForE() {
        updHabourRegionForE();
        logBlankGrid();
    }

    //替换当前的地区的所有相同区块为一个id的所在区块
    public void replaceRegionIdById(int id){
        int regionId=MapBin.get(id).getRegionId();
        for (MapBin mapBin : MapBin) {
            if(mapBin.getRegionId()==regionId){
                mapBin.setRegionId(id);
            }
        }
    }


    //替换当前空白的地块以及与其相邻的地块的region
    public void replaceRegionIdForFFArea(int id,int regionId){
        //替换不穿海,只替换该区域的
        List<Integer> rs= new ArrayList<Integer>();
        List<Integer> tempI;
        if(MapBin.get(id).getRegionId()!=0){
            return;
        }else{
            List<Integer> tempIds=getAroundIdById(id, 6);
            rs.addAll(tempIds);
            int n=0;
            do{
                tempIds= (List<Integer>) ((ArrayList<Integer>) rs).clone();
                for(int i:tempIds){
                    tempI=getAroundIdById(i, 6);
                    rs.removeAll(tempI);
                    rs.addAll(tempI);
                }
                n=n+1;
                if(n>5){
                    break;
                }
            }while(ComUtil.ifListContainListByInteger(rs,tempIds));


            for(int i:rs){
                MapBin.get(i).setRegionId(regionId);
            }
        }
    }

    //批量获取符合某种条件的地块,条件参看getAroundIdById
    public List<Integer> getIdsByAround(int type){
        List<Integer> rsGrid=new ArrayList<Integer>();
        List<Integer> rs;
        int id=0;
        for (MapBin mapBin : MapBin) {
            rs = getAroundIdById(id, type);
            if(rs.size()>0){
                rsGrid.add(id);
            }
            id=id+1;
        }
        return rsGrid;
    }

    public Map getRegionMap() {
        if(regionMap==null){
            regionMap=new HashMap();
            int i=0;
            for (MapBin mapBin : MapBin) {
                if(mapBin.getRegionId()==i&&mapBin.getRegionId()!=0){
                    regionMap.put(mapBin.getRegionId(),i);
                }
                i=i+1;
            }
        }
        return regionMap;
    }
    public int getIdByRegionId(int regionId){
        if(regionMap==null){
            getRegionMap();
        }
        if(regionMap.containsKey(regionId)){
            return (int) regionMap.get(regionId);
        }
        return -1;
    }

}
MapBinDAO

另附最近的进度