**作为一个平面地图 位置加载以及 像素 转 格子位置 以及 格子位置 转 唯一的key key 转 格子标识 格子转 像素 **
为了展示 效果 图片为 unity 实际 代码是 ts
3d 和 2d 平面 加载基本是一样的 都可以用这套代码 为什么要做 六边形加载 第一 范围 距离是一样的 第二 需求问题
首先 是像素坐标转换成 格子坐标
在这里插入代码片
```/**
* 六边形 像素位置转换格子位置根据 位置转换
* 3d 是 x z 2d 是 x y
// 格子的 宽度
public static RANCH_TILE_WIDTH = 10;
// 格子的 高度
public static RANCH_TILE_HEIGHT = 8.66666;
// 左偏移量
public static SIDE_OFFSET_X = (ITileHelper.RANCH_TILE_WIDTH -(ITileHelper.RANCH_TILE_HEIGHT / 2)) / 2;
// 高的 偏移量
public static SIDE_OFFSET_Y = ITileHelper.RANCH_TILE_HEIGHT / 2;
// 行的高度
public static RANCH_ROW_HEIGHT = ITileHelper.RANCH_TILE_HEIGHT / 2;
// 列的宽度
public static RANCH_COLUMN_WIDTH = ITileHelper.RANCH_TILE_HEIGHT / 2 + ITileHelper.SIDE_OFFSET_X;
* @param x
* @param z
*/
public getHexagonalPixelToTileWithPosition(x: number, z: number, factor: number = 1) {
// 边的偏移 是 (格子的宽度 - 高度 /2)/ 2
let sideOffsetX = ITileHelper.SIDE_OFFSET_X
// 这个是格子的宽度 / 2 + 偏移量 也就是格子的 4分之3 处;
let columnWidth = ITileHelper.RANCH_COLUMN_WIDTH;
// 这个是 高度 / 2
let rowHeight = ITileHelper.RANCH_ROW_HEIGHT;
// 这个是格子的高度
let tileHeight = ITileHelper.RANCH_TILE_HEIGHT;
// 宽度 / 2
let sideLengthX = columnWidth / 2;
// 一个 数租记录 距离的位置 来辅助 定位 记录四个位置 最后来比较 里那个位置最近来辅助定位
if (!this._center) {
let lift = sideLengthX / 2;
let centerX = lift + columnWidth;
let centerZ = tileHeight / 2;
let arr: Vec3[] = [];
arr.push(new Vec3(lift, 0, centerZ));
arr.push(new Vec3(centerX, 0, centerZ - rowHeight));
arr.push(new Vec3(lift, 0, centerZ + rowHeight));
arr.push(new Vec3(centerX + columnWidth, 0, centerZ));
this._center = arr;
}
// 获取理论的格子中心偏移点
let xx = x - sideOffsetX;
// 正反方向 如果 2d 则等于 z
let zz = -z;
let referenceX = Math.floor(xx / (columnWidth * 2));
let referenceZ = Math.floor(zz / (rowHeight * 2));
// Relative x and y position on the base square of the grid-aligned tile
let rel = new Vec3(xx - referenceX * (columnWidth * 2), 0, zz - referenceZ * (rowHeight * 2));
// Adjust the reference point to the correct tile coordinates
referenceX *= 2;
let nearest = 0;
let minDist = 10000000;
// 循环对比最近的距离
for (let i = 0; i < this._center.length; ++i) {
var dc = this._center[i].clone().subtract(rel).length();
if (dc < minDist) {
minDist = dc;
nearest = i;
}
}
let outTileV3 = v3(referenceX, 0, -referenceZ);
outTileV3.add(PolygonRectControl._offsetsStaggerX[nearest]);
outTileV3.multiplyScalar(factor);
return outTileV3;
}
private static _offsetsStaggerX: Vec3[] = [
new Vec3(0, 0, 0),
new Vec3(1, 0, 1),
new Vec3(1, 0, 0),
new Vec3(2, 0, 0),
]
然后是 格子坐标转换成像素坐标
/// <summary>
/// 将格子坐标转像素坐标
/// </summary>
/// <param name="tileV3"></param>
/// <param name="outPosV3"></param>
public static TileToPixel(x: number, z: number, Vector3: Vec3 = null): Vec3 {
let outPosV3 = new Vec3();
let tileX = x;
let tileZ = z;
let Z = tileZ * (ITileHelper.RANCH_ROW_HEIGHT + ITileHelper.SIDE_OFFSET_Y);
if (PolygonRectControl.DoStaggerX(tileX)) {
Z -= ITileHelper.RANCH_ROW_HEIGHT;
}
let X = tileX * (ITileHelper.RANCH_COLUMN_WIDTH);
outPosV3.x = X;
outPosV3.y = 1;
outPosV3.z = Z;
return outPosV3;
}
public static DoStaggerX(x: number): boolean {
return x % 2 != 0;
}
所有的格子坐标会有一个 key 值作为记录 方便读取格子 或者 获取区域格子等等
/// <summary>
/// 将格子坐标转格子标识 注意 不能出现负数 出现负数会 出现错误
/// </summary>
/// <param name="tileX"></param>
/// <param name="tileY"></param>
/// <param name="tileZ"></param>
/// <returns>格子标识</returns>
public static TileToTileKey(tileX: number, tileY: number, tileZ: number): number {
return 1000000000 + tileX * 1000000 + tileY * 1000 + tileZ;
}
然后 通过 key值 转换成格子坐标
/// <summary>
/// 将格子标识转格子坐标
/// </summary>
/// <param name="tileKey"></param>
/// <param name="outTileV3"></param>
public static TileKeyToTile(tileKey: number): Vec3 {
let baseKey = (tileKey - 1000000000) //;
let x = (baseKey / 1000000) % 1000 | 0;
let y = (baseKey / 1000) % 1000 | 0;
//1040999999
let z = (baseKey / 1) % 10000 | 0;
// 这里片段就是 可能出现 负数 以后自己优化一下 正常来讲不会出现负坐标的格子 要是会有 负坐标的格子 就需要改//一下 key 的生成方式 和解析方式
if(z >= 9000){
z = -(10000 - z);
x+=1
}else if(z < -9000){
z = 10000 + z;
x-=1
}
let outTileV3 = new Vec3();
outTileV3.x = x;
outTileV3.y = y;
outTileV3.z = z;
return outTileV3;
}
以上就是完成的六边形格子 处理 以后有时间了在吧 摄像机 区域加载 动态显示 隐藏 或者缓冲池加载写上