Files
slgclient/assets/scripts/map/MapUtil.ts
2025-11-18 18:38:53 +08:00

298 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { _decorator, Size, Vec2, size, v2, TiledMap, UITransform, game, view } from 'cc';
import MapCommand from "./MapCommand";
export default class MapUtil {
//地图像素大小
protected static _mapPixelSize: Size = null;
//地图锚点偏移量
protected static _mapOffsetPoint: Vec2 = null;
//格子大小
protected static _tileSize: Size = size(256, 128);;
//地图大小 宽高需要相同
protected static _mapSize: Size = size(20, 20);
//地图 (0, 0)点对应的像素坐标
protected static _zeroPixelPoint: Vec2 = v2(0, 0);
//划分区域的格子大小
protected static _areaCellSize: Size = null;
protected static _areaSize: Size = null;
// 初始化地图配置
public static initMapConfig(map: TiledMap): void {
var uit = map.node.getComponent(UITransform);
this._mapPixelSize = size(uit.width, uit.height);
this._mapOffsetPoint = v2(uit.width * uit.anchorX, uit.height * uit.anchorY);
this._tileSize = map.getTileSize();
this._mapSize = map.getMapSize();
this._mapPixelSize = size(uit.width, uit.height);
this._zeroPixelPoint.x = this._mapSize.width * this._tileSize.width * 0.5;
this._zeroPixelPoint.y = this._mapSize.height * this._tileSize.height - this._tileSize.height * 0.5;
var vsize = view.getVisibleSize();
//划分区域的大小
let showH: number = Math.min(Math.ceil(vsize.height / this._tileSize.height / 2) * 2 + 2, this._mapSize.height);
this._areaCellSize = size(showH, showH);
this._areaSize = size(Math.ceil(this._mapSize.width / showH), Math.ceil(this._mapSize.height / showH));
}
/**地图的像素大小*/
public static get mapPixcelSize(): Size {
return this._mapPixelSize;
}
public static get mapSize(): Size {
return this._mapSize;
}
/**格子数量*/
public static get mapCellCount(): number {
return this._mapSize.width * this._mapSize.height;
}
/**每个区域包含的格子数量*/
public static get areaCellSize(): Size {
return this._areaCellSize;
}
/**区域大小*/
public static get areaSize(): Size {
return this._areaSize;
}
/**区域数量*/
public static get areaCount(): number {
return this._areaSize.width * this._areaSize.height;
}
/**获取格子id*/
public static getIdByCellPoint(x: number, y: number): number {
return x + y * this._mapSize.width;
}
/**获取格子坐标*/
public static getCellPointById(id: number): Vec2 {
return v2(id % this._mapSize.width, Math.floor(id / this._mapSize.width));
}
/**获取区域id*/
public static getIdByAreaPoint(x: number, y: number): number {
return x + y * this._areaSize.width;
}
/**获取区域坐标*/
public static getAreaPointById(id: number): Vec2 {
return v2(id % this._areaSize.width, Math.floor(id / this._areaSize.width));
}
/**获取格子为中点的九宫格id列表*/
public static get9GridCellIds(id:number):number[] {
return [
id + this._mapSize.width - 1, id + this._mapSize.width, id + this._mapSize.width + 1,
id - 1, id, id + 1,
id - this._mapSize.width - 1, id - this._mapSize.width, id - this._mapSize.width + 1
];
}
public static getSideIdsForRoleCity(id:number):number[] {
return [
id + this._mapSize.width * 2 - 2, id + this._mapSize.width * 2 - 1, id + this._mapSize.width * 2, id + this._mapSize.width * 2 + 1, id + this._mapSize.width * 2 + 2,
id + this._mapSize.width - 2, id + this._mapSize.width + 2,
id - 2, id + 2,
id - this._mapSize.width - 2, id - this._mapSize.width + 2,
id - this._mapSize.width * 2 - 2, id - this._mapSize.width * 2 - 1, id - this._mapSize.width - 1, id - this._mapSize.width * 2 + 1, id - this._mapSize.width * 2 + 2
];
}
public static getSideIdsForSysCity(x, y, level): number[] {
let ids: number[] = [];
var dis = 0;
if(level >= 8){
dis = 3;
}else if(level >= 5){
dis = 2;
}else {
dis = 1;
}
//上
for (let tx = x-dis; tx <= x+dis; tx++) {
var ty:number = y + dis;
var id = MapUtil.getIdByCellPoint(tx, ty);
ids.push(id);
}
//下
for (let tx = x-dis; tx <= x+dis; tx++) {
var ty:number = y - dis;
var id = MapUtil.getIdByCellPoint(tx, ty);
ids.push(id);
}
//左
for (let ty = y-dis; ty <= y+dis; ty++) {
var tx:number = x - dis;
var id = MapUtil.getIdByCellPoint(tx, ty);
ids.push(id);
}
//右
for (let ty = y-dis; ty <= y+dis; ty++) {
var tx:number = x + dis;
var id = MapUtil.getIdByCellPoint(tx, ty);
ids.push(id);
}
return ids;
}
/**获取区域为中点的九宫格id列表*/
public static get9GridAreaIds(id: number): number[] {
return [
id + this._areaSize.width - 1, id + this._areaSize.width, id + this._areaSize.width + 1,
id - 1, id, id + 1,
id - this._areaSize.width - 1, id - this._areaSize.width, id - this._areaSize.width + 1
];
}
public static get9GridVaildAreaIds(id: number): number[] {
let list: number[] = [];
let totalList: number[] = this.get9GridAreaIds(id);
for (let i: number = 0; i < totalList.length; i++) {
if (this.isVaildAreaId(totalList[i])) {
list.push(totalList[i]);
}
}
return list;
}
public static getAreaPointByCellPoint(x: number, y: number): Vec2 {
return v2(Math.floor(x / this._areaCellSize.width), Math.floor(y / this._areaCellSize.height));
}
/**获取区域id*/
public static getAreaIdByCellPoint(x: number, y: number): number {
let point: Vec2 = this.getAreaPointByCellPoint(x, y);
return this.getIdByAreaPoint(point.x, point.y);
}
public static getStartCellPointByAreaPoint(x: number, y: number): Vec2 {
return v2(x * this._areaCellSize.width, y * this._areaCellSize.height);
}
public static getEndCellPointByAreaPoint(x: number, y: number): Vec2 {
return v2((x + 1) * this._areaCellSize.width, (y + 1) * this._areaCellSize.height);
}
public static getVaildAreaIdsByPixelPoints(...points: Vec2[]): number[] {
let list: number[] = [];
for (let i: number = 0; i < points.length; i++) {
let cellPoint: Vec2 = this.mapPixelToCellPoint(points[i]);
let areaPoint: Vec2 = this.getAreaPointByCellPoint(cellPoint.x, cellPoint.y);
let index: number = this.getIdByAreaPoint(areaPoint.x, areaPoint.y);
if (this.isVaildAreaId(index)
&& list.indexOf(index) == -1) {
list.push(index);
}
}
return list;
}
//是否是有效的格子
public static isVaildCellPoint(point: Vec2): boolean {
if (point.x >= 0 && point.x < this._mapSize.width
&& point.y >= 0 && point.y < this._mapSize.height) {
return true;
}
return false;
}
//是否是有效的格子
public static isVaildAreaPoint(point: Vec2): boolean {
if (point.x >= 0 && point.x < this._areaSize.width
&& point.y >= 0 && point.y < this._areaSize.height) {
return true;
}
return false;
}
public static isVaildAreaId(id: number) {
if (id >= 0 && id < this.areaCount) {
return true;
}
return false;
}
// 世界像素坐标转地图坐标
public static worldPixelToMapCellPoint(point: Vec2): Vec2 {
// 转换原理
// tiledMap 45度地图是已上方为(0,0)点 以左上方边界为y轴 右上方边界为x轴的坐标系
// 所以只需要将点击坐标点的平行映射到地图坐标系的边界上 求解出映射点的像素坐标 / 格子大小 即可计算出对饮的 格子坐标
let x: number = Math.floor(0.5 * this._mapSize.height + point.x / this._tileSize.width - point.y / this._tileSize.height);
let y: number = Math.floor(1.5 * this._mapSize.width - point.x / this._tileSize.width - point.y / this._tileSize.height);
return v2(x, y);
}
//地图坐标(格子的中心点)转世界像素坐标
public static mapCellToWorldPixelPoint(point: Vec2): Vec2 {
let pixelX: number = this._zeroPixelPoint.x - (point.y - point.x) * this._tileSize.width * 0.5;
let pixelY: number = this._zeroPixelPoint.y - (point.x + point.y) * this._tileSize.height * 0.5;
return v2(pixelX, pixelY);
}
// 地图坐标转地图像素坐标
public static mapCellToPixelPoint(point: Vec2): Vec2 {
let worldPoint: Vec2 = this.mapCellToWorldPixelPoint(point);
return worldPoint.subtract(this._mapOffsetPoint);
}
//地图像素转地图坐标
public static mapPixelToCellPoint(point: Vec2): Vec2 {
let temp = point.clone();
let worldPoint: Vec2 = temp.add(this._mapOffsetPoint);
return this.worldPixelToMapCellPoint(worldPoint);
}
public static armyIsInView(x:number, y:number): boolean {
let buildProxy = MapCommand.getInstance().buildProxy;
let cityProxy = MapCommand.getInstance().cityProxy;
let myId = cityProxy.getMyPlayerId();
let myUnionId = cityProxy.myUnionId;
// let parentId = cityProxy.myParentId;
//可视觉区域以当前为原点半径为5
for (let i = Math.max(0, x-5); i<= Math.min(x+5, this._mapSize.width); i++) {
for (let j = Math.max(0, y-5); j<= Math.min(y+5, this._mapSize.height); j++) {
let id: number = MapUtil.getIdByCellPoint(i, j);
var b = buildProxy.getBuild(id);
if (!b){
continue
}
if(b.rid == myId || (myUnionId != 0 && (b.unionId == myUnionId || b.parentId == myUnionId))){
return true;
}
var c = cityProxy.getCity(id)
if (!c){
continue
}
if(c.rid == myId || (myUnionId != 0 && (b.unionId == myUnionId || b.parentId == myUnionId))){
return true;
}
}
}
return false
}
}