六角形格子地図座標計算と変換


//            ,            

var WorldMapManager = function () {
    this.mapSize = null;     //     ,  
    this.curViewPos = null;  //          

    //           
    this.init = function (mapSize, tileSize) {
        this.mapSize = {
                width  : globalConsts.WorldMapSize.width * globalConsts.TileSize.width + globalConsts.TileSize.width / 2,
                height : globalConsts.WorldMapSize.height * ((globalConsts.TileSize.height - globalConsts.TileSize.hex) / 2 + globalConsts.TileSize.hex) + 
                            (globalConsts.TileSize.height - globalConsts.TileSize.hex) / 2
            };
        this.tileSize = globalConsts.TileSize;
    };

    //          cell
    this.mapPosToTile = function (pos) {
        //              a   
        var a = this.tileSize.width / Math.sqrt(3);
        var x = pos.x, y = (this.mapSize.height - pos.y) / this.tileSize.height * a * 2 + a / 2;    //   a / 2                  a / 2
        
        //            CELL   
        var points = new Array(cc.p(0, 0), cc.p(0, 0), cc.p(0, 0));
        //       
        var dist;
        //      index:      
        var i, index;
        //     3      ,        ,     
        var g_MinDistance2 = Math.pow(a * Math.sqrt(3) / 2, 2);
        //    、 
        var g_unitx = a * Math.sqrt(3);     //sqrt(3) * a
        var g_unity = a * 1.5;              //a * 3 / 2
        //            
        var mindist= Math.ceil(Math.pow(g_unitx, 2) + Math.pow(g_unity, 2));
        //                
        var cx = parseInt(x/g_unitx);
        var cy = parseInt(y/g_unity);

        points[0].x = parseInt(g_unitx * cx);
        points[1].x = parseInt(g_unitx * (cx+0.5));
        points[2].x = parseInt(g_unitx * (cx+1));
        //  cy     ,         
        if(cy % 2 == 0)
        {
            //   ,         
            points[0].y = points[2].y = parseInt(g_unity * cy);
            points[1].y = parseInt(g_unity * (cy+1));
        }    
        else
        {
            //   ,         
            points[0].y = points[2].y = parseInt(g_unity * (cy+1));
            points[1].y = parseInt(g_unity * cy);
        }
        
        //           
        function distance2(x1, y1, x2, y2)
        {
            return ((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
        }

        //              
        for(i = 0; i < 3; ++i)
        {
            //       
            dist = distance2(x, y, points[i].x, points[i].y);

            //         
            if(dist < g_MinDistance2)
            {
                index = i;
                break;
            }

            //          
            if(dist < mindist)
            {
                mindist = dist;
                index = i;
            }
        }
        
        // x   0        1   cell.x ( x       -1   )
        // cy        + 1,       + 1,  1             y    a / 2 ( y           -1 )
        return {x : cx - (index > 0? 0 : 1), y : cy + (cy % 2 + index % 2) % 2 - 1};
    };
    
    //           
    this.tilePosToMap = function (pos) {
        var tileCenter, xPixel, yPixel;

        tileCenter = (pos.x * this.tileSize.width) + this.tileSize.width / 2;
        xPixel = tileCenter + (pos.y % 2) * this.tileSize.width / 2;
        yPixel = this.tileSize.height / 2 + pos.y * (this.tileSize.height / 2 + this.tileSize.hex / 2);

        //        ,y      ,    
        yPixel = this.mapSize.height - yPixel;

        return cc.p(xPixel, yPixel);
    };
    
    //                 
    this.getAdjacentHexagonCenterPointDistance = function (isLeftAndRight) {
        if (isLeftAndRight) {
            return this.tileSize.width;
        } else {
            return Math.sqrt(Math.pow((this.tileSize.height + this.tileSize.hex) / 2, 2) + Math.pow(this.tileSize.width / 2, 2));
        }
    };
};

//   

WorldMapManager.sharedInstance = null;

WorldMapManager.getInstance = function(){
    if (WorldMapManager.sharedInstance == null) {
        WorldMapManager.sharedInstance = new WorldMapManager();
        WorldMapManager.sharedInstance.init();
    }
    return WorldMapManager.sharedInstance;
};
var tileCalculate = {

    //      tilePos                 0~1 return 1
    getTwoTileDistance : function(lightTilePos, findTilePos) {
        var offX = 1, offY = 1;   //    findTilePos   lightTilePos   ,    
        var tilePos, count;

        if (lightTilePos.y === findTilePos.y) {
            return Math.abs(lightTilePos.x - findTilePos.x);
        } else if (lightTilePos.x === findTilePos.x) {
            return Math.abs(lightTilePos.y - findTilePos.y);
        } else {
            count = 0;
            tilePos = {x:findTilePos.x, y:findTilePos.y};
            //   ,   
            if (lightTilePos.x < tilePos.x) {
                offX = -1;
            }
            //   ,   
            if (lightTilePos.y < tilePos.y) {
                offY = -1;
            }
            do {
                ++count;
                tilePos.x += tilePos.y % 2 > 0 ? (offX > 0 ? offX : 0) : (offX < 0 ? offX : 0);
                tilePos.y += offY;
            } while (lightTilePos.x !== tilePos.x && lightTilePos.y !== tilePos.y);
            count += Math.abs(lightTilePos.x - tilePos.x) + Math.abs(lightTilePos.y - tilePos.y);
            return count;
        }
    },

    //         ,          
    getAroundTilePos : function(tilePos) {
        if (tilePos.y % 2 > 0) {
            return [{x : tilePos.x, y : tilePos.y - 1}, {x : tilePos.x, y : tilePos.y + 1}, //   
                    {x : tilePos.x - 1, y : tilePos.y}, {x : tilePos.x + 1, y : tilePos.y}, //   
                    {x : tilePos.x + 1, y : tilePos.y - 1}, {x : tilePos.x + 1, y : tilePos.y + 1}];    //   ,  
        } else {
            return [{x : tilePos.x, y : tilePos.y - 1}, {x : tilePos.x, y : tilePos.y + 1}, //   
                    {x : tilePos.x - 1, y : tilePos.y}, {x : tilePos.x + 1, y : tilePos.y}, //   
                    {x : tilePos.x - 1, y : tilePos.y - 1}, {x : tilePos.x - 1, y : tilePos.y + 1}];    //   ,  
        }
    },

    //         ,           
    getAroundTwoLapsTilePos : function(tilePos) {
        var i, j, tiles1, tiles2 = [];
        var tilePoses = {};

        //                     
        tiles1 = this.getAroundTilePos(tilePos);
        for (i in tiles1) {
            tiles2 = this.getAroundTilePos(tiles1[i]);
            for (j in tiles2) {
                if (tiles2[j].x !== tilePos.x || tiles2[j].y !== tilePos.y) {
                    tilePoses[JSON.stringify(tiles2[j])] = tiles2[j];
                }
            }
        }

        return tilePoses;
    },

};