因为准备做世界大战,所以准备了一张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);
                        }
                    }
View Code

  //六边形的绘制方法

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);
                            }
 
                        }
View Code

//获取六边形坐标

// 六边形网格定位
    // @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;
        
    }
View Code

//改变中心点

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;
            
        }
View Code

完整代码:

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;
    }
    
}
View Code

感慨下:数学不学好,做游戏空流泪  ----记于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;
    }




}
cam完整代码

 

    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.因为采用的地图宽度问题导致无法衔接,解决方法是 增加地图偏移,减一定的数值

 

posted on 2019-03-05 17:39  黑狱  阅读(384)  评论(0编辑  收藏  举报