在这之前我并没有怎么接触过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; } }
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; } }
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; } }
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; } }
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; } }
另附最近的进度