1.不知道为何 加载比较大的地图的时候 a星 用模拟器运气每次点击都比较卡 用的tiled map。图片大小3200*2400 小的地图就都不会 浏览器和手机运行也不会。
2.看了无数的a星算法帖子居然没人写 点击掩码层走到就近位置的算法,我也是毫无头绪 点击障碍物都是直接停止行走 有哪位大神帮忙解决下 下面是a星代码:
cc.Class({
extends: cc.Component,
properties: {
barrierLayerName: 'Barrier',
},
editor: {
requireComponent: cc.TiledMap,
},
onLoad: function () {
this._tiledMap = this.getComponent(cc.TiledMap);
this._layerBarrier = this._tiledMap.getLayer(this.barrierLayerName);
},
moveToward: function(startTilePos, desTilePos) {
if (this._isInBarrierLayer(desTilePos)) {
return [];
}
let deltaX = desTilePos.x - startTilePos.x;
let deltaY = desTilePos.y - startTilePos.y;
let openList = [];
let closeList = [];
let finalList = [];
let start = {
x: startTilePos.x,
y: startTilePos.y,
h: (Math.abs(deltaX) + Math.abs(deltaY)) * 10,
g: 0,
p: null,
};
start.f = start.h + start.g;
openList.push(start);
while(openList.length !== 0) {
let parent = openList.shift();
closeList.push(parent);
if (parent.h === 0) {break;}
for (let i = -1; i <= 1; i++) {
for (let j = -1; j <= 1; j++) {
// ==========四方向或八方向开关==========
if (Math.abs(i) + Math.abs(j) === 8) {continue;}
// ======================================
let raw = cc.p(parent.x + i, parent.y + j);
if (this._isInBarrierLayer(raw)) {continue;}
if (this._isInList(raw, openList)) {continue;}
if (this._isInList(raw, closeList)) {continue;}
let neibour = {
x: raw.x,
y: raw.y,
h: Math.max(Math.abs(raw.x - desTilePos.x), Math.abs(raw.y - desTilePos.y)) * 10,
g: parent.g + ((i !== 0 && j !== 0) ? 14 : 10),
p: parent,
};
neibour.f = neibour.h + neibour.g;
openList.push(neibour);
}
}
openList.sort(this._sortF);
}
let des = closeList.pop();
while (des.p) {
des.dx = des.x - des.p.x;
des.dy = des.y - des.p.y;
finalList.unshift(des);
des = des.p;
}
return finalList;
},
_isInList: function(tilePosition, list){
for (let pos of list) {
if (cc.pointEqualToPoint(pos, tilePosition)) return true;
}
return false;
},
_sortF: function(a, b) {
return a.f - b.f;
},
_isInBarrierLayer: function(tilePosition) {
let mapSize = this._tiledMap.getMapSize();
if (tilePosition.x < 0 || tilePosition.x >= mapSize.width) {
return true;
}
if (tilePosition.y < 0 || tilePosition.y >= mapSize.height) {
return true;
}
if (this._layerBarrier.getTileGIDAt(tilePosition)) {
return true;
}
return false;
},
});