经过构思,游戏将分为两部分,
1,预览图,只负责展示世界形势
2,根据预览图生成的战役项
现在要记录的是我制作预览图的部分
1.预览图只有实际地图的1/4,首先生成地图(建议不要缩放以前地图,由于误差原因会导致地图色绘制不准),由于方法只支持int值,1/4导致一些误差(海洋中有些尖刺),不得不手动修复
然后处理为4024*2024大小通过分割工具分割为几部分
再通过xml记录绘制位置,在游戏中合成大图
<SmallMaps><!--存放位置为img下的name文件夹,id与mapId一一对应--> <Maps id="1" name="world" width="3308" height="1536" > <map n="1.png" x="0" y="0"/> <map n="2.png" x="1000" y="0"/> <map n="3.png" x="2000" y="0"/> <map n="4.png" x="3000" y="0"/> <map n="5.png" x="0" y="1000"/> <map n="6.png" x="1000" y="1000"/> <map n="7.png" x="2000" y="1000"/> <map n="8.png" x="3000" y="1000"/> </Maps> </SmallMaps>
经过考虑,将把预览图内容放入actor中
首先实现根据玩家动作缩放,移动预览图
然后是地图循环
先定义ifLoop,drawLoop状态,在actor中的draw方法里
如果是drawLoop状态,则在上次绘制的右边追加一次绘制
{ 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); }
然后是通过x坐标判断drawLoop状态
public void setX(float x) { if(ifLoop){////判断当前坐标是否需要循环显示右边 if(x<=xMin&&x >= (-xMax * zoom + vw)){ drawLoop=false; }else if(x>xMin){//从起点向左 drawLoop=true; x=(-xMax -vw)+x; }else if(x < (-xMax + vw)&&x>(-xMax )){//划入右边,接近循环 drawLoop=true; }else if(x<=(-xMax -vw)) {//划出并还原 drawLoop=false; x = x + xMax +vw; }/**/ }else { if (x > xMin) { x = xMin; } else if (x < -(xMax)) { x = -(xMax); } } this.x = x; }
然后就可以实现循环了.
以下为地图色思路:
地图色这里使用的是区块色,前几天花了两天时间重绘了地图色
首先说思路:
首先绘制区块色(缩放1/4)
然后与预览图一起加载这里会完美的盖到一起(如果是用相同坐标绘制是不会有偏差的)
然后是区块变色,这里参考了libgdx 涂口红的原理,使用 texture.draw(pixmap,0,0);
变色前:
变色后:
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.Texture; 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.Group; 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.GameMap; import com.zhfy.game.framework.GameUtil; import com.zhfy.game.model.framework.TextureRegionListDAO; import com.zhfy.game.screen.actor.MapActor; import com.zhfy.game.screen.actor.SMapActor; /** * 主游戏场景(游戏主界面), 实现 Screen 接口 或者 继承 ScreenAdapter 类 <br/> * 这里就展示一张图片代表游戏主界面 */ public class GameScreen extends ScreenAdapter { private MainGame game; private Stage gameStage; private TextureRegionListDAO imgLists; private TextureRegionListDAO imgUpList; private TextureRegionListDAO imgDownList; 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; //中心点位置 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; com.badlogic.gdx.utils.Array<Element> buttonEs; private Map tempMap; private int i;//function的计数标志,从1开始 private SMapActor mapActor; private float mapX; private float mapY; private float mapXMax; private float mapYMax; private float mapScaleX; private float mapScaleY; public GameScreen(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(); // 使用伸展视口创建舞台 gameStage = new Stage(new StretchViewport(GAMESTAGE_WIDTH, GAMESTAGE_HEIGHT)); // 将输入处理设置到舞台(必须设置, 否则点击按钮没效果) 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 SMapActor(stageId,GAMESTAGE_WIDTH, GAMESTAGE_HEIGHT,mainGame.getAssetManager(),screenId); gameStage.addActor(mapActor); //将来以玩家选择国家首都为位置标准 TODO //根据screenId初始化资源 //获取对应图片 imgLists=GameUtil.getTextureReigonByScreenId( screenId,mainGame.getAssetManager()); i=1; for (Element window:ui) { tempX=window.getInt("x");tempY=window.getInt("y");tempW=window.getInt("w");tempH=window.getInt("h"); // 添加演员到舞台 imgUpList=new TextureRegionListDAO(); imgDownList=new TextureRegionListDAO(); //遍历window的buttons按钮 buttonEs = window.getChildByName("buttons").getChildrenByNameRecursively("button"); // 递归遍历,否则的话返回null for (Element buttonE : buttonEs) { //Gdx.app.log("ui测试", button.get("remark")); imgUpList.add(imgLists.getTextureByName(buttonE.get("imgUpName"))); imgDownList.add(imgLists.getTextureByName(buttonE.get("imgDownName"))); 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(new BitmapFont(), null)); label.setWidth(200);//设置每行的宽度 label.setWrap(true);//开启换行 label.setPosition(20, 40); gameStage.addActor(label); 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"); //label.getText().appendLine("inputKeyMode:"+mapActor.getKeyMode());//快捷键模式 gp.reset(); } public void dispose() { super.dispose(); // 场景被销毁时释放资源 if (gameStage != null) { gameStage.dispose(); gameStage=null; } if(mapActor!=null){ mapActor.dispose(); mapActor=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://保存bin button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { Gdx.app.log("点击了第3个按钮2", "x:" + x+" y:" + y+" stageId:"+stageId); } }); break; case 3://随机装饰(除特殊装饰外) button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { Gdx.app.log("点击了第4个按钮", "x:" + x+" y:" + y+" stageId:"+stageId); } }); break; case 4: button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { Gdx.app.log("点击了第4个按钮", "x:" + x+" y:" + y+" stageId:"+stageId); } }); break; case 5: button.addListener(new ClickListener() { public void clicked(InputEvent event, float x, float y) { Gdx.app.log("点击了第4个按钮", "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("点击了第5个按钮", "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) { mapActor.setZoom(mapActor.getZoom()+0.01f,cx,cy); }else { mapActor.setZoom(mapActor.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; } mapActor.setX(mapActor.getX()-moveX); mapActor.setY(mapActor.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)) { mapActor.setX(mapActor.getX()+1); } if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) { mapActor.setX(mapActor.getX()-1); } if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) { mapActor.setY(mapActor.getY()+1); } if (Gdx.input.isKeyPressed(Input.Keys.UP)) { mapActor.setY(mapActor.getY()-1); } } public int getStageId() { return stageId; } public void setStageId(int stageId) { this.stageId = stageId; } }
package com.zhfy.game.screen.actor; import java.util.ArrayList; import java.util.List; 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.BitmapFont; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; 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.zhfy.game.config.ResConfig; import com.zhfy.game.config.ResConfig.Map; import com.zhfy.game.framework.ComUtil; import com.zhfy.game.framework.GameFramework; import com.zhfy.game.framework.GameMap; import com.zhfy.game.framework.GameUtil; import com.zhfy.game.model.content.BTLDAO; import com.zhfy.game.model.content.MapBinDAO; import com.zhfy.game.model.content.def.DefMap; import com.zhfy.game.model.content.def.DefPt; import com.zhfy.game.model.content.def.DefStage; import com.zhfy.game.model.framework.Coord; import com.zhfy.game.model.framework.SpriteDAO; import com.zhfy.game.model.framework.SpriteListDAO; public class SMapActor extends Actor { //做实时绘制前的备份 // 本类用来存放背景地图,获取地图范围,移动,缩放背景地图,确定点击位置等,以及环状地图 //private DefMap defMap; private Pixmap pixmap;// 临时画布 private MapBinDAO mapBinDAO; private BTLDAO btlDao; private DefStage defStage; private List<Integer> coastGrid; private List<Integer> regionGrid; private Texture textureMain;// 主图 private Texture textureCountry; private Pixmap pixmapCountry; private Sprite spriteMain;// 主图 private Sprite spriteCountry; private GameFramework gameFramework; private float x; private float y; private int w; private int h; private int mapId; private int mapW_px; private int mapH_px; private boolean ifLoop;// 是否循环 private boolean drawLoop; private float zoom; private float zoomMax; private float zoomMin; private float xMin; private float yMin; private float xMax; private float yMax; private float vw; private float vh; private float vx; private float vy; private Coord coord; private Coord gridCoord; private AssetManager am; Color oldColor; private int screenId; private boolean ifNeedUnload;//是否需要卸载,在资源加载完后卸载,如果未加载完退出,在退出时顺带清理资源 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 Texture textureGrid; private SpriteDAO spriteGrid; private SpriteListDAO spriteGrids; private int gw; private int gh; public SMapActor(int stageId, float vw, float vh, AssetManager am, int screenId) { super(); this.am=am; ifLoop = true;//TODO drawLoop=false; ifNeedUnload=false; this.screenId=screenId; // 获取defMap this.gameFramework=new GameFramework(); defStage = gameFramework.getDefStageByStageId(stageId); long start = System.currentTimeMillis(); btlDao=gameFramework.getBtlDaoByStageId(stageId); long end = System.currentTimeMillis(); // 记录结束时间 Gdx.app.log("stage加载时间", (end-start)+""); mapBinDAO = gameFramework.getMapDaoByMapId(stageId);; //mapBinDAO=new MapBinDAO(btlDao); coastGrid=mapBinDAO.getIdsByAround(12); regionGrid=mapBinDAO.getAllRegionIds(); { // 绘制主要图 textureMain= new Texture(GameMap.drawSmallMapAndClearPixmap(stageId,am)); spriteMain= new Sprite(textureMain); } { this.x = 0;// TODO 随后设计为玩家起始位置 this.y = 0; this.w = mapBinDAO.getMapWidth(); this.h = mapBinDAO.getMapHeight(); this.vw = vw; this.vh = vh; // 实际宽高 this.mapW_px = textureMain.getWidth(); this.mapH_px = textureMain.getHeight(); this.zoom = 1f; this.zoomMax = 1.2f; this.zoomMin = 0.5f; this.xMax = mapW_px*this.zoom-vw;; this.yMax = mapH_px*this.zoom-vh; this.yMin = 0; this.xMin = 0; } /**/{//绘制一个区域图 // 绘制画布转为装饰 long startTime = System.currentTimeMillis(); pixmapCountry = GameMap.createPixmap((int)(w*ResConfig.Map.SMALLMAP_SCALE),(int)(h*ResConfig.Map.SMALLMAP_SCALE)); GameMap.getPixmapByDaoForColor(mapBinDAO,pixmapCountry,ResConfig.Map.SMALLMAP_SCALE,coastGrid); //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()); } /*{ // 绘制画布转为装饰 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) {//TODO 点击生成任务区域 // 点击图片,图片隐藏![这里写图片描述](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,int regionId,Color color,List<Integer> coastGrid pixmapCountry=GameMap.updateColorByRegion(mapBinDAO,pixmapCountry, Map.SMALLMAP_SCALE,regionGrid.get(ComUtil.getOneByListRand(regionGrid)),GameUtil.getColorByNum((int)(Math.random()*60000)),coastGrid); textureCountry.draw(pixmapCountry,0,0); } }); } @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); } } public float getX() { return x; } public void setX(float x) { if(ifLoop){////判断当前坐标是否需要循环显示右边 if(x<=xMin&&x >= (-xMax * zoom + vw)){ drawLoop=false; }else if(x>xMin){//从起点向左 drawLoop=true; x=(-xMax -vw)+x; }else if(x < (-xMax + vw)&&x>(-xMax )){//划入右边,接近循环 drawLoop=true; }else if(x<=(-xMax -vw)) {//划出并还原 drawLoop=false; x = x + xMax +vw; }/**/ }else { if (x > xMin) { x = xMin; } else if (x < -(xMax)) { x = -(xMax); } } this.x = x; } public float getY() { return y; } public void setY(float y) { if (y > yMin) { y = yMin; } else if (y < -yMax) { y = -yMax; } this.y = y; } 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; } public float getVw() { return vw; } public void setVw(float vw) { this.vw = vw; } public float getVh() { return vh; } public void setVh(float vh) { this.vh = vh; } public float getZoom() { return zoom; } public void setZoom(float zoom,float cx,float cy) { this.xMax = mapW_px*zoom-vw;; this.yMax = mapH_px*zoom-vh; 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 - (vh-cy)) * (zoom-this.zoom)) / zoom); this.zoom = zoom; } } // 将↓→坐标(左上角为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 MapBinDAO getMapBinDAO() { return mapBinDAO; } public void setMapBinDAO(MapBinDAO mapBinDAO) { this.mapBinDAO = mapBinDAO; } 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 float getZoomMax() { return zoomMax; } public void setZoomMax(float zoomMax) { this.zoomMax = zoomMax; } 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; } }
package com.zhfy.game.framework; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.Properties; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.PixmapIO; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.TextureData; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.XmlReader; import com.badlogic.gdx.utils.XmlReader.Element; import com.badlogic.gdx.utils.viewport.StretchViewport; import com.zhfy.game.MainGame; import com.zhfy.game.config.ResConfig; import com.zhfy.game.framework.tool.BTLTooL; import com.zhfy.game.framework.tool.FSearchTool; import com.zhfy.game.model.content.BTLDAO; import com.zhfy.game.model.content.MapBinDAO; import com.zhfy.game.model.content.def.DefMap; import com.zhfy.game.model.content.def.DefPt; import com.zhfy.game.model.content.def.DefStage; import com.zhfy.game.model.content.def.DefTerrainimg; import com.zhfy.game.model.framework.PixmapDAO; import com.zhfy.game.model.framework.PixmapListDAO; import com.zhfy.game.model.framework.TextureDAO; import com.zhfy.game.model.framework.TextureListDAO; import com.zhfy.game.model.framework.TextureRegionDAO; import com.zhfy.game.model.framework.TextureRegionListDAO; import com.zhfy.game.screen.actor.base.BaseActor; public class GameFramework { //private TextureListDAO imgLists; //private Texture imgBg; //private List<Stage> stages; private byte[] bt;// 等待清空 //private MapBinDAO mapBinDao;// 等待清空 //private Pixmap pixmap;// 使用完就清空 //private PixmapListDAO pixmapLists;// 使用完就清空 private FSearchTool tool ;//哪个用到哪个初始化 /*//TODO // 通过使用场景来清理图片 public void textureDispose(int beforeScreenId,int nextScreenId) { Gdx.app.log("执行了内存销毁 " ," screenId:"+beforeScreenId); //获取当前场景,下一个场景要加载的资源图 //比对资源,把不用的资源清除掉 // 通过使用场景id获取图片名集合 List<String> nameList = getTextureNameByScreenId(beforeScreenId); // 根据图片名集合清理资源 imgLists.clearTexture(nameList); // 清理背景图 if (imgBg != null) { imgBg.dispose(); imgBg = null; } }*/ // 通过screenId获取要读取的图片资源 public List<String> getTextureNameByScreenId(int screenId) { List<String> strs = new ArrayList<String>(); XmlReader reader = ResConfig.reader; Element root = ResConfig.ConfigScreen; int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id") == screenId) { Array<Element> xmlFiles = root.getChild(i) .getChildrenByNameRecursively("xmlFile"); for (Element xmlFile : xmlFiles) { strs.add(xmlFile.get("name")); } break; } } return strs; } /*// 根据screenid,获取要加载的资源 public TextureRegionListDAO getTextureReigonByScreenId(int screenId) { // 验证imgLists是否有东西 List<String> nameList = getTextureNameByScreenId(screenId); TextureRegionListDAO imgList = new TextureRegionListDAO(); for (int i = 0; i < nameList.size(); i++) { XmlReader reader = ResConfig.reader; *//** * root是整个xml文件从根节点算起,此处是指<Credits> </Credits> *//* Element root = reader.parse( Gdx.files.internal("image/" + nameList.get(i) + ".xml")); String imgFile = root.getAttribute("imagePath"); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = root.getChildrenByNameRecursively("sprite"); for (Element image : images) { TextureRegion imgRegion = new TextureRegion( imgLists.getName(nameList.get(i)).getTexture(), image.getInt("x"), image.getInt("y"), image.getInt("w"), image.getInt("h")); TextureRegionDAO imgRegionDAO = new TextureRegionDAO(); imgRegionDAO.setTextureRegion(imgRegion); imgRegionDAO.setRefx(image.getInt("refx")); imgRegionDAO.setRefy(image.getInt("refy")); imgRegionDAO.setName(image.get("n").replace(".png", "")); imgList.add(imgRegionDAO); // Gdx.app.log("getImgName",image.get("n").replace(".png", "")+" // x:"+image.getInt("refx")+" y:"+image.getInt("refy")); } } imgList.check(); return imgList; }*/ /*// 根据imgName,获取要加载的资源 public TextureRegionListDAO getTextureReigonByImgFileName( String imgFileName) { // 验证imgLists是否有东西 TextureRegionListDAO imgList = new TextureRegionListDAO(); XmlReader reader = ResConfig.reader; Element root = reader .parse(Gdx.files.internal("image/" + imgFileName + ".xml")); String imgFile = root.getAttribute("imagePath"); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = root.getChildrenByNameRecursively("sprite"); for (Element image : images) { TextureRegion imgRegion = new TextureRegion( imgLists.getName(imgFileName).getTexture(), image.getInt("x"), image.getInt("y"), image.getInt("w"), image.getInt("h")); TextureRegionDAO imgRegionDAO = new TextureRegionDAO(); imgRegionDAO.setTextureRegion(imgRegion); imgRegionDAO.setRefx(image.getInt("refx")); imgRegionDAO.setRefy(image.getInt("refy")); imgRegionDAO.setName(image.get("n").replace(".png", "")); imgList.add(imgRegionDAO); // Gdx.app.log("getImgName",image.get("n").replace(".png", "")+" // x:"+image.getInt("refx")+" y:"+image.getInt("refy")); } imgList.check(); return imgList; }*/ // TODO 未验证 // 根据imgName,获取要加载的资源 /*public PixmapListDAO getPixmapByImgFileName(String fileName) { PixmapListDAO pixmapLists=new PixmapListDAO(); // 验证pixmapLists是否有东西 XmlReader reader = ResConfig.reader; Element root = reader .parse(Gdx.files.internal("pixmap/" + fileName + ".xml")); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = root.getChildrenByNameRecursively("sprite"); for (Element image : images) { PixmapDAO pixmapDAO = new PixmapDAO(); pixmapDAO.setPixmap( new Pixmap(Gdx.files.internal("pixmap/"+image.get("n"))));; pixmapDAO.setRefx(image.getInt("refx")); pixmapDAO.setRefy(image.getInt("refy")); pixmapDAO.setName(image.get("n").replace(".png", "")); pixmapLists.add(pixmapDAO); } pixmapLists.check(); return pixmapLists; }*/ /* // 根据screenId获取加载的背景图名称 public Texture getBgTextureByScreenId(int screenId,AssetManager as) { XmlReader reader = ResConfig.reader; String str = ""; Element root = ResConfig.ConfigScreen; int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id") == screenId) { str = root.getChild(i).get("bgImg"); //imgBg = new Texture(Gdx.files.internal("image/" + str + ".png")); imgBg =as.get("image/" + str + ".png", Texture.class); return imgBg; } } return null; }*/ // 根据screenId来把资源存入 getResourceByScreentId /*public void init(int screenId) { imgLists = new TextureListDAO(); List<String> nameList = getTextureNameByScreenId(screenId); //stages = new ArrayList<Stage>(); for (int i = 0; i < nameList.size(); i++) { XmlReader reader = ResConfig.reader; *//** * root是整个xml文件从根节点算起,此处是指<Credits> </Credits> *//* Element root = reader.parse( Gdx.files.internal("image/" + nameList.get(i) + ".xml")); String imgFile = root.getAttribute("imagePath"); // 加入临时文件 TextureDAO tempImgDao = new TextureDAO(); tempImgDao.setName(imgFile.toString().substring(0, imgFile.toString().lastIndexOf("."))); tempImgDao.setTexture( new Texture(Gdx.files.internal("image/" + imgFile))); imgLists.add(tempImgDao); // Gdx.app.log( "setImgName", imgFile.toString().substring(0, // imgFile.toString().lastIndexOf("."))); } }*/ // 根据配置文件生成相关stage对象并返回 // stage相当于一个窗口,一个游戏场景由一个或多个窗口组成 // 暂时废弃 /* public List<Stage> getStagesByScreenId(int screenId) { Stage stage = new Stage(new StretchViewport(ResConfig.FIX_WORLD_WIDTH, Gdx.graphics.getHeight() * ResConfig.FIX_WORLD_WIDTH / Gdx.graphics.getWidth())); GameFramework framework = new GameFramework(); // 根据screenId获取下级元素 XmlReader reader = ResConfig.reader; Element root = reader .parse(Gdx.files.internal("config/config_layout.xml")); int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("screenId") == screenId) { // 绘制背景图 imgBg = new Texture(Gdx.files.internal( "image/" + root.getChild(i).get("bg") + ".png")); BaseActor actor = new BaseActor(new TextureRegion(imgBg)); stage.addActor(actor); // 如果defaultWinId不为空,则查找对应win if (!root.getChild(i).get("defaultWinId").equals("")) { int childNum1 = root.getChild(i).getChildCount(); for (int i1 = 0; i1 < childNum1; i1++) { // 生成win下的各个组件 pixmap 拼合图 textures 装饰图 buttons 按钮 Element pixmaps = root.getChild(i).getChild(i1) .getChildByName("pixmaps"); // Gdx.app.log("imgs",imgs.size+""); // 临时-拼合图 { Array<Element> pixmapList = pixmaps .getChildrenByNameRecursively("pixmap"); for (Element pixmap : pixmapList) { Array<Element> imgs = pixmap .getChildrenByNameRecursively("img"); // Gdx.app.log("imgs",imgs.size+""); for (Element img : imgs) { } } } Element textures = root.getChild(i).getChild(i1) .getChildByName("textures"); // 装饰图 { } Element buttons = root.getChild(i).getChild(i1) .getChildByName("buttons"); // 按钮 { } if (stage != null) { //stages.add(stage); } // 打开默认窗口 } } } } return null; }*/ // 根据mapid生成MapBinDAO类 画全图 public MapBinDAO getMapDaoByMapId(int mapId) { XmlReader reader = ResConfig.reader; String str = ""; Element root = reader.parse(Gdx.files.internal("config/def_map.xml")); int childNum = root.getChildCount(); MapBinDAO mapBinDao=null; for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id") == mapId) { str = root.getChild(i).get("name"); //TODO 安卓不能加载,会闪退 bt = Gdx.files.local("bin/" + str + ".bin").readBytes(); //bt = Gdx.files.internal("bin/" + str + ".bin").readBytes(); try { mapBinDao = GameMap.saveBin(bt); } catch (IOException e) { e.printStackTrace(); } return mapBinDao; } } return mapBinDao; } public BTLDAO getBtlDaoByStageId(int stageId) { XmlReader reader = ResConfig.reader; String str = ""; // FileHandle file = Gdx.files.internal("rule/rule_fb1_btl.xml"); Element root = reader.parse(Gdx.files.internal("config/def_stage.xml")); int childNum = root.getChildCount(); BTLDAO btlDao=null; for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id") == stageId) { str = root.getChild(i).get("name"); bt = Gdx.files.internal("stage/" + str + ".btl").readBytes(); try { btlDao = BTLTooL.LoadBtl("rule/rule_fb1_btl.xml",bt); } catch (Exception e) { e.printStackTrace(); } return btlDao; } } return btlDao; } //根据传入的地图编号保存地图 public void saveMapDaoByMapId(MapBinDAO mapbin,int mapId) { XmlReader reader = ResConfig.reader; String str = ""; Element root = reader.parse(Gdx.files.internal("config/def_map.xml")); int childNum = root.getChildCount(); for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id") == mapId) { str = root.getChild(i).get("name"); String path="bin/" + str + ".bin"; GameMap.saveMapBin(mapbin,path); } } } //根据MapId获得地图属性 public DefMap getDefMapByMapId(int id) { DefMap defMap = new DefMap(); List<DefMap> defMaps = new ArrayList<DefMap>(); try { defMaps = GameUtil.getDaoListByClass(defMap, "config/def_map.xml"); } catch (Exception e) { e.printStackTrace(); } if (defMaps != null) { try { tool= new FSearchTool(defMaps, "id"); return (DefMap) tool.searchTask((id+"")); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } //根据MapId获得地图属性 public DefStage getDefStageByStageId(int id) { DefStage defStage = new DefStage(); List<DefStage> defStages = new ArrayList<DefStage>(); try { defStages = GameUtil.getDaoListByClass(defStage, "config/def_stage.xml"); } catch (Exception e) { e.printStackTrace(); } if (defStages != null) { try { tool= new FSearchTool(defStages, "id"); return (DefStage) tool.searchTask((id+"")); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } // 依据id画全图 public Texture getMapByMapId(int id,AssetManager am,float scale) { // 2.1加载图片资源 一次性使用 用完就删 //TextureRegionListDAO mapRegionList = getTextureReigonByImgFileName("bt_tiles"); PixmapListDAO pixmapLists=getPixmapListByFileName("pm_tiles",am); MapBinDAO mapBinDao=null; // 2.2加载地图属性 DefTerrainimg defTerrainimg = new DefTerrainimg(); DefMap defMap = new DefMap(); List<DefTerrainimg> defTerrainimgs = new ArrayList<DefTerrainimg>(); List<DefMap> defMaps = new ArrayList<DefMap>(); boolean state=false; try { defTerrainimgs = GameUtil.getDaoListByClass(defTerrainimg, "config/def_terrainimg.xml"); defMaps = GameUtil.getDaoListByClass(defMap, "config/def_map.xml"); } catch (Exception e) { e.printStackTrace(); } // 2.3加载bin mapBinDao = getMapDaoByMapId(id); // 2.4读取map.xml获取地图属性 if (defMaps != null) { /*for (int i = 0; i < defMaps.size(); i++) { if (defMaps.get(i).getId() == id) { defMap = defMaps.get(i); state=true; break; } }*/ try { tool= new FSearchTool(defMaps, "id"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } defMap =(DefMap) tool.searchTask((id+"")); if(defMap!=null) { state=true; } } if(state) { Gdx.app.log("存在地图:", "继续"); }else { Gdx.app.log("不存在地图:", "终止"); return null; } // 2.5生成Pixmap Pixmap pixmap=GameMap.createPixmapByDefMap(defMap); //绘制底纹 pixmap=GameMap.coverImgByPtimgId(pixmap,2); long startTime = System.currentTimeMillis(); //获取开始时间 //绘图 pixmap=GameMap.getPixmapByDao(mapBinDao,pixmap,pixmapLists,defTerrainimgs,0,mapBinDao.getMapbin().size(),scale); long endTime = System.currentTimeMillis(); //获取结束时间 Gdx.app.log("地图构建", " 运行时间:"+(endTime - startTime) + "ms"); // 再由新的 Pixmap 对象生成一个新的 Texture 对象 Texture textureMap = new Texture(pixmap, Format.RGBA8888,false); if(pixmap!=null) { //这里输出截图进行测试 //PixmapIO.writePNG(Gdx.files.external(defMap.getName()+".png"), pixmap); pixmap.dispose(); //Gdx.app.log("地图图片保存", "成功"); } //clearPixmapListByFileName("pm_tiles"); return textureMap; } // 根据条件画图 public Pixmap getPixmapDecorateByDao(Pixmap pixmap,MapBinDAO mapBinDao,AssetManager am,float scale) { // 2.1加载图片资源 一次性使用 用完就删 //TextureRegionListDAO mapRegionList = getTextureReigonByImgFileName("bt_tiles"); PixmapListDAO pixmapLists=getPixmapListByFileName("pm_tiles",am); // 2.2加载地图属性 DefTerrainimg defTerrainimg = new DefTerrainimg(); List<DefTerrainimg> defTerrainimgs = new ArrayList<DefTerrainimg>(); try { defTerrainimgs = GameUtil.getDaoListByClass(defTerrainimg, "config/def_terrainimg.xml"); } catch (Exception e) { e.printStackTrace(); } long startTime = System.currentTimeMillis(); //获取开始时间 //绘图 pixmap=GameMap.getPixmapByDao(mapBinDao,pixmap,pixmapLists,defTerrainimgs,0,mapBinDao.getMapbin().size(),scale); long endTime = System.currentTimeMillis(); //获取结束时间 Gdx.app.log("地图构建", " 运行时间:"+(endTime - startTime) + "ms"); //clearPixmapListByFileName("pm_tiles"); return pixmap; } //根据条件给陆地打孔 废弃 /* public Pixmap getLandByDAO(MapBinDAO mapBinDAO, Pixmap pixmap, int mapx, int mapy,int mapw,int maph) { //加载打孔图片 PixmapListDAO pixmapLists=getPixmapListByFileName("pm_shadow"); pixmap=GameMap.getLandByDAO(mapBinDAO,pixmap,pixmapLists,mapx,mapy,mapw,maph); //clearPixmapListByFileName("pm_shadow"); return pixmap; }*/ //加载内存图片PixmapListDAO pixmapLists 目标pm_tiles 则传入pm_tiles TODO public static PixmapListDAO getPixmapListByFileName(String fileName,AssetManager am) { //1读取路径下说明文件 XmlReader reader = ResConfig.reader; Element root = reader .parse(Gdx.files.internal("pixmap/"+fileName.substring(3)+"/" + fileName + ".xml")); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = root.getChildrenByNameRecursively("sprite"); //验证pixmapLists是否有东西 PixmapListDAO pixmapLists=new PixmapListDAO(); //2根据说明文件添加到pixmapLists for (Element image : images) { PixmapDAO pixmapDAO = new PixmapDAO(); //pixmapDAO.setPixmap( new Pixmap(Gdx.files.internal("pixmap/"+fileName.substring(3)+"/" +image.get("n"))));; pixmapDAO.setPixmap(am.get("pixmap/"+fileName.substring(3)+"/" +image.get("n"),Pixmap.class)); pixmapDAO.setRefx(image.getInt("refx")); pixmapDAO.setRefy(image.getInt("refy")); pixmapDAO.setName(image.get("n").replace(".png", "")); pixmapLists.add(pixmapDAO); } pixmapLists.check(); return pixmapLists; } //清除内存图片PixmapListDAO pixmapLists /*public void clearPixmapListByFileName(String fileName) { //1读取路径下说明文件 //2根据说明文件移除pixmapLists的内容,并depose XmlReader reader = ResConfig.reader; Element root = reader .parse(Gdx.files.internal("pixmap/"+fileName.substring(3)+"/" + fileName + ".xml")); // 每个图片添加的时候都要加使用场景,多场景用;分割screenid="1" Array<Element> images = root.getChildrenByNameRecursively("sprite"); for (Element image : images) { pixmapLists.remove(image.get("n").replace(".png", "")); } pixmapLists.check(); }*/ }
package com.zhfy.game.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 MapBinDAO(BTLDAO btlDao){ if(btlDao!=null) { mapVersion=1; mapWidth=Integer.parseInt(btlDao.getBm0().getBm0_13()); mapHeight=Integer.parseInt(btlDao.getBm0().getBm0_14()); MapBin=new ArrayList<MapBin>(); MapBin mapBin; for(BtlModule1 bm1:btlDao.getBm1()) { mapBin=new MapBin(); mapBin.setBlockType(Integer.parseInt(bm1.getBm1_1())); mapBin.setBackTile(Integer.parseInt(bm1.getBm1_2())); mapBin.setBackIdx(Integer.parseInt(bm1.getBm1_3())); mapBin.setBackRefX(Integer.parseInt(bm1.getBm1_4())); mapBin.setBackRefY(Integer.parseInt(bm1.getBm1_5())); mapBin.setWaterPass(Integer.parseInt(bm1.getBm1_6())); mapBin.setLandPass(Integer.parseInt(bm1.getBm1_7())); mapBin.setRegionId(Integer.parseInt(bm1.getBm1_8())); mapBin.setClimateId(Integer.parseInt(bm1.getBm1_9())); mapBin.setBuildId(Integer.parseInt(bm1.getBm1_10())); mapBin.setBuildLv(Integer.parseInt(bm1.getBm1_11())); mapBin.setFacility(Integer.parseInt(bm1.getBm1_12())); mapBin.setAreaId(Integer.parseInt(bm1.getBm1_13())); MapBin.add(mapBin); } } } 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> 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; } }
package com.zhfy.game.framework; import java.awt.Graphics; import java.awt.geom.Point2D; import java.io.DataOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; 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.files.FileHandle; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Blending; import com.badlogic.gdx.graphics.Pixmap.Filter; import com.badlogic.gdx.graphics.PixmapIO; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.utils.XmlReader; import com.zhfy.game.config.ResConfig; import com.zhfy.game.framework.tool.FileByte; import com.zhfy.game.model.content.MapBin; import com.zhfy.game.model.content.MapBinDAO; import com.zhfy.game.model.content.def.DefMap; import com.zhfy.game.model.content.def.DefPt; import com.zhfy.game.model.content.def.DefTerrainimg; import com.zhfy.game.model.framework.Coord; import com.zhfy.game.model.framework.PixmapDAO; import com.zhfy.game.model.framework.PixmapListDAO; public class GameMap { // 六边形地图绘制 全部static方法 public static void main(String[] args) throws Exception { // saveBinByWirteByte(fb,"123"); // MapBinDAO fb=apBin("123"); // saveMapBin(fb,"123"); } // 写为bin数组 @SuppressWarnings("unused") public static void saveMapBin(MapBinDAO binFile, String Path) { try { //FileOutputStream fs_out = new FileOutputStream(Path);//"D://test.bin" FileByte out=new FileByte(); out.writeShort(binFile.mapVersion);// 4 out.writeInt(binFile.mapWidth);// 8 out.writeInt(binFile.mapHeight);// 8 for (int i = 0; i < binFile.getMapbin().size(); i++) { out.writeByte(binFile.getMapbin().get(i).getBlockType());// 2 out.writeByte(binFile.getMapbin().get(i).getBackTile());// 2 out.writeByte(binFile.getMapbin().get(i).getBackIdx());// 2 out.writeByte(binFile.getMapbin().get(i).getBackRefX());// 2 out.writeByte(binFile.getMapbin().get(i).getBackRefY());// 2 out.writeByte(binFile.getMapbin().get(i).getForeTile());// 2 out.writeByte(binFile.getMapbin().get(i).getForeIdx());// 2 out.writeByte(binFile.getMapbin().get(i).getForeRefX());// 2 out.writeByte(binFile.getMapbin().get(i).getForeRefY());// 2 out.writeByte(binFile.getMapbin().get(i).getWaterPass());// 2 out.writeByte(binFile.getMapbin().get(i).getLandPass());// 2 out.writeInt(binFile.getMapbin().get(i).getRegionId());// 8 out.writeByte(binFile.getMapbin().get(i).getClimateId());// 2 out.writeByte(binFile.getMapbin().get(i).getBuildId());//2 out.writeByte(binFile.getMapbin().get(i).getBuildLv());//2 out.writeByte(binFile.getMapbin().get(i).getFacility());//2 out.writeShort(binFile.getMapbin().get(i).getAreaId());//4 } FileHandle file = Gdx.files.local(Path); file.writeBytes(out.getByte(), false); //out.writeInt(i);//8位 2147483647 //out.writeShort(i2);//4位 32769 //out.writeByte(i3);//2位 127 } catch (FileNotFoundException fe) { System.err.println(fe); } catch (IOException ioe) { System.err.println(ioe); } System.out.println("Ok"); } public static void saveMapBin2(MapBinDAO binFile, String Path) { try { FileOutputStream fs_out = new FileOutputStream(Path);//"D://test.bin" DataOutputStream out = new DataOutputStream(fs_out); out.writeShort(binFile.mapVersion);// 4 out.writeInt(binFile.mapWidth);// 8 out.writeInt(binFile.mapHeight);// 8 for (int i = 0; i < binFile.getMapbin().size(); i++) { out.writeByte(binFile.getMapbin().get(i).getBlockType());// 2 out.writeByte(binFile.getMapbin().get(i).getBackTile());// 2 out.writeByte(binFile.getMapbin().get(i).getBackIdx());// 2 out.writeByte(binFile.getMapbin().get(i).getBackRefX());// 2 out.writeByte(binFile.getMapbin().get(i).getBackRefY());// 2 out.writeByte(binFile.getMapbin().get(i).getForeTile());// 2 out.writeByte(binFile.getMapbin().get(i).getForeIdx());// 2 out.writeByte(binFile.getMapbin().get(i).getForeRefX());// 2 out.writeByte(binFile.getMapbin().get(i).getForeRefY());// 2 out.writeByte(binFile.getMapbin().get(i).getWaterPass());// 2 out.writeByte(binFile.getMapbin().get(i).getLandPass());// 2 out.writeInt(binFile.getMapbin().get(i).getRegionId());// 8 out.writeByte(binFile.getMapbin().get(i).getClimateId());// 2 } out.close(); //out.writeInt(i);//8位 2147483647 //out.writeShort(i2);//4位 32769 //out.writeByte(i3);//2位 127 // out.close(); } catch (FileNotFoundException fe) { System.err.println(fe); } catch (IOException ioe) { System.err.println(ioe); } System.out.println("Ok"); }/* */ // 循环遍历 在地块图上 是海洋和海岸的位置打窟窿,海岸使用id为2的抹除相应地形 public static Pixmap getLandByDAO(MapBinDAO mapBinDAO, Pixmap pixmap,PixmapListDAO pixmapLists, int mapx, int mapy,int mapw,int maph) { int x = 0; int y = 0; //int x_px_circle = 0; //int y_px_circle = 0; int x_px = 0; int y_px = 0; PixmapDAO shadowPixmap; Pixmap shadowTargetPixmap = new Pixmap(46, 40, Pixmap.Format.RGBA8888);; String shadowName; HashMap<String, String> terrainimgMap = new HashMap<String, String>(); //六边形四个角的坐标 int hexgaon_x1=0;//左上,左下 int hexgaon_x2=0;//右上,右下 int hexgaon_x3=0;//左中 int hexgaon_x4=0;//右中 int hexgaon_y1=0;//上 int hexgaon_y2=0;//中 int hexgaon_y3=0;//下 //TODO 随后增加对地图属性的解析 int beginIndex=0; int EndIndex=mapw*maph; int xC; int yC; Blending blend = pixmap.getBlending(); pixmap.setBlending(Blending.None); for (int id = beginIndex; id < EndIndex; id++) { x = (id % mapBinDAO.getMapWidth()) + 1; y = (id / mapBinDAO.getMapWidth()) + 1; //x_px_circle = (int) (((x - 1) * ResConfig.Map.GRID_WIDTH) * Config.Map.MAP_SCALE + Config.Map.HEXAGON_WIDTH * Config.Map.MAP_SCALE / 2); //y_px_circle = (int) ((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * Config.Map.MAP_SCALE + Config.Map.HEXAGON_HEIGHT * Config.Map.MAP_SCALE / 2); x_px = (int) ((x - 1) * ResConfig.Map.GRID_WIDTH* ResConfig.Map.MAP_SCALE); y_px = (int) (((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)* ResConfig.Map.MAP_SCALE); if (mapBinDAO.getMapbin().get(id).getBackTile() == 1 ) { // 这里填充圆,或四个三角形组合的六边形 // pixmap.fillCircle(x_px_circle, y_px_circle, (int) ((Config.Map.HEXAGON_WIDTH+12) * Config.Map.MAP_SCALE / 2)); //六个点 hexgaon_x1=(int) (((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE +35*ResConfig.Map.MAP_SCALE);//左上,左下 原来是36 hexgaon_x2=(int) (((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE +113*ResConfig.Map.MAP_SCALE);//右上,右下 ResConfig.Map.GRID_WIDTH hexgaon_x3=(int) (((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE-1);//左中 hexgaon_x4=(int) (((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_WIDTH * ResConfig.Map.MAP_SCALE );//右中 hexgaon_y1=(int) ((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * ResConfig.Map.MAP_SCALE -1);//上 hexgaon_y2=(int) ((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_HEIGHT * ResConfig.Map.MAP_SCALE / 2);//中 hexgaon_y3=(int) ((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_HEIGHT * ResConfig.Map.MAP_SCALE );//下 pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x1, hexgaon_y1, hexgaon_x2, hexgaon_y1); pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x2, hexgaon_y1, hexgaon_x4, hexgaon_y2); pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x2, hexgaon_y3, hexgaon_x4, hexgaon_y2); pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x1, hexgaon_y3, hexgaon_x2, hexgaon_y3); // Gdx.app.log("切除陆地", "id:" + id +" x:"+x+" y:"+ y+" // x_px:"+x_px+" y_px:"+ y_px); }else if(mapBinDAO.getMapbin().get(id).getBackTile() == 2) { //pixmap.setBlending(blend); shadowName=terrainimgMap.get(mapBinDAO.getMapbin().get(id).getBackTile() + "_" + mapBinDAO.getMapbin().get(id).getBackIdx()); if(shadowName!=null) { shadowPixmap = pixmapLists.getPixmapByName(shadowName); /* pixmap.drawPixmap(shadowPixmap.getPixmap(), 0, 0, (int)(shadowPixmap.getPixmap().getWidth()), (int)(shadowPixmap.getPixmap().getHeight()), x_px, y_px, (int) (shadowPixmap.getPixmap().getWidth() * Config.Map.MAP_SCALE), (int) (shadowPixmap.getPixmap().getHeight() * Config.Map.MAP_SCALE)); */ //Gdx.app.log("切除海岸边缘","shadowName:"+shadowName); /* TODO * 暂时未完成 *根据阴影的形状来切割掉像素,实现边界对齐 * */ //pixmap.setBlending(Blending.None); shadowTargetPixmap.drawPixmap(shadowPixmap.getPixmap(), 0, 0, (int)(shadowPixmap.getPixmap().getWidth()), (int)(shadowPixmap.getPixmap().getHeight()), 0, 0, (int) (shadowPixmap.getPixmap().getWidth() * ResConfig.Map.MAP_SCALE), (int) (shadowPixmap.getPixmap().getHeight() * ResConfig.Map.MAP_SCALE)); for ( xC=0; xC<(int) (shadowTargetPixmap.getWidth() ); xC++) { for ( yC=0; yC<(int) (shadowTargetPixmap.getHeight() ); yC++) { //int color = pixmap.getPixel(xC, yC); /*if(shadowPixmap.getPixmap().getPixel(xC, yC)>256&&shadowPixmap.getPixmap().getPixel(xC, yC)<66000){ pixmap.drawPixel(xC+x_px, yC+y_px, 0); }*/ /*if(shadowPixmap.getName().equals("coast_58")) { //Gdx.app.log("切除海岸边缘","color:"+shadowTargetPixmap.getPixel(xC, yC)+" x:"+xC+" y:"+yC); Gdx.app.log("",""+shadowTargetPixmap.getPixel(xC, yC)); }*/ if(shadowTargetPixmap.getPixel(xC, yC)==65535||shadowTargetPixmap.getPixel(xC, yC)==65022){ pixmap.drawPixel(xC+x_px, yC+y_px,0); Gdx.app.log("切除海岸边缘","color:"+shadowPixmap.getPixmap().getPixel(xC, yC)+" x:"+xC+" y:"+yC); }/*else { Gdx.app.log("切除海岸边缘","color:"+pixmap.getPixel(xC, yC)+" x:"+xC+" y:"+yC); }*/ } } } } } // 把blending设置回来 pixmap.setBlending(blend); return pixmap; } // 通过dao绘制图片 // pixmap要绘制的目标图片 // pixmapLists使用图片 // defTerrainimgs图片说明文件 public static Pixmap getPixmapByDao(MapBinDAO mapBinDAO, Pixmap pixmap, PixmapListDAO pixmapLists, List<DefTerrainimg> defTerrainimgs, int beginIndex, int EndIndex,float scale) { // 解析dao if (mapBinDAO.getMapbin() != null) { int x = 0; int y = 0; int x_px = 0; int y_px = 0; HashMap<String, String> terrainimgMap = new HashMap<String, String>(); // 将要取得的图片的id和名字放入位置 for (DefTerrainimg defTerrainimg : defTerrainimgs) { terrainimgMap.put(defTerrainimg.getId() + "_" + defTerrainimg.getIdx(), defTerrainimg.getImage()); } String imgBack; String imgFore; PixmapDAO backPixmap; PixmapDAO forePixmap; int refSize=0;//对水面大小补位,否则可能有空缺 //Pixmap.Filter filter; // 单线程绘制图片 for (int id = beginIndex; id < EndIndex; id++) { x = (id % mapBinDAO.getMapWidth()) + 1; y = (id / mapBinDAO.getMapWidth()) + 1; // x_px=(int) ((x-1)*139.5); // y_px=(int) ((x&1) == 1?(y-1)*161:(y-1)*161+80.5); x_px = (int) ((x - 1) * ResConfig.Map.GRID_WIDTH); y_px = (int) (((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)); //Gdx.app.log("地图开始构建", "mapId:" + id + " x:" + x + " y:" + y); if (mapBinDAO.getMapbin().get(id).getBackTile() != 0 /*&& mapBinDAO.getMapbin().get(id).getBackTile() != 1*/) { if(mapBinDAO.getMapbin().get(id).getBackTile() == 1&&scale<0.5f){ refSize=1; }else{ refSize=0; } // 获取该位置要画的地形 z imgBack = terrainimgMap.get(mapBinDAO.getMapbin().get(id).getBackTile() + "_" + mapBinDAO.getMapbin().get(id).getBackIdx()); if (imgBack == null) { //Gdx.app.log("地图层1未找到", mapBinDAO.getMapbin().get(id).getBackTile() + "_" + mapBinDAO.getMapbin().get(id).getBackIdx()); imgBack = terrainimgMap.get(mapBinDAO.getMapbin().get(id).getBackTile() + "_"+ComUtil.getRandom(1,4)); } // 获取图像并绘制到上面 backPixmap = pixmapLists.getPixmapByName(imgBack); if (backPixmap != null) { pixmap.drawPixmap (backPixmap.getPixmap(), 0, 0, backPixmap.getPixmap().getWidth(), backPixmap.getPixmap().getHeight(), (int) (scale*((x_px + mapBinDAO.getMapbin().get(id).getBackRefX()+backPixmap.getRefx()) * ResConfig.Map.MAP_SCALE))-refSize*2, (int) (scale*((y_px + mapBinDAO.getMapbin().get(id).getBackRefY()+backPixmap.getRefy()) * ResConfig.Map.MAP_SCALE))-refSize*2, (int) (scale*backPixmap.getPixmap().getWidth() * ResConfig.Map.MAP_SCALE)+refSize*3, (int) (scale*backPixmap.getPixmap().getHeight() * ResConfig.Map.MAP_SCALE)+refSize*3); //Gdx.app.log("地图层1构建成功", " backid:" + mapBinDAO.getMapbin().get(id).getBackTile() + "_" + mapBinDAO.getMapbin().get(id).getBackIdx() + "img:" + imgBack); } /* * else { Gdx.app.log("地图层1构建失败", " backid:" + * mapBinDAO.getMapbin().get(id).getBackTile() + "_" + * mapBinDAO.getMapbin().get(id).getBackIdx()); } */ } /* * else { Gdx.app.log("地图层1忽略构建", ""); } */ // 忽略底图和海洋 if (mapBinDAO.getMapbin().get(id).getForeTile() != 0 && mapBinDAO.getMapbin().get(id).getForeTile() != 1) { imgFore = terrainimgMap.get(mapBinDAO.getMapbin().get(id).getForeTile() + "_" + mapBinDAO.getMapbin().get(id).getForeIdx()); if (imgFore == null) { Gdx.app.log("地图层2未找到",mapBinDAO.getMapbin().get(id).getForeTile() + "_" + mapBinDAO.getMapbin().get(id).getForeIdx()); imgFore = terrainimgMap.get(mapBinDAO.getMapbin().get(id).getForeTile() + "_1"); } forePixmap = pixmapLists.getPixmapByName(imgFore); if (forePixmap != null) { pixmap.drawPixmap (forePixmap.getPixmap(), 0, 0, forePixmap.getPixmap().getWidth(), forePixmap.getPixmap().getHeight(), (int) (scale*((x_px + mapBinDAO.getMapbin().get(id).getForeRefX()+forePixmap.getRefx()) * ResConfig.Map.MAP_SCALE)), (int) (scale*((y_px + mapBinDAO.getMapbin().get(id).getForeRefY()+forePixmap.getRefy()) * ResConfig.Map.MAP_SCALE)), (int) (scale*forePixmap.getPixmap().getWidth() * ResConfig.Map.MAP_SCALE), (int) (scale*forePixmap.getPixmap().getHeight() * ResConfig.Map.MAP_SCALE)); } /* * else { Gdx.app.log("地图层2构建成功", " backid:" + * mapBinDAO.getMapbin().get(id).getForeTile() + "_" + * mapBinDAO.getMapbin().get(id).getForeIdx()); } */ } /* * else { Gdx.app.log("地图层2", "忽略构建"); } */ } Gdx.app.log("地图构建", "完成"); // PixmapIO.writePNG(Gdx.files.external("texture_world.png"), pixmap); return pixmap; } else { Gdx.app.log("地图构建", "失败"); return null; } } //绘制颜色区块图 public static Pixmap getPixmapByDaoForColor(MapBinDAO mapBinDAO, Pixmap pixmap,float scale,List<Integer> coastGrid) { // 解析dao if (mapBinDAO.getMapbin() != null) { int x = 0; int y = 0; int x_px_circle = 0; int y_px_circle = 0; int hexgaon_x1; int hexgaon_x2; int hexgaon_x3; int hexgaon_x4; int hexgaon_y1; int hexgaon_y2; int hexgaon_y3; //沿海地块用圆形来填充 //List<Integer> coastGrid=mapBinDAO.getIdsByAround(12); int color; int nextRegionId=0; //先绘制海岸 //沿海地块用圆形来填充 pixmap.setBlending(Blending.None); for(int id:coastGrid) { if(mapBinDAO.getMapbin().get(id).getBlockType()!=1&&mapBinDAO.getMapbin().get(id).getRegionId()!=0){ x = (id % mapBinDAO.getMapWidth()) + 1; y = (id / mapBinDAO.getMapWidth()) + 1; x_px_circle = (int) (scale*(((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_WIDTH * ResConfig.Map.MAP_SCALE / 2)); y_px_circle = (int) (scale*((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_HEIGHT * ResConfig.Map.MAP_SCALE / 2)); //Gdx.app.log("海陆绘制圆", "" + id); //沿海地块用圆形来填充 if (mapBinDAO.getMapbin().get(id).getRegionId() != nextRegionId) { color = GameUtil.getColorByNum(mapBinDAO.getMapbin().get(id).getRegionId()); //获取颜色 pixmap.setColor(color); nextRegionId = mapBinDAO.getMapbin().get(id).getRegionId(); //Gdx.app.log("setColor","id:"+id+" color:"+color); } pixmap.fillCircle(x_px_circle, y_px_circle, (int) ((ResConfig.Map.HEXAGON_WIDTH + 13) * ResConfig.Map.MAP_SCALE / 2*scale)); } } // 单线程绘制所有图片 for (int id = 0; id < mapBinDAO.getMapbin().size(); id++) { x = (id % mapBinDAO.getMapWidth()) + 1; y = (id / mapBinDAO.getMapWidth()) + 1; hexgaon_x1=(int) (scale*(((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE +35*ResConfig.Map.MAP_SCALE));//左上,左下 原来是36 hexgaon_x2=(int) (scale*(((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE +113*ResConfig.Map.MAP_SCALE));//右上,右下 ResConfig.Map.GRID_WIDTH hexgaon_x3=(int) (scale*(((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE-1));//左中 hexgaon_x4=(int) (scale*(((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_WIDTH * ResConfig.Map.MAP_SCALE ));//右中 hexgaon_y1=(int) (scale*((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * ResConfig.Map.MAP_SCALE -1));//上 hexgaon_y2=(int) (scale*((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_HEIGHT * ResConfig.Map.MAP_SCALE / 2));//中 hexgaon_y3=(int) (scale*((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_HEIGHT * ResConfig.Map.MAP_SCALE ));//下 if (mapBinDAO.getMapbin().get(id).getRegionId() != nextRegionId) { color = GameUtil.getColorByNum(mapBinDAO.getMapbin().get(id).getRegionId()); //获取颜色 pixmap.setColor(color); nextRegionId = mapBinDAO.getMapbin().get(id).getRegionId(); //Gdx.app.log("setColor","id:"+id+" color:"+color); } //Gdx.app.log("地图开始构建", "mapId:" + id + " x:" + x + " y:" + y); if (mapBinDAO.getMapbin().get(id).getBlockType()!=1&&mapBinDAO.getMapbin().get(id).getRegionId()!=0) { pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x1, hexgaon_y1, hexgaon_x2, hexgaon_y1); pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x2, hexgaon_y1, hexgaon_x4, hexgaon_y2); pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x2, hexgaon_y3, hexgaon_x4, hexgaon_y2); pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x1, hexgaon_y3, hexgaon_x2, hexgaon_y3); } } Gdx.app.log("色图构建", "完成"); // PixmapIO.writePNG(Gdx.files.external("texture_world.png"), pixmap); return pixmap; } else { Gdx.app.log("色图构建", "失败"); return null; } } //修改region的颜色 public static Pixmap updateColorByRegion(MapBinDAO mapBinDAO, Pixmap pixmap,float scale,int regionId,int color,List<Integer> coastGrid){ //待绘制地块 List<Integer> ids=mapBinDAO.getIdsByRegionId(regionId); if (mapBinDAO.getMapbin() != null&&ids.size()>0) { pixmap.setColor(color); int x = 0; int y = 0; int x_px_circle = 0; int y_px_circle = 0; int hexgaon_x1; int hexgaon_x2; int hexgaon_x3; int hexgaon_x4; int hexgaon_y1; int hexgaon_y2; int hexgaon_y3; //先绘制海岸 //沿海地块用圆形来填充 pixmap.setBlending(Blending.None); for(int id:ids) { if(mapBinDAO.getMapbin().get(id).getBlockType()!=1&&mapBinDAO.getMapbin().get(id).getRegionId()!=0 &&coastGrid.contains(id)){ x = (id % mapBinDAO.getMapWidth()) + 1; y = (id / mapBinDAO.getMapWidth()) + 1; x_px_circle = (int) (scale*(((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_WIDTH * ResConfig.Map.MAP_SCALE / 2)); y_px_circle = (int) (scale*((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_HEIGHT * ResConfig.Map.MAP_SCALE / 2)); //Gdx.app.log("海陆绘制圆", "" + id); //沿海地块用圆形来填充 pixmap.fillCircle(x_px_circle, y_px_circle, (int) ((ResConfig.Map.HEXAGON_WIDTH + 13) * ResConfig.Map.MAP_SCALE / 2*scale)); } } // 单线程绘制所有图片 for (int id:ids) { x = (id % mapBinDAO.getMapWidth()) + 1; y = (id / mapBinDAO.getMapWidth()) + 1; hexgaon_x1=(int) (scale*(((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE +35*ResConfig.Map.MAP_SCALE));//左上,左下 原来是36 hexgaon_x2=(int) (scale*(((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE +113*ResConfig.Map.MAP_SCALE));//右上,右下 ResConfig.Map.GRID_WIDTH hexgaon_x3=(int) (scale*(((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE-1));//左中 hexgaon_x4=(int) (scale*(((x - 1) * ResConfig.Map.GRID_WIDTH) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_WIDTH * ResConfig.Map.MAP_SCALE ));//右中 hexgaon_y1=(int) (scale*((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * ResConfig.Map.MAP_SCALE -1));//上 hexgaon_y2=(int) (scale*((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_HEIGHT * ResConfig.Map.MAP_SCALE / 2));//中 hexgaon_y3=(int) (scale*((((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)) * ResConfig.Map.MAP_SCALE + ResConfig.Map.HEXAGON_HEIGHT * ResConfig.Map.MAP_SCALE ));//下 //Gdx.app.log("地图开始构建", "mapId:" + id + " x:" + x + " y:" + y); if (mapBinDAO.getMapbin().get(id).getBlockType()!=1&&mapBinDAO.getMapbin().get(id).getRegionId()!=0) { pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x1, hexgaon_y1, hexgaon_x2, hexgaon_y1); pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x2, hexgaon_y1, hexgaon_x4, hexgaon_y2); pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x2, hexgaon_y3, hexgaon_x4, hexgaon_y2); pixmap.fillTriangle(hexgaon_x3, hexgaon_y2, hexgaon_x1, hexgaon_y3, hexgaon_x2, hexgaon_y3); } } Gdx.app.log("色图构建", "完成"+" regionId:"+regionId+" color:"+color); //PixmapIO.writePNG(Gdx.files.external("updateColor_"+regionId+".png"), pixmap); return pixmap; } else { Gdx.app.log("色图构建", "失败"); return pixmap; } } // 绘制分区图片 512*512 // pixmap要绘制的目标图片 // pixmapLists使用图片 // defTerrainimgs图片说明文件 //beginX,beginY绘制的起始坐标 public static Pixmap getPixmapForArea(MapBinDAO mapBinDAO, Pixmap pixmap, PixmapListDAO pixmapLists, List<DefTerrainimg> defTerrainimgs, int beginX, int beginY) { int areaW=ResConfig.Map.PT_GRID_WIDTH; int areaH=ResConfig.Map.PT_GRID_HEIGHT+1; beginX=beginX+1; beginY=beginY+1; int mapRefX=0; int mapRefXPx=0; //如果beginX不是1,则要从这个开始的再开始绘制 if(beginX>1) { mapRefX=-1; mapRefXPx=(int) ((beginX-1)*ResConfig.Atlas.PT_SIDE % (ResConfig.Map.GRID_WIDTH*ResConfig.Map.MAP_SCALE)/ResConfig.Map.MAP_SCALE); }/**/ int areaSum=areaW*areaH; int mapW=mapBinDAO.mapWidth; //区域偏移量 // 解析dao if (mapBinDAO.getMapbin() != null) { int x = 0; int y = 0; int x_px = 0; int y_px = 0; HashMap<String, String> terrainimgMap = new HashMap<String, String>(); // 将要取得的图片的id和名字放入位置 for (DefTerrainimg defTerrainimg : defTerrainimgs) { terrainimgMap.put(defTerrainimg.getId() + "_" + defTerrainimg.getIdx(), defTerrainimg.getImage()); } String imgBack; String imgFore; PixmapDAO backPixmap; PixmapDAO forePixmap; int id; // 单线程绘制图片 for (int i = 0; i < areaSum; i++) { x = (i % areaW) + 1; y = (i / areaW) + 1; //判断是否跨行 if(((beginX-1)*areaW+x-1)<mapW) { id=((beginX-1)*areaW+x-1+mapRefX)+((beginY-1)*(areaH)+y-1)*mapW;//计算当前绘制的id }else { id=((beginX-1)*areaW+x-1+mapRefX)+((beginY-1)*(areaH)+y-1)*mapW-mapW; } x_px = (int) ((x - 1) * ResConfig.Map.GRID_WIDTH)-mapRefXPx; y_px = (int) (((id & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT+ ResConfig.Map.HEXAGON_HEIGHT_REF : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT )); /*if(beginX==2&&beginY==1) { Gdx.app.log("测试:", "id:"+id+" x:"+x+" y:"+y+" x_px:"+x_px+" y_px:"+y_px); }*/ if(id>=mapBinDAO.getMapbin().size()) { break; } if (mapBinDAO.getMapbin().get(id).getBackTile() != 0 /*&& mapBinDAO.getMapbin().get(id).getBackTile() != 1*/) { //Gdx.app.log("地图开始构建", "mapId:" + id + " x:" + x + " y:" + y); // 获取该位置要画的地形 z imgBack = terrainimgMap.get(mapBinDAO.getMapbin().get(id).getBackTile() + "_" + mapBinDAO.getMapbin().get(id).getBackIdx()); if (imgBack == null) { //Gdx.app.log("地图层1未找到", mapBinDAO.getMapbin().get(id).getBackTile() + "_" + mapBinDAO.getMapbin().get(id).getBackIdx()); imgBack = terrainimgMap.get(mapBinDAO.getMapbin().get(id).getBackTile() + "_"+ComUtil.getRandom(1,4)); } // 获取图像并绘制到上面 backPixmap = pixmapLists.getPixmapByName(imgBack); if (backPixmap != null) { pixmap.drawPixmap(backPixmap.getPixmap(), 0, 0, backPixmap.getPixmap().getWidth(), backPixmap.getPixmap().getHeight(), (int) ((x_px + mapBinDAO.getMapbin().get(id).getBackRefX()) * ResConfig.Map.MAP_SCALE), (int) ((y_px + mapBinDAO.getMapbin().get(id).getBackRefY()) * ResConfig.Map.MAP_SCALE), (int) (backPixmap.getPixmap().getWidth() * ResConfig.Map.MAP_SCALE), (int) (backPixmap.getPixmap().getHeight() * ResConfig.Map.MAP_SCALE)); } } // 忽略底图和海洋 if (mapBinDAO.getMapbin().get(id).getForeTile() != 0 && mapBinDAO.getMapbin().get(id).getForeTile() != 1) { imgFore = terrainimgMap.get(mapBinDAO.getMapbin().get(id).getForeTile() + "_" + mapBinDAO.getMapbin().get(id).getForeIdx()); if (imgFore == null) { Gdx.app.log("地图层2未找到",mapBinDAO.getMapbin().get(id).getForeTile() + "_" + mapBinDAO.getMapbin().get(id).getForeIdx()); imgFore = terrainimgMap.get(mapBinDAO.getMapbin().get(id).getForeTile() + "_1"); } forePixmap = pixmapLists.getPixmapByName(imgFore); if (forePixmap != null) { pixmap.drawPixmap(forePixmap.getPixmap(), x_px + mapBinDAO.getMapbin().get(id).getForeRefX(), y_px + mapBinDAO.getMapbin().get(id).getForeRefY(), 0, 0, forePixmap.getPixmap().getWidth(), forePixmap.getPixmap().getHeight()); } } } /*if(beginX==2&&beginY==1) { PixmapIO.writePNG(Gdx.files.external("texture_"+beginY+"."+beginX+".png"), pixmap); }*/ //PixmapIO.writePNG(Gdx.files.external("texture_"+beginY+"."+beginX+".png"), pixmap); Gdx.app.log("地图构建", "完成"); return pixmap; } else { Gdx.app.log("地图构建", "失败"); return null; } } // 读取地图 保存位置编号 public static MapBinDAO saveBin(byte[] bt) throws IOException { MapBinDAO fs = new MapBinDAO(null); List<MapBin> mps = new ArrayList<MapBin>(); /* * //TODO根据Index获取保存位置 * * //定位bin位置 byte[] bt = GameUtils.readFile("D:\\test1.bin"); */ // 新建对象 StringBuilder buf = new StringBuilder(); int line = 0;// 十六进制标记 for (byte d : bt) { if (line % 1 == 0) { buf.append(String.format("%02x", d)); // System.out.println(String.format("%02x", d)); // buf.append(",") ; line++; } } // 解析并赋值 int bufTag = 0; // System.out.println(buf.substring(bufTag, bufTag+4)); fs.setMapVersion(Integer.parseInt(buf.substring(bufTag, bufTag + 4), 16)); bufTag = bufTag + 4; // System.out.println(buf.substring(bufTag, bufTag+8)); int width = Integer.parseInt(buf.substring(bufTag, bufTag + 8), 16); bufTag = bufTag + 8; // System.out.println(buf.substring(bufTag, bufTag+8)); int height = Integer.parseInt(buf.substring(bufTag, bufTag + 8), 16); bufTag = bufTag + 8; fs.setMapWidth(width); fs.setMapHeight(height); int totalCount = width * height; // System.out.println(fs.mapVersion); // System.out.println(width); // System.out.println(height); // System.out.println(totalCount); for (int i = 0; i < totalCount; i++) { MapBin mp = new MapBin(); mp.setBlockType(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setBackTile(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setBackIdx(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setBackRefX(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setBackRefY(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setForeTile(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setForeIdx(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setForeRefX(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setForeRefY(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setWaterPass(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setLandPass(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setRegionId(Integer.parseInt(buf.substring(bufTag, bufTag + 8), 16)); bufTag = bufTag + 8; mp.setClimateId(Integer.parseInt(buf.substring(bufTag, bufTag + 2), 16)); bufTag = bufTag + 2; mp.setBuildId(Integer.parseInt(buf.substring(bufTag, bufTag+2),16)); bufTag=bufTag+2; mp.setBuildLv(Integer.parseInt(buf.substring(bufTag, bufTag+2),16)); bufTag=bufTag+2; mp.setFacility(Integer.parseInt(buf.substring(bufTag, bufTag+2),16)); bufTag=bufTag+2; mp.setAreaId(Integer.parseInt(buf.substring(bufTag, bufTag+4),16)); bufTag=bufTag+4; mps.add(mp); } fs.setMapbin(mps); return fs; } public static int getWidth(int w) { return (int) ((148 + ResConfig.Map.GRID_WIDTH * (w - 1))); } public static int getHeight(int h) { return (int) ((192 + ResConfig.Map.HEXAGON_HEIGHT * (h - 1))); } // 六边形网格定位 // @param xPos 输入,所需查询的点的x坐标 // @param yPos 输入,所需查询的点的y坐标 // @param cell_x 输出,改点所在网格的x坐标 // @param cell_y 输出,改点所在网格的y坐标 public static Coord getHotCell(float xPos, float yPos,float zoom) { float GRID_WIDTH = ResConfig.Map.GRID_WIDTH;// (CELL_BORDER*1.5f) float GRID_HEIGHT =ResConfig.Map.HEXAGON_HEIGHT;// (CELL_BORDER*0.8660254f) float Grid_BORDER=GRID_WIDTH/1.5f; int cell_y; int cell_x; xPos=xPos/ResConfig.Map.MAP_SCALE; yPos=yPos/ResConfig.Map.MAP_SCALE; cell_x = (int) (xPos / GRID_WIDTH); float x = xPos - cell_x * GRID_WIDTH; cell_y = (int) (yPos / GRID_HEIGHT); float y = yPos - cell_y * GRID_HEIGHT; //if(! (Grid_BORDER-Math.abs((x-1/2*GRID_WIDTH))>Math.abs(y-1/2*GRID_HEIGHT)/Math.sqrt(3))) { if(! (Math.abs(GRID_WIDTH/2-x)+Math.abs(GRID_HEIGHT/2-y)/Math.sqrt(3)<=Grid_BORDER*Math.sqrt(3))) { //不在六边形内部 if(x>GRID_WIDTH/2) { //在右边 cell_x++; } } /*if( cell_x % 2==1 && y<64) { cell_y--; } if((cell_x&1)!=1&& y>64) { cell_y=cell_y-1; } if(cell_y<0) { cell_y=0; }*/ Coord coord = new Coord(cell_x, cell_y); return coord; } // 六边形网格定位 // @param xPos 输入,所需查询的点的x坐标 // @param yPos 输入,所需查询的点的y坐标,y必须转换,因为以左上开始计算 // @param cell_x 输出,改点所在网格的x坐标 // @param cell_y 输出,改点所在网格的y坐标 public static Coord getHotCell2(float xPos, float yPos) { float GRID_WIDTH =ResConfig.Map.GRID_WIDTH; float GRID_HEIGHT =ResConfig.Map.HEXAGON_HEIGHT;// (CELL_BORDER*0.8660254f) float GRID_W_B=(GRID_WIDTH/4);//宽-变成/2 即小长 int cell_y; int cell_x; float vertex_x_px; float vertex_y_px; xPos=xPos/ResConfig.Map.MAP_SCALE;//不知道为什么会出现偏移,所以通过这里来减少偏移 yPos=yPos/ResConfig.Map.MAP_SCALE; cell_x = (int) (xPos / GRID_WIDTH); float x = Math.abs(xPos - cell_x * GRID_WIDTH); cell_y = (int) (yPos / GRID_HEIGHT); float y = Math.abs(yPos - cell_y * GRID_HEIGHT); //先判断位置 if(x<GRID_W_B) { if(y<GRID_HEIGHT/2) { //在上 if(x/Math.tan(60)<y) { cell_x++; } }else { //在下 if(x/Math.tan(60)<(y-GRID_HEIGHT/2)) { cell_x++; } } //右边 }/**/ if( cell_x % 2==0 && y<64) { cell_y--; }else if(cell_x % 2!=0){ cell_y--; } /*if((cell_x&1)!=1&& y>64) { cell_y=cell_y-1; } if(cell_y<0) { cell_y=0; }*/ vertex_x_px=cell_x*GRID_WIDTH*ResConfig.Map.MAP_SCALE; vertex_y_px=cell_x%2!=0?(cell_y+1)*GRID_HEIGHT*ResConfig.Map.MAP_SCALE:(cell_y+0.5f)*GRID_HEIGHT*ResConfig.Map.MAP_SCALE; Coord coord = new Coord(-cell_x, cell_y-1,vertex_x_px,vertex_y_px); return coord; } // TODO // 横六边形地图类 class hexagonMap { private int w; private int h; private float w_px;// 单个像素长度 private float h_px;// 单个像素宽度 private float sum_w_px; private float sum_h_px; } //画六边形网格 public static Pixmap drawHexagonGrid(Pixmap pixmap, MapBinDAO mapBinDAO)// 画网格 { // 加载边框 int x = 0; int y = 0; int x_px = 0; int y_px = 0; // 将要取得的图片的id和名字放入位置 Pixmap gridPixmap = new Pixmap(Gdx.files.internal("pixmap/tiles/grid.png")); // 绘制网格图片 for (int id = 0; id < mapBinDAO.getMapbin().size(); id++) { x = (id % mapBinDAO.getMapWidth()) + 1; y = (id / mapBinDAO.getMapWidth()) + 1; // x_px=(int) ((x-1)*139.5); // y_px=(int) ((x&1) == 1?(y-1)*161:(y-1)*161+80.5); x_px = (int) ((x - 1) * ResConfig.Map.GRID_WIDTH); y_px = (int) (((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)); // Gdx.app.log("绘制地图网格", "mapId:" + id + " x:" + x + " y:" + y); pixmap.drawPixmap(gridPixmap, 0, 0, gridPixmap.getWidth(), gridPixmap.getHeight(), (int) ((x_px + mapBinDAO.getMapbin().get(id).getBackRefX()) * ResConfig.Map.MAP_SCALE), (int) ((y_px + mapBinDAO.getMapbin().get(id).getBackRefY()) * ResConfig.Map.MAP_SCALE), (int) (gridPixmap.getWidth() * ResConfig.Map.MAP_SCALE), (int) (gridPixmap.getHeight() * ResConfig.Map.MAP_SCALE)); } // 清除边框 gridPixmap.dispose(); return pixmap; } //画六边形网格 public static Pixmap drawHexagonGridByView(Pixmap pixmap,AssetManager am)// 画网格 { // 加载边框 int x = 0; int y = 0; int x_px = 0; int y_px = 0; // 将要取得的图片的id和名字放入位置 //Pixmap gridPixmap = new Pixmap(Gdx.files.internal("pixmap/tiles/grid.png")); Pixmap gridPixmap = am.get(("pixmap/tiles/grid.png"),Pixmap.class); int w=(int)(pixmap.getWidth()/ResConfig.Map.GRID_WIDTH/ResConfig.Map.MAP_SCALE)+3; int h=(int)(pixmap.getHeight()/ResConfig.Map.HEXAGON_HEIGHT/ResConfig.Map.MAP_SCALE)+3; int size=w*h; // 绘制网格图片 for (int id = 0; id < size; id++) { x = (id % w) + 1; y = (id / w) + 1; // x_px=(int) ((x-1)*139.5); // y_px=(int) ((x&1) == 1?(y-1)*161:(y-1)*161+80.5); x_px = (int) ((x - 1) * ResConfig.Map.GRID_WIDTH); y_px = (int) (((x & 1) == 1 ? (y - 1) * ResConfig.Map.HEXAGON_HEIGHT : (y - 1) * ResConfig.Map.HEXAGON_HEIGHT + ResConfig.Map.HEXAGON_HEIGHT_REF)); //Gdx.app.log("绘制地图网格", "mapId:" + id + " x:" + x + " y:" + y+ " x_px:" + x_px + " y_px:" + y_px); pixmap.drawPixmap(gridPixmap, 0, 0, gridPixmap.getWidth(), gridPixmap.getHeight(), (int) ((x_px)* ResConfig.Map.MAP_SCALE), (int) ((y_px) * ResConfig.Map.MAP_SCALE), (int) (gridPixmap.getWidth() * ResConfig.Map.MAP_SCALE), (int) (gridPixmap.getHeight() * ResConfig.Map.MAP_SCALE)); } // 清除边框 //gridPixmap.dispose(); return pixmap; } // Pixmap大小计算 // w=186+139.5*(x-1) h=242+161*(y-1) // int w = (int) (186 + 139.5 * (defMap.getWidth() - 1)); // int h = 242 + 161 * (defMap.getHeight() - 1); // int w = (int) ((148 + ResConfig.Map.GRID_WIDTH * (defMap.getWidth() - 1))); // int h = (int) ((191 + ResConfig.Map.HEXAGON_HEIGHT * (defMap.getHeight() - 1))); public static Pixmap createPixmapByDefMap(DefMap defMap) { int w = GameMap.getWidth(defMap.getWidth()); int h = GameMap.getHeight(defMap.getHeight()); int sum = defMap.getWidth() * defMap.getHeight(); /* * if(sum>10000) { scale=(float) (((int)(10-(sum-10000)*0.0001))*0.06); * } */ w = (int) (w * ResConfig.Map.MAP_SCALE); h = (int) (h * ResConfig.Map.MAP_SCALE); //Gdx.app.log("地图大小", "sum:" + sum + " w:" + defMap.getWidth() + " h:" + defMap.getHeight()); //Gdx.app.log("地图图片大小", "缩放比例:" + Config.Map.MAP_SCALE + " w_px:" + w + " h_px:" + h); return new Pixmap(w, h, Pixmap.Format.RGBA8888); } public static Pixmap createPixmap(int mapW,int mapH) { int w = GameMap.getWidth(mapW); int h = GameMap.getHeight(mapH); int sum = w * h; /* * if(sum>10000) { scale=(float) (((int)(10-(sum-10000)*0.0001))*0.06); * } */ w = (int) (w * ResConfig.Map.MAP_SCALE); h = (int) (h * ResConfig.Map.MAP_SCALE); //Gdx.app.log("地图大小", "sum:" + sum + " w:" + defMap.getWidth() + " h:" + defMap.getHeight()); //Gdx.app.log("地图图片大小", "缩放比例:" + Config.Map.MAP_SCALE + " w_px:" + w + " h_px:" + h); return new Pixmap(w, h, Pixmap.Format.RGBA8888); } //创建一个当前窗口大小的画布 public static Pixmap createPixmapByView(float vw,float vh) { int w = (int)vw; int h = (int)vh; //Gdx.app.log("海洋地图:"," w:" + w + " h:" +h); return new Pixmap(w, h, Pixmap.Format.RGBA8888); } // 使用前必须初始化 pixmap // ptId-->type -1固定 1海洋 0底图通用 2沙漠 3雪地 4草地 5泥地 6外星 7热带草地 public static Pixmap coverImgByPtimgId(Pixmap pixmap, int ptId) { // 通过配置文件获取读取的pt DefPt defPt = new DefPt(); List<DefPt> defPts = new ArrayList<DefPt>(); try { defPts = GameUtil.getDaoListByClass(defPt, "config/def_pt.xml"); } catch (Exception e) { e.printStackTrace(); } String imgPtStr = null; for (int i = 0; i < defPts.size(); i++) { if (defPts.get(i).getId() == ptId) { imgPtStr = defPts.get(i).getImage(); break; } } if (imgPtStr != null && pixmap != null) { // 获取图片资源 Pixmap imgPt = new Pixmap(Gdx.files.internal("pixmap/pts/" + imgPtStr)); // 获取目标长宽,并循环绘制 int w = (int) ((pixmap.getWidth() / imgPt.getWidth()) + 1); int h = (int) ((pixmap.getHeight() / imgPt.getHeight()) + 1); int x = 0; int y = 0; int x_px; int y_px; int coverCount = w * h; // Gdx.app.log("地图底图开始构建", "w:" + w + " h:" + h ); for (int i = 0; i < coverCount; i++) { x = i % w; y = (int) (i / w); x_px = x * imgPt.getWidth(); y_px = y * imgPt.getHeight(); Gdx.app.log("地图底图开始构建", " id:" + i + " x:" + x + " y:" + y+ "x_px:" + x_px + " y_px:" + y_px); pixmap.drawPixmap(imgPt, x_px, y_px, 0, 0, imgPt.getWidth(), imgPt.getHeight()); } /*if(ptId==1){ int color = pixmap.getPixel(12, 12); //pixmap.drawPixel(xC, yC, color); Gdx.app.log("海色","color:"+color); }*/ // 清除资源 imgPt.dispose(); } return pixmap; } //获得地形装饰的最高上限,最低下限为0 //储存方式为 Map(id_type+"_min",idx_min) Map(id_type+"_max",idx_max) public static Map getDecorateRandMaxMap() { DefTerrainimg defTerrainimg = new DefTerrainimg(); List<DefTerrainimg> defTerrainimgs = new ArrayList<DefTerrainimg>(); try { defTerrainimgs = GameUtil.getDaoListByClass(defTerrainimg, "config/def_terrainimg.xml"); } catch (Exception e) { e.printStackTrace(); } int i,iLength; iLength=defTerrainimgs.size(); Map map=new HashMap(); for(i=0;i<iLength;i++) {//省略掉类型为-1的值 if(defTerrainimgs.get(i).getType()==-1) { } else if(!map.containsKey((defTerrainimgs.get(i).getId()+"_"+defTerrainimgs.get(i).getType()+"_min"))) { map.put(defTerrainimgs.get(i).getId()+"_"+defTerrainimgs.get(i).getType()+"_min", defTerrainimgs.get(i).getIdx()); } else if(!map.containsKey((defTerrainimgs.get(i).getId()+"_"+defTerrainimgs.get(i).getType()+"_max"))) { map.put(defTerrainimgs.get(i).getId()+"_"+defTerrainimgs.get(i).getType()+"_max", defTerrainimgs.get(i).getIdx()); }else if((Integer)map.get(defTerrainimgs.get(i).getId()+"_"+defTerrainimgs.get(i).getType()+"_min")>defTerrainimgs.get(i).getIdx() ) { map.put(defTerrainimgs.get(i).getId()+"_"+defTerrainimgs.get(i).getType()+"_min", defTerrainimgs.get(i).getIdx()); }else if((Integer)map.get(defTerrainimgs.get(i).getId()+"_"+defTerrainimgs.get(i).getType()+"_max")<defTerrainimgs.get(i).getIdx() ) { map.put(defTerrainimgs.get(i).getId()+"_"+defTerrainimgs.get(i).getType()+"_max", defTerrainimgs.get(i).getIdx()); } } return map; } //添加周围的id坐标 public static List<Coord> addCoordByIds(List<Integer> aroundIds,int w){ int cell_x,cell_y;float vertex_x_px,vertex_y_px; List<Coord> coords = new ArrayList<Coord>(); for(Integer id:aroundIds) { cell_x=id-(int)(id/w)*w; cell_y=(int)(id/w)+1; vertex_x_px=-cell_x*ResConfig.Map.GRID_WIDTH*ResConfig.Map.MAP_SCALE; vertex_y_px=-cell_x%2!=0?(cell_y+1)*ResConfig.Map.HEXAGON_HEIGHT*ResConfig.Map.MAP_SCALE:(cell_y+0.5f)*ResConfig.Map.HEXAGON_HEIGHT*ResConfig.Map.MAP_SCALE; coords.add(new Coord(cell_x,cell_y,vertex_x_px,vertex_y_px)); } return coords; } //根据smallMap文件绘制图片顺便清理图片 public static Pixmap drawSmallMapAndClearPixmap(int mapId,AssetManager am){ XmlReader reader = ResConfig.reader; XmlReader.Element root = reader.parse(Gdx.files.internal("config/def_smallmap.xml")); int childNum = root.getChildCount(); String imgFileName; int w=0; int h=0; Pixmap pixmap = null;XmlReader.Element xmlFile; for (int i = 0; i < childNum; i++) { if (root.getChild(i).getInt("id")==mapId) { imgFileName=root.getChild(i).get("name"); xmlFile=root.getChild(i); pixmap = GameMap.createPixmapByView(xmlFile.getInt("width"), xmlFile.getInt("height")); for(int j=0;j<xmlFile.getChildCount();j++) { pixmap.drawPixmap(am.get(("image/"+imgFileName+"/"+xmlFile.getChild(j).get("n")),Pixmap.class),xmlFile.getChild(j).getInt("x"),xmlFile.getChild(j).getInt("y")); am.unload("image/"+imgFileName+"/"+xmlFile.getChild(j).get("n")); } break; } } //PixmapIO.writePNG(Gdx.files.external("smallWorld.png"), pixmap); return pixmap; } }
---------------------------补充------------------------------------------
背景色的绘制也可以使用 ShapeRenderer来完成,效果如下图
简单说下使用ShapeRenderer的优缺点
优点:
1.性能比原来使用的pixmap好,原来的地图色是建立一个pixmap,在pixmap上绘制显示
2.实时绘制,不需要像原来的pixmap一样更新(在游戏中我根据当前显示坐标位置,绘制国家势力)
缺点:
只能绘制形状,不能绘制图形
实时绘制,实时计算坐标,我对将来在安卓的测试持保留态度.
这里放一个 使用ShapeRenderer 绘制 点击地块的方法作为参考
public static void drawMapRegionByShapeRenderer(Fb2Smap smapDao,ShapeRenderer shapeRenderer, float scale, IntArray ids, boolean ifDrawSea,int mapW_px,int mapH_px,float alpha) { shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); if (smapDao.hexagonDatas != null &&smapDao.legionColors!=null&&smapDao.masterData.getIfColor()==1 && smapDao.hexagonDatas.size > 0) { int x = 0; int y = 0; float x_px_circle = 0; float y_px_circle = 0; float hexgaon_x1; float hexgaon_x2; float hexgaon_x3; float hexgaon_x4; float hexgaon_y1; float hexgaon_y2; float hexgaon_y3; int nextRegionId = 0; Color color = Color.CLEAR; boolean ifDrawIdWarLine; //先绘制海岸 //沿海地块用圆形来填充 //pixmap.setBlending(Blending.None); for (int id=0,iMax=ids.size,i=0;id<iMax;id++) { i=ids.get(id); if ( smapDao.hexagonDatas.get(i).getRegionId() != -1 ) { if(!ifDrawSea&& smapDao.hexagonDatas.get(i).getTerrainType() == 1){ continue; } //沿海地块用圆形来填充 if (smapDao.hexagonDatas.get(i).getRegionId() != nextRegionId) { //获取颜色 color=smapDao.getColorForRegion(smapDao.hexagonDatas.get(i).getRegionId()); shapeRenderer.setColor(color.r,color.g,color.b,alpha); nextRegionId =smapDao.hexagonDatas.get(i).getRegionId(); //Gdx.app.log("setColor","id:"+id+" color:"+color); } x = (i % smapDao.masterData.getWidth()) + 1; y = (i / smapDao.masterData.getWidth()) + 1; hexgaon_x1 = getHexagonX1F(x,y,scale)+mapW_px;//左上,左下 hexgaon_x2 = getHexagonX2F(x,y,scale)+mapW_px;//右上,右下 hexgaon_x3 = getHexagonX3F(x,y,scale)+mapW_px;//左中 hexgaon_x4 = getHexagonX4F(x,y,scale)+mapW_px;//右中 hexgaon_y1 = mapH_px-getHexagonY1F(x,y,scale);//上 hexgaon_y2 = mapH_px-getHexagonY2F(x,y,scale);//中 hexgaon_y3 = mapH_px- getHexagonY3F(x,y,scale);//下 x_px_circle=getX_px_CircleF(x,scale)+mapW_px; y_px_circle=mapH_px-getY_px_CircleF(x,y,scale); if(smapDao.hexagonDatas.get(i).getIfCoast()>0){ shapeRenderer.circle(x_px_circle, y_px_circle, (int) ((ResConfig.Map.HEXAGON_WIDTH + 13) * ResConfig.Map.MAP_SCALE / 2 * scale)); //pixmap.fillCircle(x_px_circle, y_px_circle, (int) ((ResConfig.Map.HEXAGON_WIDTH + 13) * ResConfig.Map.MAP_SCALE / 2 * scale)); }else{ shapeRenderer.triangle(hexgaon_x3, hexgaon_y2, hexgaon_x1, hexgaon_y1, hexgaon_x2, hexgaon_y1); shapeRenderer.triangle(hexgaon_x3, hexgaon_y2, hexgaon_x2, hexgaon_y1, hexgaon_x4, hexgaon_y2); shapeRenderer.triangle(hexgaon_x3, hexgaon_y2, hexgaon_x2, hexgaon_y3, hexgaon_x4, hexgaon_y2); shapeRenderer.triangle(hexgaon_x3, hexgaon_y2, hexgaon_x1, hexgaon_y3, hexgaon_x2, hexgaon_y3); } //Gdx.app.log("updColor","id:"+id+" legion:"+(Integer) regionColors.get(mapBinDAO.getMapbin().get(id).getPolitical())); } } } shapeRenderer.end(); }