因为准备做世界大战,所以准备了一张360*170的世界地图,但是这张地图实在是太大了,缩放到32%,仍然将近13000*6000
从var3d那里听说sprite挺好用,所以准备重新优化地图.
1.设定比例上限,玩家对多显示60*40的大小,即2400个格子
2.仿照网格,海洋写法,取消构建大地图的制作方式,,使用装饰素材处理为sprite,实时的构建玩家视野范围内的地图
Ps:海洋地图层的写法:为水蓝色,只铺满屏幕大小,显示在最底层,不做移动
网格地图层的写法:创建一个比玩家视野稍微大的网格,当玩家横向移动超过2格则反向移动2格距离,纵向超过1格则反向移动1格
pixmap的drawPixmap方法很坑,因为只能传int值,会导致地图不准
想要实现向世界4的海岸那样,暂时未成功,思路:制作了阴影层,绘制地图时判断阴影层颜色,然后删除对应地区的海洋边界颜色,遇到的问题:地块缩放后阴影层颜色改变,改变颜色需要遍历色素替换很费时间,构建临时存放地图无透明色等等,暂时放弃模仿世界4的海岸.
地图优化具体的实践结果随后会补上 ------记于3/5/17:38
从5号提出到现在的5天里,一直在实验和操作,最后终于觉得坚持不下去了.
出现的问题:1.实时绘制的坐标变换,纵轴横移基本没问题,个别地方会出现晃屏,原因不明
2.横坐标绘制,移动方向力度难以把控,比纵轴还难,在横坐标交汇点,会出现位移
暂时决定封存此设计方案,仍然采用原pixmap方式制作.随后做战略类游戏时再进行试验 ----记于3/10/22:13
---------------------------------------------------------------更新的分割线2019.4.5----------------------------------------------------------
经过无数尝试,终于完成了此算法
此算法的主要难度为:
1.中心点缩放,当陆地与六边形的绘制方位不对应时,会出现偏移 难度3星
2.x轴相对坐标的计算,类似于大陆地的算法相对简单 难度2星
3.y轴相对坐标的计算,因为y的方向是向上递减,所以计算坐标方向与传统思维计算方式会出现矛盾,会让思考方法出现偏转 难度4.5星
首先说明整体的实现思路:
1.计算屏幕高宽,确定显示范围
2.根据当前坐标确定左上坐标应绘制的类型,然后依次绘制,这里y的值需要根据左上的奇偶调整变换
3.陆地与六边形的绘制方位必须对应,如果不对应,改变zoom时,就会出现偏移!
下面为主要实现方法
//大陆块的实现方法
{ // 或根据玩家屏幕大小限制缩放比例 // 绘制循环陆地,如果比例尺大于一定值,则绘制三层 lw = (int) (spriteLand.getWidth() / vw / getZoom() + 2); lh = (int) (spriteLand.getHeight() / vh / getZoom() + 1); lh = lh < 2 ? 2 : lh; for (li = 0; li < lw * lh; li++) { lx = (li % lw) + 1; ly = (li / lw) + 1; lx_px = getX()*zoom % (spriteLand.getWidth() * getZoom()) + spriteLand.getWidth() * getZoom() * (lx - 1); ly_px = getY()*zoom % (spriteLand.getHeight() * getZoom()) + spriteLand.getHeight() * getZoom() * (ly - 1); batch.draw(spriteLand, lx_px, ly_px, getOriginX(), getOriginY(), spriteLand.getWidth(), spriteLand.getHeight(), // getScaleX(), getScaleY(), getZoom(), getZoom(), getRotation()); //bitmapFont.draw(batch, "id:"+li, lx_px-27*zoom, ly_px+48*zoom); } }
//六边形的绘制方法
gw = (int) (((vw / (112 * Config.Map.MAP_SCALE* getZoom())) +2)); gh = (int) (((vh / (128 * Config.Map.MAP_SCALE* getZoom())) +3)); ulcoord = GameMap.getHotCell((getImgX()), getImgY(),zoom); ul_parity_x=(ulcoord.getX()&1); ul_parity_y=(ulcoord.getY()&1); for (gi = 0; gi < gw * gh; gi++) { gx = (gi % gw) + 1; gy = (gi / gw) + 1; dx_px = -getImgX()*zoom+((int)((getImgX()* this.zoom)/ (112 * Config.Map.MAP_SCALE * this.zoom)))*(112 * Config.Map.MAP_SCALE * this.zoom)+( ((gx-1) * 112 * getZoom() * Config.Map.MAP_SCALE))/*+zoom==1?0:(112 * zoom * Config.Map.MAP_SCALE)*/; dy_px = -(vh%(128 * Config.Map.MAP_SCALE *zoom))+((vh)/zoom)*(zoom-1)+getImgY()*zoom+vh/zoom-((((int)((getImgY()*zoom)/ (128 * Config.Map.MAP_SCALE *zoom)))*(128 * Config.Map.MAP_SCALE * zoom))+ (((gy-1) * 128 +( (gx & 1) == 1 ? 0 : ((ul_parity_x&1)==1?-62:62)))* getZoom() * Config.Map.MAP_SCALE)+((ul_parity_x&1)==1?62:0)* Config.Map.MAP_SCALE * zoom); draw_gx = ulcoord.getX() + gx - 2; draw_gy = ulcoord.getY() + gy - gh ; draw_gd = w * draw_gy + draw_gx+1; if (draw_gx < w && draw_gy < h &&draw_gd<mapBinDAO.getMapbin().size()&&draw_gd>=0) { mapBin = mapBinDAO.getMapbin().get(draw_gd); backTile = tilesMap.get(mapBin.getBackTile() + "_" + mapBin.getBackIdx()); if (backTile == null) { backTile = tilesMap.get(mapBin.getBackTile() + "_1"); } if (backTile != null) { batch.draw(spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getSprite(), dx_px+mapBin.getBackRefX()*zoom*Config.Map.MAP_SCALE+spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getRefx()*zoom*Config.Map.MAP_SCALE, dy_px+mapBin.getBackRefY()*zoom*Config.Map.MAP_SCALE+spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getRefy()*zoom*Config.Map.MAP_SCALE, getOriginX(), getOriginY(), spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getSprite().getWidth() * Config.Map.MAP_SCALE, spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getSprite().getHeight() * Config.Map.MAP_SCALE, getZoom(), getZoom(), getRotation()); } else { // Gdx.app.log("", "id:"+draw_gd+" // backTile:"+backTile); } foreTile = tilesMap.get(mapBin.getForeTile() + "_" + mapBin.getForeIdx()); if (foreTile == null) { foreTile = tilesMap.get(mapBin.getForeTile() + "_1"); } if (foreTile != null) {//dx_px-spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getRefx()*zoom*Config.Map.MAP_SCALE, dy_px-spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getRefy()*zoom*Config.Map.MAP_SCALE batch.draw(spriteList.get(Integer.parseInt(spriteMap.get(foreTile))).getSprite(), dx_px+mapBin.getForeRefX()*zoom*Config.Map.MAP_SCALE+spriteList.get(Integer.parseInt(spriteMap.get(foreTile))).getRefx()*zoom*Config.Map.MAP_SCALE, dy_px+mapBin.getForeRefY()*zoom*Config.Map.MAP_SCALE+spriteList.get(Integer.parseInt(spriteMap.get(foreTile))).getRefy()*zoom*Config.Map.MAP_SCALE, getOriginX(), getOriginY(), spriteList.get(Integer.parseInt(spriteMap.get(foreTile))).getSprite().getWidth() * Config.Map.MAP_SCALE, spriteList.get(Integer.parseInt(spriteMap.get(foreTile))).getSprite().getHeight() * Config.Map.MAP_SCALE, getZoom(), getZoom(), getRotation()); } else { // Gdx.app.log("", "id:"+draw_gd+" // foreTile:"+foreTile); } }
//获取六边形坐标
// 六边形网格定位 // @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 = 112;// (CELL_BORDER*1.5f) float GRID_HEIGHT =128;// (CELL_BORDER*0.8660254f) float Gride_BORDER=GRID_WIDTH/1.5f; int cell_y; int cell_x; xPos=xPos/Config.Map.MAP_SCALE; yPos=yPos/Config.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(! (Gride_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)<=Gride_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; }
//改变中心点
public void setZoom(float zoom,float cx,float cy) { this.xMax= (this.mapW_px * Config.Map.MAP_SCALE * zoom - vw/zoom+(1-zoom)*this.mapW_px * Config.Map.MAP_SCALE); this.yMax= (this.mapH_px * Config.Map.MAP_SCALE * zoom - vh/zoom+(1-zoom)*this.mapH_px * Config.Map.MAP_SCALE); cx=(getX() - cx) ; cy=(getY() - cy) ; // if (zoom * this.mapW_px < vw || zoom * this.mapH_px < vh) { if (zoom < zoomMax) { //Gdx.app.log("阻止缩放", " zoomMax:"+zoomMax+" zoom:"+zoom); // Gdx.app.log("阻止缩放", "w:"+this.mapW_px+" // h:"+this.mapH_px+" vw:"+vw+" vh:"+vh); } else if (zoom > 2.0f) { zoom = 2.0f; } else if (zoom < 0.5f) { zoom = 0.5f; } else { //旧坐标-(鼠标实际坐标-旧坐标)*(新倍率-旧倍率)/旧倍率 //Gdx.app.log("", "x:"+x+" y:"+y+" cx:"+cx+" cy"+cy); x=x+(cx-x)*(zoom-this.zoom)/this.zoom; y=y+(cy-y)*(zoom-this.zoom)/this.zoom; this.zoom = zoom; }
完整代码:
package com.zhfy.game.screen.actor; import java.util.ArrayList; import java.util.HashMap; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; 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.ui.List; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.zhfy.game.config.Config; import com.zhfy.game.config.Config.Map; import com.zhfy.game.framework.GameFramework; import com.zhfy.game.framework.GameMap; import com.zhfy.game.framework.GameUtils; 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.SpriteDAO; import com.zhfy.game.model.framework.SpriteListDAO; import com.zhfy.game.model.framework.TextureListDAO; public class BgActor extends Actor { //使用左上角为顶点前的备份 // 本类用来存放背景地图,获取地图范围,移动,缩放背景地图,确定点击位置等,以及环状地图 private DefMap defMap; private Pixmap pixmap;// 临时画布 private MapBinDAO mapBinDAO; private MapBin mapBin; private Texture textureLand;// 陆地 // private Texture textureColor;// 颜色 // private Texture textureDecor;// 装饰 // private Texture textureOcean;// 海洋 // private Texture textureGrid;// 网格 private Sprite spriteLand;// 陆地 // private Sprite spriteColor;// 颜色 // private Sprite spriteDecor;// 装饰 // private Sprite spriteOcean;// 海洋 // private Sprite spriteGrid;// 网格 // private GameFramework gameFramework; private int mapW_px; private int mapH_px; private float x; private float y; private float x_vector; private float y_vector; private int w; private int h; private boolean ifGrid;// 是否显示网格 private float zoom; private float zoomMax; private float xMax; private float yMax; // 使用此判断是否需要重新计算绘制坐标 private float mx; private float my; private float mz; private float vw;// 玩家屏幕宽 private float vh;// 玩家屏幕高 // 横向平移2格还原地图 // 纵向平移1格还原地图 // 网格使用 private float vx;// 视口位置x private float vy;// 视口位置y private int gw;// 网格循环横向次数,即宽 private float gw_y; private int gh;// 网格循环纵向次数,即高 private float gh_y; private int gx;// 网格横坐标 private int gy;// 网格纵坐标 private float gx_px;// 网格横坐标 private float gy_px;// 网格纵坐标 private float dx_px;// 装饰横坐标 private float dy_px;// 装饰纵坐标 private float dy_refpx;// 装饰纵坐标偏离 private float dy_yz;//y轴最上方原坐标 public float getDx_px() { return dx_px; } public void setDx_px(float dx_px) { this.dx_px = dx_px; } public float getDy_px() { return dy_px; } public void setDy_px(float dy_px) { this.dy_px = dy_px; } // 绘制陆地使用,大概是1024*1024的大图 int lw; int lh; int li; int lx; int ly; float lx_px = 0; float ly_px = 0; private int gi;// 网格循环次数 // 点击坐标 private Coord coord; // 左下角坐标,即x,y的坐标 private Coord ulcoord; //左上坐标奇偶 private int ul_parity_x; private int ul_parity_y; // 绘制中的坐标以及id private int draw_gx; private int draw_gy; private int draw_gd; // 是否移动时再绘制 private boolean ifDraw = false; // 存放图像素材 private TextureListDAO textureList; // 对图像素材进行操作 private SpriteListDAO spriteList; // 存放spriteList的顺序{m_n,i} private HashMap<String, String> spriteMap; // 存放对应的装饰名与id private HashMap<String, String> tilesMap; DefTerrainimg defTerrainimgTemp; java.util.List<DefTerrainimg> defTerrainimgs; String backTile; String foreTile; // 文字贴图(默认不支持中文)。 BitmapFont bitmapFont; //TODO 测试 随后删除 float qb;float hb; String s2=""; String s1=""; float a0; float a1; float a2; float a3; float a4; float a5; float a6; float a7; float a8; float a9; 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; } public BgActor(GameFramework gameFramework, int mapId, float vw, float vh) { super(); ifGrid = false; // 获取defMap // this.gameFramework=gameFramework; defMap = gameFramework.getDefMapByMapId(mapId); mapBinDAO = gameFramework.getMapDaoByMapId(mapId); { this.x = 0;// TODO 随后设计为玩家起始位置 this.y = 0; this.w = defMap.getWidth(); this.h = defMap.getHeight(); this.vw = vw; this.vh = vh; this.zoom = 1.0f; // 实际宽高 this.mapW_px = GameMap.getWidth(w); this.mapH_px = GameMap.getHeight(h); this.mx = this.x; this.my = this.y; this.mz = this.zoom; this.zoomMax=(vw/(mapW_px)<vh/(mapH_px)?vh/(mapH_px):vw/(mapW_px))/Map.MAP_SCALE; this.xMax= (this.mapW_px * Config.Map.MAP_SCALE * zoom - vw/zoom+(1-zoom)*this.mapW_px * Config.Map.MAP_SCALE); this.yMax= (this.mapH_px * Config.Map.MAP_SCALE * zoom - vh/zoom+(1-zoom)*this.mapH_px * Config.Map.MAP_SCALE); Gdx.app.log("", "w:" + w + " h:" + h + " mapW_px:" + mapW_px + " mapH_px:" + mapH_px+" zoomMax:"+zoomMax); } { // 绘制画布转为陆地 陆地制作一个pixmap大小的地图,实时绘制 // TODO 先默认为这个通用地块色,随后改为加载btl的地图 textureLand = new Texture(Gdx.files.internal("pixmap/pts/pt1.png")); spriteLand = new Sprite(textureLand); } { // 绘制画布转为颜色 // textureColor = new // Texture(Gdx.files.internal("pixmap/tiles/hexagon.png")); // spriteColor= new Sprite(textureColor); } { bitmapFont = new BitmapFont(); bitmapFont.setColor(Color.RED); bitmapFont.getData().setScale(0.8f*zoom); // 绘制画布转为装饰 textureList = new TextureListDAO(); textureList.addPixmapByFileName("pm_tiles"); spriteList = new SpriteListDAO(); spriteMap = spriteList.init(textureList); tilesMap = new HashMap<String, String>(); defTerrainimgTemp = new DefTerrainimg(); defTerrainimgs = new ArrayList<DefTerrainimg>(); try { defTerrainimgs = GameUtils.getDaoListByClass(defTerrainimgTemp, "config/def_terrainimg.xml"); } catch (Exception e) { e.printStackTrace(); } // 将要取得的图片的id和名字放入位置 for (DefTerrainimg defTerrainimg : defTerrainimgs) { tilesMap.put(defTerrainimg.getId() + "_" + defTerrainimg.getIdx(), defTerrainimg.getImage().replace(".png", "")); } } { // 绘制画布转为海洋 } { // 实时绘制网格 // textureGrid = new // Texture(Gdx.files.internal("pixmap/tiles/grid.png")); // spriteGrid = new Sprite(textureGrid); } setSize(this.mapW_px * Config.Map.MAP_SCALE, this.mapH_px * Config.Map.MAP_SCALE); addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { // 点击图片,图片隐藏![这里写图片描述](https://img-blog.csdn.net/20160425220710777) // super.clicked(event, x, y); // Gdx.app.log("点击的精灵位置1", "x:" + (getX()/getZoom()+x)+" y:" // +(getY()/getZoom()+ y)); // 由于要在actor等中使用坐标绘图,所以采用libgdx的actor坐标系 // 左下为0,0,向右上方向负数扩展 //Gdx.app.log("点击背景位置1", "x:" + (getX()-x)+" y:" + (getY()- y)+" zoom:" + zoom); //Gdx.app.log("点击背景位置1", "bgx:" + getX()+" bgy:" + getY()+"zoom:" + zoom+" x:" + x+" y:" + y); // Gdx.app.log("点击背景位置2", "actX:" + (getX()-x)/getZoom()+" // actY:"+ (getY()-y)/getZoom()); // 点击偏移,经过测试x+4 y+20后合适 coord = GameMap.getHotCell(getImgX((getX() - x)/ getZoom()), getImgY((getY()- y)/ getZoom() ),zoom); Gdx.app.log("点击背景位置", "cx:" + (getX() - x)/ getZoom() + " cy:" + (getY()- y)/ getZoom()); //Gdx.app.log("点击背景位置", "imgX:" + getImgX((getX() - x) / getZoom()) + " imgY:" + getImgY((getY() - y) / getZoom())); //Gdx.app.log("点击坐标", "imgX:" + coord.getX() + " imgY:" + coord.getY()); } }); } @Override public void act(float delta) { super.act(delta); } @Override public void draw(Batch batch, float parentAlpha) { super.draw(batch, parentAlpha); { // 实时绘制地图色 // TODO // 实时绘制装饰 // 0.确定每层装饰最大显示格子数 // 0.1增加中间处理,把地图分为n层,可以通过id计算处于某层,或某层包含哪些id // 1.平时绘制2层装饰,缩放超过一定范围,绘制三层装饰 // 2.写一个方法,获取mapbin的每层装饰,然后实时绘制 // 3.测试能否与海洋色一起绘制的效果 { // 实时绘制网格 if (!ifDraw) { mx = 1; } if ((mx != x || my != y || mz != zoom)) { //显示的范围,跨屏显示+3 gw = (int) (((vw / (112 * Config.Map.MAP_SCALE* getZoom())) +2)); gw_y=vw % (112 * Config.Map.MAP_SCALE* zoom); gh = (int) (((vh / (128 * Config.Map.MAP_SCALE* getZoom())) +3)); gh_y=vh % (128 * Config.Map.MAP_SCALE* zoom); ulcoord = GameMap.getHotCell((getImgX()), getImgY(),zoom); //ulcoord = GameMap.getHotCell(getImgX((getX() )/ getZoom()), getImgY((getY())/ getZoom() ),zoom); //Gdx.app.log(""," ulcoord.x:"+ulcoord.getX()+"ulcoord.y:"+(ulcoord.getY()-gh)+ " gw:"+gw+" gh:"+gh); mx = x; my = y; mz = zoom; ul_parity_x=(ulcoord.getX()&1); ul_parity_y=(ulcoord.getY()&1); { // 或根据玩家屏幕大小限制缩放比例 // 绘制循环陆地,如果比例尺大于一定值,则绘制三层 lw = (int) (spriteLand.getWidth() / vw / getZoom() + 2); lh = (int) (spriteLand.getHeight() / vh / getZoom() + 1); lh = lh < 2 ? 2 : lh; for (li = 0; li < lw * lh; li++) { lx = (li % lw) + 1; ly = (li / lw) + 1; //lx_px = getX()*zoom % (spriteLand.getWidth() * getZoom()) + spriteLand.getWidth() * getZoom() * (lx - 1); //ly_px = getY()*zoom % (spriteLand.getHeight() * getZoom()) + spriteLand.getHeight() * getZoom() * (ly - 1); lx_px = getX()*zoom % (spriteLand.getWidth() * getZoom()) + spriteLand.getWidth() * getZoom() * (lx - 1); ly_px = getY()*zoom % (spriteLand.getHeight() * getZoom()) + spriteLand.getHeight() * getZoom() * (ly - 1); //lx_px = -getImgX() % (spriteLand.getWidth() * getZoom()) + spriteLand.getWidth() * getZoom() * (lx - 1); //ly_px = getImgY() % (spriteLand.getHeight() * getZoom()) - spriteLand.getHeight() * getZoom() * (ly - 1); batch.draw(spriteLand, lx_px, ly_px, getOriginX(), getOriginY(), spriteLand.getWidth(), spriteLand.getHeight(), // getScaleX(), getScaleY(), getZoom(), getZoom(), getRotation()); bitmapFont.draw(batch, "id:"+li, lx_px-27*zoom, ly_px+48*zoom); } //Gdx.app.log("1", " lw:" + lw + " lh:" + lh + " size:"+ lw * lh + " zoom:" + zoom + " lx_px:" + lx_px + "ly_px:" + ly_px); } //Gdx.app.log("3"," dx_px:"+dx_px+" dy_px:"+dy_px+" ulcoordx:"+ulcoord.x+" x:"+getX()+" gw:"+gw); for (gi = 0; gi < gw * gh; gi++) { gx = (gi % gw) + 1; gy = (gi / gw) + 1; //gx_px = -getImgX() % (224 * Config.Map.MAP_SCALE * this.zoom) + ((gx - 1) * 112 * getZoom() * Config.Map.MAP_SCALE); //gy_px = (getImgY() % (128 * Config.Map.MAP_SCALE * this.zoom)+(((gx & 1) == 1 ? (gy - 1) * 128 : (gy - 1) * 128 - 62))* getZoom() * Config.Map.MAP_SCALE); //TODO 获取屏幕中点与游戏显示中点,缩放等比例距离保持比例一致 //dx_px = -(((int)((getX())/ (112 * Config.Map.MAP_SCALE * this.zoom)))*(112 * Config.Map.MAP_SCALE * this.zoom))+ (((gx-1) * 112 )* getZoom() * Config.Map.MAP_SCALE)+getX(); //dx_px = -getImgX()+(((int)((getImgX())/ (112 * Config.Map.MAP_SCALE * this.zoom)))*(112 * Config.Map.MAP_SCALE * this.zoom))+ ((gx-1) * 112 * getZoom() * Config.Map.MAP_SCALE)/*+zoom==1?0:(112 * zoom * Config.Map.MAP_SCALE)*/; dx_px = -getImgX()*zoom+((int)((getImgX()* this.zoom)/ (112 * Config.Map.MAP_SCALE * this.zoom)))*(112 * Config.Map.MAP_SCALE * this.zoom)+( ((gx-1) * 112 * getZoom() * Config.Map.MAP_SCALE))/*+zoom==1?0:(112 * zoom * Config.Map.MAP_SCALE)*/; //dx_px = -getImgX()*zoom+((int)((getImgX()* this.zoom)/ (112 * Config.Map.MAP_SCALE * this.zoom)))*(112 * Config.Map.MAP_SCALE * this.zoom)+( ((gx-1) * 112 * getZoom() * Config.Map.MAP_SCALE))/*+zoom==1?0:(112 * zoom * Config.Map.MAP_SCALE)*/; // dx_px = getX()*zoom % (112 * Config.Map.MAP_SCALE * getZoom())+(112 * Config.Map.MAP_SCALE * getZoom())*(gx-1); /*if(gi==0) { a1=(getImgX()); a2=((int)((getImgX())/ (112 * Config.Map.MAP_SCALE * this.zoom))); a3=((112 * Config.Map.MAP_SCALE * this.zoom)); a4=(gx-1) ; a5=-a1+a2*a3+a4*a3; a9=dx_px; }*/ dy_px = -(vh%(128 * Config.Map.MAP_SCALE *zoom))+((vh)/zoom)*(zoom-1)+getImgY()*zoom+vh/zoom-((((int)((getImgY()*zoom)/ (128 * Config.Map.MAP_SCALE *zoom)))*(128 * Config.Map.MAP_SCALE * zoom))+ (((gy-1) * 128 +( (gx & 1) == 1 ? 0 : ((ul_parity_x&1)==1?-62:62)))* getZoom() * Config.Map.MAP_SCALE)+((ul_parity_x&1)==1?62:0)* Config.Map.MAP_SCALE * zoom); //正确 dy_px = ((vh)/zoom)*(zoom-1)+getImgY()*zoom+vh/zoom-((((int)((getImgY()*zoom)/ (128 * Config.Map.MAP_SCALE *zoom)))*(128 * Config.Map.MAP_SCALE * zoom))+ (((gy-1) * 128 +( (gx & 1) == 1 ? 0 : ((ul_parity_x&1)==1?-62:62)))* getZoom() * Config.Map.MAP_SCALE)+((ul_parity_x&1)==1?62:0)* Config.Map.MAP_SCALE * zoom); // dy_px = (h+(int)((getY()*zoom)/ (128 * Config.Map.MAP_SCALE *zoom)))*(128 * Config.Map.MAP_SCALE * zoom)+(y*zoom % (128 * Config.Map.MAP_SCALE * getZoom()))- (((gy-1) * 128 +( (gx & 1) == 1 ? 0 : ((ul_parity_x&1)==1?-62:62)))* getZoom() * Config.Map.MAP_SCALE)+((ul_parity_x&1)==1?0:62)* Config.Map.MAP_SCALE * zoom; s1=" dy_refpx:"+gy+" y:"+zoom; //Gdx.app.log("", " x:"+dy_px); if(draw_gd==1&&!s1.equals(s2)) { //dy_px=dy_px-(mapH_px-dy_px)*zoom; //Gdx.app.log("", " dy_px:"+dy_px+" yMax:"+((yMax+y/zoom)-dy_px)); /* a1=(((vh)/zoom)*(zoom-1)+(mapH_px * Config.Map.MAP_SCALE-yMax)*zoom+vh/zoom); a2=((int)(((mapH_px * Config.Map.MAP_SCALE-yMax)*zoom)/ (128 * Config.Map.MAP_SCALE *zoom))); a3=(128 * Config.Map.MAP_SCALE *zoom); a4=(((-ulcoord.getY()+ gh-1) * 128 +62)* getZoom() * Config.Map.MAP_SCALE); a5=((ul_parity_x&1)==1?62:0)* Config.Map.MAP_SCALE * zoom; a9=(((vh)/zoom)*(zoom-1)+(mapH_px * Config.Map.MAP_SCALE-yMax)*zoom+vh/zoom)-((((int)(((mapH_px * Config.Map.MAP_SCALE-yMax)*zoom)/ (128 * Config.Map.MAP_SCALE *zoom)))*(128 * Config.Map.MAP_SCALE *zoom))+(((-ulcoord.getY()+ gh-1) * 128 +62)* getZoom() * Config.Map.MAP_SCALE)); Gdx.app.log("", " a1:"+a1+" a2:"+a2+" a3:"+a3+" a4:"+a4+" a5:"+a5+" a9:"+a9+" dy_px:"+dy_px); */ Gdx.app.log("", " gi:"+gi+" gw:"+gw+" gw_y:"+gw_y+" gh:"+gh+" gh_y:"+gh_y+" gx:"+gx+" gy:"+gy+" dy_px:"+dy_px+" ulcoord_X:"+ulcoord.getX()+" getImgY:"+getImgY()+" ulcoord_Y:"+ulcoord.getY()+" zoom:"+zoom+" dy_yz:"+dy_yz+" dy_px:"+dy_px); s2=s1; } // 绘制背景色 // TODO 获取背景色,然后根据颜色排序,然后为batch赋值并绘制 // batch.setColor(123,123,123,123); /* * batch.setColor(new Color( * GameUtils.toIntColor(191,200,41,255))); * batch.draw(spriteColor, gx_px, gy_px, getOriginX(), * getOriginY(), spriteGrid.getWidth() * * Config.Map.MAP_SCALE, spriteGrid.getHeight() * * Config.Map.MAP_SCALE, getZoom(), getZoom(), * getRotation()); * * //Gdx.app.log(""," r:"+Color.RED.r+" g:"+Color.RED. * g+" b:"+Color.RED.b+" a:"+Color.RED.a); */ // 绘制装饰 // 1.建立sprite合集存放图片√ // 2.获取左上角坐标,推算显示的数量是哪几个 // 3.再从对应的mapbin中获取显示的id值,然后在sprite合集的图片中取出对应图片放入相应位置 // 要显示的id,以及对应的图片 // 绘制的x坐标 draw_gx = ulcoord.getX() + gx - 2; draw_gy = ulcoord.getY() + gy - gh ; draw_gd = w * draw_gy + draw_gx+1; /* s1="dx_px:"+dx_px+" draw_gy:"+draw_gy+" draw_gd:"+draw_gd+" x:"+getX(); if(draw_gd==7791&&!s1.equals(s2)) { a1=(getImgX()); a2=((int)((getImgX())/ (112 * Config.Map.MAP_SCALE * this.zoom))); a3=((112 * Config.Map.MAP_SCALE * this.zoom)); a4=(gx-1) ; a5=-a1+a2*a3+a4*a3; a9=dx_px; // Gdx.app.log("3", "dx_px:"+dx_px+" a1:"+a1+" a2:"+a2+" a3:"+a3+" a4:"+a4+" a5:"+a5+" a9:"+a9+" gx:"+gx+" gw:"+gw+" zoom:"+zoom); s2=s1; } */ if (draw_gx < w && draw_gy < h &&draw_gd<mapBinDAO.getMapbin().size()&&draw_gd>=0) { //mapBin = mapBinDAO.getMapbin().get((ulcoord.getX() + gx) * ((ulcoord.getY() - 1 + gy)) + ulcoord.getY() + gy); //TODO mapBin = mapBinDAO.getMapbin().get(draw_gd); backTile = tilesMap.get(mapBin.getBackTile() + "_" + mapBin.getBackIdx()); if (backTile == null) { backTile = tilesMap.get(mapBin.getBackTile() + "_1"); } // Gdx.app.log("绘制的坐标为:","x:"+draw_gx+" // y:"+draw_gy+" id:"+draw_gd); if (backTile != null) { batch.draw(spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getSprite(), dx_px+mapBin.getBackRefX()*zoom*Config.Map.MAP_SCALE+spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getRefx()*zoom*Config.Map.MAP_SCALE, dy_px+mapBin.getBackRefY()*zoom*Config.Map.MAP_SCALE+spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getRefy()*zoom*Config.Map.MAP_SCALE, getOriginX(), getOriginY(), spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getSprite().getWidth() * Config.Map.MAP_SCALE, spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getSprite().getHeight() * Config.Map.MAP_SCALE, getZoom(), getZoom(), getRotation()); } else { // Gdx.app.log("", "id:"+draw_gd+" // backTile:"+backTile); } foreTile = tilesMap.get(mapBin.getForeTile() + "_" + mapBin.getForeIdx()); if (foreTile == null) { foreTile = tilesMap.get(mapBin.getForeTile() + "_1"); } if (foreTile != null) {//dx_px-spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getRefx()*zoom*Config.Map.MAP_SCALE, dy_px-spriteList.get(Integer.parseInt(spriteMap.get(backTile))).getRefy()*zoom*Config.Map.MAP_SCALE batch.draw(spriteList.get(Integer.parseInt(spriteMap.get(foreTile))).getSprite(), dx_px+mapBin.getForeRefX()*zoom*Config.Map.MAP_SCALE+spriteList.get(Integer.parseInt(spriteMap.get(foreTile))).getRefx()*zoom*Config.Map.MAP_SCALE, dy_px+mapBin.getForeRefY()*zoom*Config.Map.MAP_SCALE+spriteList.get(Integer.parseInt(spriteMap.get(foreTile))).getRefy()*zoom*Config.Map.MAP_SCALE, getOriginX(), getOriginY(), spriteList.get(Integer.parseInt(spriteMap.get(foreTile))).getSprite().getWidth() * Config.Map.MAP_SCALE, spriteList.get(Integer.parseInt(spriteMap.get(foreTile))).getSprite().getHeight() * Config.Map.MAP_SCALE, getZoom(), getZoom(), getRotation()); } else { // Gdx.app.log("", "id:"+draw_gd+" // foreTile:"+foreTile); } /**/ if (ifGrid) { //字体 bitmapFont.draw(batch, "id:"+draw_gd, dx_px-27*zoom, dy_px+50*zoom); bitmapFont.draw(batch, "gi:"+gi, dx_px-27*zoom, dy_px+40*zoom); bitmapFont.draw(batch, " x:"+draw_gx, dx_px-25*zoom, dy_px+61*zoom); bitmapFont.draw(batch, " y:"+draw_gy, dx_px-25*zoom, dy_px+30*zoom); } /* if(gi==0) { bitmapFont.draw(batch, "dy_px:"+dy_px,dx_px-27*zoom, dy_px+48*zoom); }*/ } // 绘制海洋色 // 绘制网格 if (ifGrid) { batch.draw(spriteList.get(Integer.parseInt(spriteMap.get("grid"))).getSprite(), dx_px, dy_px, getOriginX(), getOriginY(), spriteList.get(Integer.parseInt(spriteMap.get("grid"))).getSprite().getWidth() * Config.Map.MAP_SCALE, spriteList.get(Integer.parseInt(spriteMap.get("grid"))).getSprite().getHeight() * Config.Map.MAP_SCALE, getZoom(), getZoom(), getRotation()); // Gdx.app.log("", "12"); } } } } } } public float getX() { if (this.x > 0) { x = 0; } else if (this.x < -(xMax)) { x = -(xMax); //Gdx.app.log("边界修正", x+""); } return x; } public void setX(float x) { this.x_vector=x-this.x; //x_vector=x_vector<0?-x_vector:x_vector; this.x = x; } public float getY() { // Gdx.app.log("边界修正", "yMax:"+(y)); if (this.y > 0) { y = 0; } else if (this.y < -yMax) { y = -yMax; // Gdx.app.log("边界修正", "yMax:"+(y)); } return y; } public void setY(float y) { this.y_vector=y-this.y; //y_vector=y_vector<0?-y_vector:y_vector; 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= (this.mapW_px * Config.Map.MAP_SCALE * zoom - vw/zoom+(1-zoom)*this.mapW_px * Config.Map.MAP_SCALE); this.yMax= (this.mapH_px * Config.Map.MAP_SCALE * zoom - vh/zoom+(1-zoom)*this.mapH_px * Config.Map.MAP_SCALE); cx=(getX() - cx) ; cy=(getY() - cy) ; // if (zoom * this.mapW_px < vw || zoom * this.mapH_px < vh) { if (zoom < zoomMax) { //Gdx.app.log("阻止缩放", " zoomMax:"+zoomMax+" zoom:"+zoom); // Gdx.app.log("阻止缩放", "w:"+this.mapW_px+" // h:"+this.mapH_px+" vw:"+vw+" vh:"+vh); } else if (zoom > 2.0f) { zoom = 2.0f; } else if (zoom < 0.5f) { zoom = 0.5f; } else { //Gdx.app.log(""," ulcoord_x:"+ulcoord.getX()+" ulcoord_y:"+ulcoord.getY()); // Gdx.app.log("容许缩放2", "w:"+this.mapW_px+" // h:"+this.mapH_px+" vw:"+vw+" vh:"+vh); /* * //改变前的中心点 float cx=(x-vw/2)/getZoom(); float * cy=(y-vh/2)/getZoom(); //改变后的中心点 float ex=(x-vw/2)/zoom; float * ey=(y-vh/2)/zoom; Gdx.app.log("变化地图1", "x:"+x+" y:"+y); * this.x=x-(ex-cx)*zoom; this.y=y-(ey-cy)*zoom; * Gdx.app.log("变化地图2", "x:"+x+" y:"+y); Gdx.app.log("变化地图", * "cx:"+cx+" cy:"+cy+" ex:"+ex+" ey:"+ey); Gdx.app.log("变化地图", * "中心点x差:"+(ex-cx)+" y差:"+(ey-cy)+" zoom:"+(this.zoom-zoom)); */ //this.x = x - (((x - vw / 2) / zoom) - ((x - vw / 2) / this.zoom)) * zoom -getX()*(zoom-this.zoom)%(vw * getZoom()) ; //this.y = y - (((y - vh / 2) / zoom) - ((y - vh / 2) / this.zoom)) * zoom -getY()*(zoom-this.zoom)%(vh * getZoom()); //this.x=x+(vw)*(this.zoom-zoom); //this.y=; //this.x = x - (((x - vw / 2) / zoom) - ((x - vw / 2) / this.zoom)) * zoom;//x+(x*(zoom-this.zoom));// //this.y = y - (((y - vh / 2) / zoom) - ((y - vh / 2) / this.zoom)) * zoom;//y+(y*(zoom-this.zoom));// //旧坐标-(鼠标实际坐标-旧坐标)*(新倍率-旧倍率)/旧倍率 //Gdx.app.log("", "x:"+x+" y:"+y+" cx:"+cx+" cy"+cy); x=x+(cx-x)*(zoom-this.zoom)/this.zoom; y=y+(cy-y)*(zoom-this.zoom)/this.zoom; //this.x=x; //this.y=y; //this.x = x - (((x - vw / 2) / zoom) - ((x - vw / 2) / this.zoom)) * zoom -getX()*(zoom-this.zoom)%(vw * getZoom()) ; //this.y = y - (((y - vh / 2) / zoom) - ((y - vh / 2) / this.zoom)) * zoom -getY()*(zoom-this.zoom)%(vh * getZoom()); //this.x = x - (((x) / zoom) - ((x - vw / 2) / this.zoom)) * zoom -getX()*(zoom-this.zoom)%(vw * getZoom()) ; //this.x=(x-vw)*; //this.y=(y-vh)*(this.zoom-zoom); this.zoom = zoom; // this.x=x-this.this.mapW_px*(this.zoom-zoom)/2; // this.y=y+vh*(this.zoom-zoom); } //Gdx.app.log("", " a3:"+a3+" dy_refpx:"+dy_refpx+" dy_px:"+dy_px+" zoom:"+zoom+" ul_parity_x&1:"+(ul_parity_x&1)+" "); //dy_px =((vh)/zoom)*(zoom-1)+getImgY()*zoom+vh/zoom-((((int)((getImgY()*zoom)/ (128 * Config.Map.MAP_SCALE *zoom)))*(128 * Config.Map.MAP_SCALE * zoom))+ (((gy-1) * 128 +( (gx & 1) == 1 ? 0 : ((ul_parity_x&1)==1?-62:62)))* getZoom() * Config.Map.MAP_SCALE)+((ul_parity_x&1)==1?62:0)* Config.Map.MAP_SCALE * zoom); /* a1=((vh)/zoom)*(zoom-1)+getImgY()*zoom+vh/zoom; a2=(int)((getImgY()*zoom)/ (128 * Config.Map.MAP_SCALE *zoom)); a3=(128 * Config.Map.MAP_SCALE * zoom); a4=(((gy-1) * 128 +( (gx & 1) == 1 ? 0 : ((ul_parity_x&1)==1?-62:62)))* getZoom() * Config.Map.MAP_SCALE); a5=((ul_parity_x&1)==1?62:0)* Config.Map.MAP_SCALE * zoom; //a6=; //a7=; //a8=; a9=a1-((a2*a3)+a4+a5); Gdx.app.log("", " a1:"+a1+" a2:"+a2+" a3:"+a3+" a4:"+a4+" a5:"+a5+" a9:"+a9+" 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 - this.mapH_px); } // 将←↓act坐标(左下角为0,0,越向右上越小)转化为↓→坐标(左上角为0,0,越向右下越大) // 将↓→坐标(左上角为0,0,越向右下越大)转为←↓act坐标(左下角为0,0,越向右上越小) public float getImgX(float print_x) { if (print_x != 0f) { return (-print_x); } else { return 0f; } } public float getImgY(float print_y) { return (this.mapH_px * Config.Map.MAP_SCALE + print_y); } //获取实际坐标 public float getImgX() { if (this.x != 0f) { return (-this.x); } else { return 0f; } } public float getImgY() { return (this.mapH_px * Config.Map.MAP_SCALE + this.y); } // 清理5张图层 public void dispose() { if (textureLand != null) { textureLand.dispose(); } /* * if (textureGrid != null) { textureGrid.dispose(); } if (textureColor * != null) { textureColor.dispose(); } if (textureDecor != null) { * textureDecor.dispose(); } if (textureOcean != null) { * textureOcean.dispose(); } */ if (textureList != null) { textureList.clearAll(); textureList = null; spriteList = null; } if (defMap != null) { defMap = null; } if (bitmapFont != null) { bitmapFont.dispose(); } } public DefMap getDefMap() { return defMap; } public void setDefMap(DefMap defMap) { this.defMap = defMap; } 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 getTextureLand() { return textureLand; } public void setTextureLand(Texture textureLand) { this.textureLand = textureLand; } public Sprite getSpriteLand() { return spriteLand; } public void setSpriteLand(Sprite spriteLand) { this.spriteLand = spriteLand; } public boolean isIfGrid() { return ifGrid; } public void setIfGrid(boolean ifGrid) { this.ifGrid = ifGrid; } 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 int getMapW_px() { return mapW_px; } public void setMapW_px(int mapW_px) { this.mapW_px = mapW_px; } public int getMapH_px() { return mapH_px; } public void setMapH_px(int mapH_px) { this.mapH_px = mapH_px; } public TextureListDAO getTextureList() { return textureList; } public void setTextureList(TextureListDAO textureList) { this.textureList = textureList; } public SpriteListDAO getSpriteList() { return spriteList; } public void setSpriteList(SpriteListDAO spriteList) { this.spriteList = spriteList; } public Coord getUlcoord() { return ulcoord; } public void setUlcoord(Coord ulcoord) { this.ulcoord = ulcoord; } public float getA1() { return a1; } public void setA1(float a1) { this.a1 = a1; } public float getA2() { return a2; } public void setA2(float a2) { this.a2 = a2; } public float getA3() { return a3; } public void setA3(float a3) { this.a3 = a3; } public float getA4() { return a4; } public void setA4(float a4) { this.a4 = a4; } public float getA5() { return a5; } public void setA5(float a5) { this.a5 = a5; } public float getA9() { return a9; } public void setA9(float a9) { this.a9 = a9; } }
感慨下:数学不学好,做游戏空流泪 ----记于2019年4月5日
在随后的测试中,发现这种绘制方法存在一些问题:
drawcell过高,即一秒要在屏幕绘制700多次
这个的原因是因为实时绘制的是动态网格而不是少量的图,所以导致的这个问题,
从大佬们那里得到一种解决思路;把根据当前屏幕把图片动态合为512*512的图来显示
这个等项目完成阶段再做尝试 --记于4.16
------------------------------过去一年的分割线----------------------------------------
已经过去一年半了,此方式经过多次大改,并且坑很大,故重新记录
总体思路:
1.移动照相机cam,更新地图的显示范围参数
2.根据cam显示范围,绘制陆地,装饰
1.地图显示方式的思路:
1.修改libgdx的照相机cam类,当cam移动后记录当前屏幕显示地图的范围
//地图移动后计算这几个坐标 private Coord tempCoord; //左上坐标 public int csx; public int csy; //右下坐标 public int cex; public int cey; //坐标宽高 public int cw; public int ch; public int setPotion(float x,float y,boolean ifRefersh){ loopState =0;//0 绘制左边 1绘制两侧 2只绘制右边 if(ifLoop) { //1 在左地图内 if(x>= camWScope *camera.zoom&&x<= mapW_px - camWScope *camera.zoom){ loopState =0; // Gdx.app.log("setPotion0","x:"+x+" y:"+y); //2 在右地图向左地图滑动 }else if(x>= camWScope *camera.zoom+ mapW_px ){ x=x- mapW_px; loopState =0; // Gdx.app.log("setPotion1","x:"+x+" y:"+y); //3 向左划出左边界 }else if(x< camWScope*camera.zoom){ // Gdx.app.log("setPotion2","x:"+x+" y:"+y); loopState =1; x=x+ mapW_px; //4 向右划出左地图的右边界 }else if(x> mapW_px - camWScope *camera.zoom&&x< camWScope *camera.zoom+ mapW_px){///划入右边,接近循环 loopState =1; // Gdx.app.log("setPotion3","x:"+x+" y:"+y); }else { Gdx.app.error("setPotionError","未知位置 x:"+x+" y:"+y); } }else{ if(x< camWScope *camera.zoom){ x= camWScope *camera.zoom; }else if(x>(mapW_px + camWScope *camera.zoom-vw*camera.zoom)){ x=(mapW_px + camWScope *camera.zoom-vw*camera.zoom); } } if(y< camHScope *camera.zoom){ y= camHScope *camera.zoom; }else if(y>(mapH_px + camHScope *camera.zoom-vh*camera.zoom)){ y=(mapH_px + camHScope *camera.zoom-vh*camera.zoom); } if(!ifRefersh){ ifRefersh=ifCrossBorder( camera.position.x, camera.position.y,x,y); } camera.position.x=x; camera.position.y=y; // Gdx.app.log("setPotion","x:"+x+" y:"+y+" w:"+getCamera().viewportWidth*camera.zoom+" h:"+getCamera().viewportHeight*camera.zoom); if(ifRefersh){ updDrawAreas(); } //计算坐标 // if(ifTest){ tempCoord = GameMap.getHotCell(tempCoord,getSX(), mapH_px-getEY(), 1f, scale, mapW, 0, 0); csx=tempCoord.x; csy=tempCoord.y; tempCoord = GameMap.getHotCell(tempCoord,getEX(),mapH_px-getSY() , 1f, scale, mapW, 0, 0); cex=tempCoord.x; cey=tempCoord.y; cw=cex-csx; ch=cey-csy; // } return loopState; }
package com.zhfy.game.model.framework; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.scenes.scene2d.actions.MoveByAction; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.IntArray; import com.zhfy.game.MainGame; import com.zhfy.game.framework.tool.CHAsyncTask; import com.zhfy.game.config.ResConfig; import com.zhfy.game.framework.ComUtil; import com.zhfy.game.framework.GameMap; import java.util.ArrayList; public class CamerDAO { public boolean ifMove; private float camX; private float camY; private float camZ; private boolean ifLoop; private float camZoomMax; private float camZoomMin; private float camWScope; private float camHScope; private int mapW_px; private int mapH_px; private float vw; private float vh; private int mapW; private int mapH; private OrthographicCamera camera; public int loopState;//0 绘制左边 1绘制两侧 2只绘制右边 public Array<Boolean> drawAreas;// 绘制区域 private int refY; private ArrayList<SpriteDAO> mapSprites; private float scale; private MainGame game; //地图移动后计算这几个坐标 private Coord tempCoord; //左上坐标 public int csx; public int csy; //右下坐标 public int cex; public int cey; //坐标宽高 public int cw; public int ch; //public boolean ifTest; public CamerDAO ( MainGame game,OrthographicCamera camera,int w,int h,float viewW,float viewH,int mapW_px,int mapH_px,float zoomMin,float zoomMax,int refY,float scale,boolean ifLoop){ this.game=game; this.camera=camera; this.mapW=w; this.mapH=h; vw=viewW; vh=viewH; camWScope =viewW/2; camHScope =viewH/2 ; this.mapW_px =mapW_px; this.mapH_px =mapH_px; int zoomMaxx=mapW_px/mapH_px<mapH_px/mapW_px?mapH_px/mapW_px:mapW_px/mapH_px; camZoomMax=zoomMax< zoomMaxx? zoomMax:zoomMaxx; camZoomMin=zoomMin; this.refY=refY; this.scale=scale; this.ifLoop=ifLoop; initDrawAreas(); game.gameConfig.setIfDrawArmyMark(camera.zoom); ifMove=false; } private void initDrawAreas(){ if(drawAreas==null){ drawAreas=new Array<>(); }else { drawAreas.clear(); } //根据地图大小来绘制 int w = (int) ((mapW_px / ResConfig.Map.PT_SIDE) + 1); int h = (int) ((mapH_px / ResConfig.Map.PT_SIDE) + 1); int spliteCount = w * h; for(int i=0;i<spliteCount;i++){ drawAreas.add(false); } } private boolean ifXInScope(int x){ if(x>=getSX()&&x<=getEX()){ return true; }else { return false; } } private boolean ifYInScope(int y){ if(y>=getSY()&&y<=getEY()){ return true; }else { return false; } } //id 要移动到的坐标位置,moveSecond 移动用时 // zoomstate:0 无变化 1 放大 2 缩小 public void asyncMoveCameraToHexagon(int id, float targetX_px, float targetY_px, int moveSecond, int zoomstate, float zoomMin, float zoomMax ){ //int x=GameMap.getHX(id,mapW); //int y=GameMap.getHY(id,mapW); //float targetX_px=GameMap.getX_pxByHexagon(x,scale,0); //float targetY_px=GameMap.getY_pxByHexagon(x,y,mapH_px,scale,0,true); float moveX; int timeRate=10; if(camera.position.x>mapW_px){ moveX=(targetX_px-(camera.position.x-mapW_px))/(moveSecond*timeRate); }else { moveX=(targetX_px-camera.position.x)/(moveSecond*timeRate); } float moveY=(targetY_px-camera.position.y)/(moveSecond*timeRate);//Gdx.app.log("asyncMoveCameraToHexagon",camera.position.x+"->"+targetX_px+" "+ camera.position.y+"->"+targetY_px); CHAsyncTask task=new CHAsyncTask() { @Override public void onPreExecute() { } @Override public void onPostExecute(String result) { } @Override public String doInBackground() { float zoomv = 0; if(zoomstate==1){ zoomv=-0.01f; }else if(zoomstate==2){ zoomv=0.01f; } float zMi=0;float zMa = 0; if(zoomMin==0){zMi=getCamZoomMin(); }else{zMi=zoomMin;} if(zoomMax==0){zMa=getCamZoomMax(); }else{zMa=zoomMax;} for(int i=0,iMax=moveSecond*timeRate;i<iMax;i++){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } translateCam(moveX ,moveY,true); //logCamScope(); } if(zoomstate!=0){ while (setZoom(zoomv)){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } if(camera.zoom>zMa){ break; }else if(camera.zoom<zMi) { break; } //logCamScope(); } } return null; } }; game.asyncManager.loadTask(task); game.asyncManager.update(); } public void asyncMoveCameraToHexagon(int id, int moveSecond, int zoomstate, float zoomMin, float zoomMax ){ int x=GameMap.getHX(id,mapW); int y=GameMap.getHY(id,mapW); float targetX_px=GameMap.getX_pxByHexagon(x,scale,0); float targetY_px=GameMap.getY_pxByHexagon(x,y,mapH_px,scale,0,true); float moveX; int timeRate=10; if(camera.position.x>mapW_px){ moveX=(targetX_px-(camera.position.x-mapW_px))/(moveSecond*timeRate); }else { moveX=(targetX_px-camera.position.x)/(moveSecond*timeRate); } float moveY=(targetY_px-camera.position.y)/(moveSecond*timeRate);//Gdx.app.log("asyncMoveCameraToHexagon",camera.position.x+"->"+targetX_px+" "+ camera.position.y+"->"+targetY_px); CHAsyncTask task=new CHAsyncTask() { @Override public void onPreExecute() { } @Override public void onPostExecute(String result) { } @Override public String doInBackground() { float zoomv = 0; if(zoomstate==1){ zoomv=-0.01f; }else if(zoomstate==2){ zoomv=0.01f; } float zMi=0;float zMa = 0; if(zoomMin==0){zMi=getCamZoomMin(); }else{zMi=zoomMin;} if(zoomMax==0){zMa=getCamZoomMax(); }else{zMa=zoomMax;} for(int i=0,iMax=moveSecond*timeRate;i<iMax;i++){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } translateCam(moveX ,moveY,true); //logCamScope(); } if(zoomstate!=0){ while (setZoom(zoomv)){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } if(camera.zoom>zMa){ break; }else if(camera.zoom<zMi) { break; } //logCamScope(); } } return null; } }; game.asyncManager.loadTask(task); game.asyncManager.update(); } public void moveCameraToHexagon(int id, int moveSecond, int zoomstate, float zoomMin, float zoomMax ){ int x=GameMap.getHX(id,mapW); int y=GameMap.getHY(id,mapW); float targetX_px=GameMap.getX_pxByHexagon(x,scale,0); float targetY_px=GameMap.getY_pxByHexagon(x,y,mapH_px,scale,0,true); float moveX; int timeRate=10; if(camera.position.x>mapW_px){ moveX=(targetX_px-(camera.position.x-mapW_px))/(moveSecond*timeRate); }else { moveX=(targetX_px-camera.position.x)/(moveSecond*timeRate); } float moveY=(targetY_px-camera.position.y)/(moveSecond*timeRate);//Gdx.app.log("asyncMoveCameraToHexagon",camera.position.x+"->"+targetX_px+" "+ camera.position.y+"->"+targetY_px); float zoomv = 0; if(zoomstate==1){ zoomv=-0.01f; }else if(zoomstate==2){ zoomv=0.01f; } float zMi=0;float zMa = 0; if(zoomMin==0){zMi=getCamZoomMin(); }else{zMi=zoomMin;} if(zoomMax==0){zMa=getCamZoomMax(); }else{zMa=zoomMax;} for(int i=0,iMax=moveSecond*timeRate;i<iMax;i++){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } translateCam(moveX ,moveY,true); //logCamScope(); } if(zoomstate!=0){ while (setZoom(zoomv)){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } if(camera.zoom>zMa){ break; }else if(camera.zoom<zMi) { break; } //logCamScope(); } } } public void updDrawAreas(){ if(mapSprites!=null){ for(int i=0,iMax=mapSprites.size();i<iMax;i++){ SpriteDAO s=mapSprites.get(i); /*if (i==19) { drawAreas.set(i,true); }*/ boolean xb; if(ifLoop){ xb=(ComUtil.ifIntervalOverlap(getSX(),getEX(),s.getRefx(), (int) (s.getRefx()+s.getWidth())) ||ComUtil.ifIntervalOverlap(getSX(),getEX(), (int) (s.getRefx()+mapW_px), (int) (s.getRefx()+s.getWidth()+mapW_px)) ); }else { xb=ComUtil.ifIntervalOverlap(getSX(),getEX(),s.getRefx(), (int) (s.getRefx()+s.getWidth())); } boolean yb=ComUtil.ifIntervalOverlap(getSY(),getEY(),s.getRefy(), (int) (s.getRefy()+s.getHeight())); if(xb&&yb){ drawAreas.set(i,true); }else { drawAreas.set(i,false); } // Gdx.app.log("updDrawAreas",i+":"+drawAreas.get(i)+ " x:" + s.getRefx() + " y:" + s.getRefy() + " x2:" + (s.getRefx()+s.getWidth()) + " y2:" + (s.getRefy()+s.getHeight())+" sx:"+getSX()+" ex:"+getEX()+" sy:"+getSY()+" ey:"+getEY()+" xb:"+xb+" yb:"+yb); } } } public int translateCam(float x,float y,boolean ifRefersh){ return setPotion(camera.position.x+x,camera.position.y+y,ifRefersh); // camera.translate(x,y,0); } //!对x,y进行检查 loopState 绘制左边 1绘制两侧 2只绘制右边 public int setPotion(float x,float y,boolean ifRefersh){ loopState =0;//0 绘制左边 1绘制两侧 2只绘制右边 if(ifLoop) { //1 在左地图内 if(x>= camWScope *camera.zoom&&x<= mapW_px - camWScope *camera.zoom){ loopState =0; // Gdx.app.log("setPotion0","x:"+x+" y:"+y); //2 在右地图向左地图滑动 }else if(x>= camWScope *camera.zoom+ mapW_px ){ x=x- mapW_px; loopState =0; // Gdx.app.log("setPotion1","x:"+x+" y:"+y); //3 向左划出左边界 }else if(x< camWScope*camera.zoom){ // Gdx.app.log("setPotion2","x:"+x+" y:"+y); loopState =1; x=x+ mapW_px; //4 向右划出左地图的右边界 }else if(x> mapW_px - camWScope *camera.zoom&&x< camWScope *camera.zoom+ mapW_px){///划入右边,接近循环 loopState =1; // Gdx.app.log("setPotion3","x:"+x+" y:"+y); }else { Gdx.app.error("setPotionError","未知位置 x:"+x+" y:"+y); } }else{ if(x< camWScope *camera.zoom){ x= camWScope *camera.zoom; }else if(x>(mapW_px + camWScope *camera.zoom-vw*camera.zoom)){ x=(mapW_px + camWScope *camera.zoom-vw*camera.zoom); } } if(y< camHScope *camera.zoom){ y= camHScope *camera.zoom; }else if(y>(mapH_px + camHScope *camera.zoom-vh*camera.zoom)){ y=(mapH_px + camHScope *camera.zoom-vh*camera.zoom); } if(!ifRefersh){ ifRefersh=ifCrossBorder( camera.position.x, camera.position.y,x,y); } camera.position.x=x; camera.position.y=y; // Gdx.app.log("setPotion","x:"+x+" y:"+y+" w:"+getCamera().viewportWidth*camera.zoom+" h:"+getCamera().viewportHeight*camera.zoom); if(ifRefersh){ updDrawAreas(); } //计算坐标 // if(ifTest){ tempCoord = GameMap.getHotCell(tempCoord,getSX(), mapH_px-getEY(), 1f, scale, mapW, 0, 0); csx=tempCoord.x; csy=tempCoord.y; tempCoord = GameMap.getHotCell(tempCoord,getEX(),mapH_px-getSY() , 1f, scale, mapW, 0, 0); cex=tempCoord.x; cey=tempCoord.y; cw=cex-csx; ch=cey-csy; // } return loopState; } public boolean getIfMove() { if(camX!=camera.position.x||camY!=camera.position.y||camZ!=camera.zoom){ camX=camera.position.x; camY=camera.position.y; camZ=camera.zoom; return true; }else { return false; } } //中心点缩放 根据鼠标中心点缩放 public int setZoomForMouse(float cx,float cy,float zoomV){ if(camera.zoom<camZoomMin){ camera.zoom=camZoomMin; return translateCam(0,0,false); }else if(camera.zoom>camZoomMax){ camera.zoom=camZoomMax; return translateCam(0,0,false); } camera.zoom +=zoomV; game.gameConfig.setIfDrawArmyMark(camera.zoom); //Gdx.app.log("Zoom","cx:"+cx+" cy:"+cy+" zoomV:"+zoomV+" zoom:"+camera.zoom); return setPotion(camera.position.x+(vw/2-cx)*zoomV,camera.position.y-(vh/2-cy)*zoomV,true);// -(cy-vh) } public boolean setZoom(float v){ if(camera.zoom<camZoomMin){ camera.zoom=camZoomMin; return false; }else if(camera.zoom>camZoomMax){ camera.zoom=camZoomMax; return false; }else { camera.zoom +=v; game.gameConfig.setIfDrawArmyMark(camera.zoom); return true; } } public float getZoom(){ return camera.zoom; } public float getCamZoomMax() { return camZoomMax; } public void setCamZoomMax(float camZoomMax) { this.camZoomMax = camZoomMax; } public float getCamZoomMin() { return camZoomMin; } public void setCamZoomMin(float camZoomMin) { this.camZoomMin = camZoomMin; } public float getCamWScope() { return camWScope; } public void setCamWScope(float camWScope) { this.camWScope = camWScope; } public float getCamHScope() { return camHScope; } public void setCamHScope(float camHScope) { this.camHScope = camHScope; } public float getMapW_px() { return mapW_px; } public void setMapW_px(int mapW_px) { this.mapW_px = mapW_px; } public float getMapH_px() { return mapH_px; } public void setMapH_px(int mapH_px) { this.mapH_px = mapH_px; } public OrthographicCamera getCamera() { return camera; } public void setCamera(OrthographicCamera camera) { this.camera = camera; } public void logCamScope(){//x,y以左上为原点的范围 Gdx.app.log("camScope"," x:"+camera.position.x+" y:"+(camera.position.y)+" fy:"+(mapH_px -camera.position.y)+" w:"+vw*camera.zoom +" h:"+vh*camera.zoom+ " zoom:"+camera.zoom+" sx:"+getSX()+" sy:"+getSY()+" ex:"+getEX()+" ey:"+getEY()); /*if(mapSprites!=null){ for(int i=0,iMax=drawAreas.size;i<iMax;i++){ if(drawAreas.get(i)){ } } }*/ } //左上为原点 public int getSX(float x){ return (int) (x-vw*camera.zoom /2); } public int getSY(float y){ return (int) (y-vh*camera.zoom/2); } public int getEX(float x){ return (int) (x+vw*camera.zoom /2); } public int getEY(float y){ return (int) (y+vh*camera.zoom/2); } public int getSX(){ return (int) (camera.position.x-vw*camera.zoom /2); } public int getSY(){ return (int) (camera.position.y-vh*camera.zoom/2); } public int getEX(){ return (int) (camera.position.x+vw*camera.zoom /2); } public int getEY(){ return (int) (camera.position.y+vh*camera.zoom/2); } public void setMapSprites(ArrayList<SpriteDAO> mapSprites) { this.mapSprites=mapSprites; updDrawAreas(); } //判断 移动时判断是否跨界 private boolean ifCrossBorder(float x1,float y1,float x2,float y2){ int area1=GameMap.getAreaId(mapSprites,mapW_px,getSX(x1),getSY(y1)); int area2=GameMap.getAreaId(mapSprites,mapW_px,getEX(x1),getSY(y1)); int area3=GameMap.getAreaId(mapSprites,mapW_px,getSX(x1),getEY(y1)); int area4=GameMap.getAreaId(mapSprites,mapW_px,getEX(x1),getEY(y1)); int area11=GameMap.getAreaId(mapSprites,mapW_px,getSX(x2),getSY(y2)); int area12=GameMap.getAreaId(mapSprites,mapW_px,getEX(x2),getSY(y2)); int area13=GameMap.getAreaId(mapSprites,mapW_px,getSX(x2),getEY(y2)); int area14=GameMap.getAreaId(mapSprites,mapW_px,getEX(x2),getEY(y2)); if(area1==area11&&area2==area12&&area3==area13&&area4==area14){ return false; } return true; } }
2.根据该范围计算显示陆地的坐标,陆地图片为1024*1024的图片
private void initDrawAreas(){ if(drawAreas==null){ drawAreas=new Array<>(); }else { drawAreas.clear(); } //根据地图大小来绘制 int w = (int) ((mapW_px / ResConfig.Map.PT_SIDE) + 1); int h = (int) ((mapH_px / ResConfig.Map.PT_SIDE) + 1); int spliteCount = w * h; for(int i=0;i<spliteCount;i++){ drawAreas.add(false); } } public void updDrawAreas(){ if(mapSprites!=null){ for(int i=0,iMax=mapSprites.size();i<iMax;i++){ SpriteDAO s=mapSprites.get(i); /*if (i==19) { drawAreas.set(i,true); }*/ boolean xb; if(ifLoop){ xb=(ComUtil.ifIntervalOverlap(getSX(),getEX(),s.getRefx(), (int) (s.getRefx()+s.getWidth())) ||ComUtil.ifIntervalOverlap(getSX(),getEX(), (int) (s.getRefx()+mapW_px), (int) (s.getRefx()+s.getWidth()+mapW_px)) ); }else { xb=ComUtil.ifIntervalOverlap(getSX(),getEX(),s.getRefx(), (int) (s.getRefx()+s.getWidth())); } boolean yb=ComUtil.ifIntervalOverlap(getSY(),getEY(),s.getRefy(), (int) (s.getRefy()+s.getHeight())); if(xb&&yb){ drawAreas.set(i,true); }else { drawAreas.set(i,false); } // Gdx.app.log("updDrawAreas",i+":"+drawAreas.get(i)+ " x:" + s.getRefx() + " y:" + s.getRefy() + " x2:" + (s.getRefx()+s.getWidth()) + " y2:" + (s.getRefy()+s.getHeight())+" sx:"+getSX()+" ex:"+getEX()+" sy:"+getSY()+" ey:"+getEY()+" xb:"+xb+" yb:"+yb); } } }
//判断 移动时判断是否跨界
private boolean ifCrossBorder(float x1,float y1,float x2,float y2){
int area1=GameMap.getAreaId(mapSprites,mapW_px,getSX(x1),getSY(y1));
int area2=GameMap.getAreaId(mapSprites,mapW_px,getEX(x1),getSY(y1));
int area3=GameMap.getAreaId(mapSprites,mapW_px,getSX(x1),getEY(y1));
int area4=GameMap.getAreaId(mapSprites,mapW_px,getEX(x1),getEY(y1));
int area11=GameMap.getAreaId(mapSprites,mapW_px,getSX(x2),getSY(y2));
int area12=GameMap.getAreaId(mapSprites,mapW_px,getEX(x2),getSY(y2));
int area13=GameMap.getAreaId(mapSprites,mapW_px,getSX(x2),getEY(y2));
int area14=GameMap.getAreaId(mapSprites,mapW_px,getEX(x2),getEY(y2));
if(area1==area11&&area2==area12&&area3==area13&&area4==area14){
return false;
}
return true;
}
3.根据该范围计算显示装饰的坐标
这里我修改了原来游戏数据中的hexagon类,用来存储游戏坐标,和region信息,在绘制时直接遍历其并调用
private void initTileTextureTegionDAO(){ HexagonData h; TextureRegionDAO tt,st;int sx,sy;float sx_Px,sy_Px; int mapH_px; // int mapTile_refX=12,mapTile_refY=18; float mapTile_refX=ResConfig.Map.MAPTILE_REFX*ResConfig.Map.MAP_SCALE; float mapTile_refY=ResConfig.Map.MAPTILE_REFY*ResConfig.Map.MAP_SCALE; for(int i=0,iMax=hexagonDatas.size;i<iMax;i++){ h=hexagonDatas.get(i); // sx=GameMap.getHexagonX1F(); //sx_Px=GameMap.getHexagonX1F(sx,sy,1); //sy_Px=GameMap.getH_px(masterData.getWidth(), masterData.getHeight(), 1)-GameMap.getHexagonY1F(sx,sy,1); //sy_Px=GameMap.getHexagonY1F(sx,sy,1); //int x = (armyData.getHexagonIndex() % btl.masterData.getWidth()) + 1; //int y = (armyData.getHexagonIndex() / btl.masterData.getWidth()) + 1; sx=GameMap.getHX(i,masterData.getWidth())+1; sy=GameMap.getHY(i,masterData.getWidth())+1; mapH_px=GameMap.getH_px(masterData.getWidth(), masterData.getHeight(), 1); //因为地图的边缘相接部分并不是取最右,而是右数第二个坐标相接来实现地图循环 h.source_x=GameMap.getX_pxByHexagon(sx,1,mapTile_refX); h.source_y=GameMap.getY_pxByHexagon(sx,sy,mapH_px,1,mapTile_refY,true); if(h.getBackTile()!=0){ tt=game.getImgLists().getTextureByName(h.getBackTile()+"_"+h.getBackIdx()); if(tt!=null){ /* st=new TextureRegionDAO(); st.setTextureRegionAndSize(tt.getTextureRegion()); st.setRefx((int) (sx_Px+((h.getBackRefX()+ tt.getRefx() ) *ResConfig.Map.MAP_SCALE))); st.setRefy((int) (sy_Px+((h.getBackRefY() + tt.getRefy()) *ResConfig.Map.MAP_SCALE))); */ h.tile1=tt; } } if(h.getForeTile()!=0){ tt=game.getImgLists().getTextureByName(h.getForeTile()+"_"+h.getForeIdx()); if(tt!=null){ /*st=new TextureRegionDAO(); st.setTextureRegionAndSize(tt.getTextureRegion()); st.setRefx((int) (sx_Px+((h.getForeRefX() + tt.getRefx() ) *ResConfig.Map.MAP_SCALE))); st.setRefy((int) (sy_Px+ ((h.getForeRefY() + tt.getRefy() ) *ResConfig.Map.MAP_SCALE))); */h.tile2=tt; } } } }
4.绘制
1.陆地的绘制
ps:loopState代表循环状态 0,地图左侧, 1 地图中央交替 2地图右侧
for(i=0,iMax=cam.drawAreas.size;i<iMax;i++){ if (cam.drawAreas.get(i)) { SpriteDAO s=mainSprites.get(i); if(cam.loopState==0){ batch.draw(s.getSprite(), s.getRefx(), s.getRefy(), getOriginX(), getOriginY(), s.getWidth(), s.getHeight(), getZoom(), getZoom(), getRotation()); // Gdx.app.log("drawS", s.getName() + ": x:" + s.getRefx() + " y:" + s.getRefy()); }else if(cam.loopState==1){ batch.draw(s.getSprite(), s.getRefx(), s.getRefy(), getOriginX(), getOriginY(), s.getWidth(), s.getHeight(), getZoom(), getZoom(), getRotation()); batch.draw(s.getSprite(), s.getRefx()+mapW_px*this.zoom, s.getRefy(), getOriginX(), getOriginY(), s.getWidth(), s.getHeight(), getZoom(), getZoom(), getRotation()); }else if(cam.loopState==2){ batch.draw(s.getSprite(), s.getRefx()+mapW_px*this.zoom, s.getRefy(), getOriginX(), getOriginY(), s.getWidth(), s.getHeight(), getZoom(), getZoom(), getRotation()); } } }
2.装饰的绘制
public static void drawTileForMap(Batch batch,Fb2Smap smapDao, CamerDAO cam, float scale, int mapW_px, int mapH_px) { if (smapDao.hexagonDatas != null && smapDao.hexagonDatas.size > 0) { int x = 0; int y = 0; float hexgaon_x1; float hexgaon_y1; // Gdx.app.log("setColor1","begin"+" "); int i = 0, j = 0,id,iMax = cam.cw+2,jMax=cam.ch+3; for (; j<jMax; j++) { for (i=0;i<iMax; i++) { x=cam.csx+i; if(smapDao.ifLoop&&x>smapDao.masterData.getWidth()){ x=x-smapDao.masterData.getWidth(); } y=cam.csy+j; id=x-1+(y-1)*smapDao.masterData.getWidth(); if ( id>0&&id<smapDao.hexagonDatas.size ) { Fb2Smap.HexagonData h=smapDao.hexagonDatas.get(id); if(h.tile1!=null){ batch.draw(h.tile1.getTextureRegion(), h.source_x+mapW_px+h.getBackRefX()* ResConfig.Map.MAP_SCALE-h.tile1.getRefx()*ResConfig.Map.MAP_SCALE, h.source_y+h.getBackRefY()* ResConfig.Map.MAP_SCALE-h.tile1.getRefy()*ResConfig.Map.MAP_SCALE ,0,0,h.tile1.getW(),h.tile1.getH(),1,1,0); } } } } } }
5.地图循环的一些坑
在cam中我们实现了loopstate方法,当地图是一个可循环的地图时,根据该方法来实现绘制,超过部分额外在地图范围外绘制一遍,
但是因为循环原因,会出现一些问题,如下图
记录下我踩过的坑:
1.因为绘制顺序问题导致边缘的陆地线迟迟去不掉,解决方法是 调整绘制顺序
2.因为采用的地图宽度问题导致无法衔接,解决方法是 增加地图偏移,减一定的数值