1125 lines
40 KiB
JavaScript
1125 lines
40 KiB
JavaScript
|
import SKUIUtil from "../ts/gear_2.3.4/util/SKUIUtil";
|
|||
|
import GameModel from "../ts/core/GameModel";
|
|||
|
import MyModel from "../ts/core/MyModel";
|
|||
|
import AudioUtil from "../ts/core/AudioUtil";
|
|||
|
import SKDataUtil from "../ts/gear_2.3.4/util/SKDataUtil";
|
|||
|
import Report from "../ts/gear_2.3.4/net/Report";
|
|||
|
import GameUtil from "../ts/core/GameUtil";
|
|||
|
import SKLogger from "../ts/gear_2.3.4/util/SKLogger";
|
|||
|
import GangWar from "../ts/GangWar";
|
|||
|
|
|||
|
let GameRes = require('./GameRes');
|
|||
|
let CNpcMgr = require('./NpcMgr');
|
|||
|
|
|||
|
cc.Class({
|
|||
|
extends: cc.Component,
|
|||
|
properties: {
|
|||
|
roleNode: cc.Node,
|
|||
|
homePre: cc.Prefab,
|
|||
|
transferPre: cc.Prefab,
|
|||
|
touchPre: cc.Prefab,
|
|||
|
rolepre: cc.Prefab,
|
|||
|
effPre: cc.Prefab,
|
|||
|
gateRight: cc.Node,
|
|||
|
gateLeft: cc.Node,
|
|||
|
},
|
|||
|
|
|||
|
ctor() {
|
|||
|
this.loaded = false;
|
|||
|
this.MAP_RES_WIDTH = 5258;
|
|||
|
this.MAP_RES_HEIGHT = 2910;
|
|||
|
this.gridWidth = 20;
|
|||
|
this.gridHeight = 20;
|
|||
|
this.mapNodeSize = 512;
|
|||
|
|
|||
|
this.rowCount = Math.ceil(this.MAP_RES_HEIGHT / this.gridHeight);
|
|||
|
this.lineCount = Math.ceil(this.MAP_RES_WIDTH / this.gridWidth);
|
|||
|
this.borderCount = 1; //屏幕外的圖片顯示寬度
|
|||
|
this.transferList = [];
|
|||
|
this.mapNodeArr = [];
|
|||
|
this.mapId = 0;
|
|||
|
this.mapres = 0;
|
|||
|
|
|||
|
this.lastpos = {
|
|||
|
x: 0,
|
|||
|
y: 0
|
|||
|
};
|
|||
|
},
|
|||
|
|
|||
|
onLoad() {
|
|||
|
this.canvasWidht = cc.find('Canvas').width;
|
|||
|
this.canvasHeight = cc.find('Canvas').height;
|
|||
|
// this.canvasWidht = 1024;
|
|||
|
// this.canvasHeight = 576;
|
|||
|
this.gamelogic = cc.find('Canvas').getComponent('GameLogic');
|
|||
|
},
|
|||
|
|
|||
|
start() {
|
|||
|
this.roleNode.zIndex = 3;
|
|||
|
this.myRole = this.roleNode.getComponent('role');
|
|||
|
this.myRole.isMy = true;
|
|||
|
this.myRole.setInfo(GameModel.player, 1);
|
|||
|
MyModel.shared.horseList = this.myRole.horseList;
|
|||
|
GameModel.player.setNode(this.roleNode);
|
|||
|
this.loadMap(false);
|
|||
|
if (!this.loaded) {
|
|||
|
this.loaded = true;
|
|||
|
this.gamelogic.loadComplete();
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
changeMap(mapid, pos, issend = true) {
|
|||
|
console.warn("換地圖", mapid)
|
|||
|
if (GameModel.player.teamid > 0 && (!GameModel.player.tempLeave && !GameModel.player.isleader) && issend) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (GameModel.player.mapid == mapid) {
|
|||
|
return;
|
|||
|
}
|
|||
|
this.myRole.actlist = [];
|
|||
|
this.roleNode.stopAllActions();
|
|||
|
this.myRole.living_state = 0;
|
|||
|
|
|||
|
GameModel.player.mapid = mapid;
|
|||
|
// this.unschedule(this.checkRolePos);
|
|||
|
cc.sys.garbageCollect();
|
|||
|
|
|||
|
this.loadMap(true, pos);
|
|||
|
if (issend) {
|
|||
|
GameModel.send('c2s_change_map', {
|
|||
|
accountid: GameModel.player.accountid,
|
|||
|
roleId: GameModel.player.roleid,
|
|||
|
mapid: mapid,
|
|||
|
x: this.myRole.netInfo.x,
|
|||
|
y: this.myRole.netInfo.y
|
|||
|
});
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
changeMapXY(mapid, pos, issend = true) {
|
|||
|
if (GameModel.player.teamid > 0 && (!GameModel.player.tempLeave && !GameModel.player.isleader) && issend) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
this.myRole.actlist = [];
|
|||
|
this.myRole.netInfo.x = pos.x;
|
|||
|
this.myRole.netInfo.y = pos.y;
|
|||
|
this.roleNode.stopAllActions();
|
|||
|
this.myRole.living_state = 0;
|
|||
|
GameModel.player.mapid = mapid;
|
|||
|
let gamelogic = (cc.find('Canvas')).getComponent('GameLogic');
|
|||
|
gamelogic.uiLogic.setPosition(pos.x, pos.y);
|
|||
|
|
|||
|
cc.sys.garbageCollect();
|
|||
|
|
|||
|
this.loadMap(true, pos);
|
|||
|
if (issend) {
|
|||
|
GameModel.send('c2s_change_map', {
|
|||
|
accountid: GameModel.player.accountid,
|
|||
|
roleId: GameModel.player.roleid,
|
|||
|
mapid: mapid,
|
|||
|
x: pos.x,
|
|||
|
y: pos.y
|
|||
|
});
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
autoPatrol() {
|
|||
|
/* if (GameModel.player.teamid > 0) {
|
|||
|
return;
|
|||
|
} */
|
|||
|
this.gamelogic.autoPatrolNode.active = true;
|
|||
|
|
|||
|
let startX = Math.round((this.roleNode.getPosition().x - this.gridWidth / 2) / this.gridWidth);
|
|||
|
let startY = Math.round((this.roleNode.getPosition().y - this.gridHeight / 2) / this.gridHeight);
|
|||
|
let endX = Math.round((Math.floor(Math.random() * this.MAP_RES_WIDTH) - this.gridWidth / 2) / this.gridWidth);
|
|||
|
let endY = Math.round((Math.floor(Math.random() * this.MAP_RES_HEIGHT) - this.gridHeight / 2) / this.gridHeight);
|
|||
|
let result = this.searchMovePath(startX, startY, endX, endY);
|
|||
|
|
|||
|
this.myRole.actlist = [];
|
|||
|
for (const act of result) {
|
|||
|
this.myRole.actlist.push({
|
|||
|
type: 2,
|
|||
|
info: act
|
|||
|
});
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
RoleStop() {
|
|||
|
if (GameModel.player.teamid > 0 && (!GameModel.player.tempLeave && !GameModel.player.isleader)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (this.gamelogic.autoPatrolNode.active) {
|
|||
|
this.autoPatrol();
|
|||
|
return;
|
|||
|
}
|
|||
|
for (const transfer of this.transferList) {
|
|||
|
if (SKUIUtil.distanceByVec2(this.roleNode.getPosition(), transfer.getPosition()) < 90) {
|
|||
|
let toinfo = GameModel.conf_transfer[transfer.__info_id__];
|
|||
|
this.changeMap(toinfo.tomap, cc.v2(toinfo.tox, toinfo.toy));
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
loadMap(change, pos) {
|
|||
|
// this.gamelogic.autoPatrolNode.active = true;
|
|||
|
if (this.gamelogic.node.getChildByName('YinYaoXiangPanel')) {
|
|||
|
this.gamelogic.node.getChildByName('YinYaoXiangPanel').getComponent('YinYaoXiangPanel').closePanel();
|
|||
|
}
|
|||
|
if (this.mapId != 0) {
|
|||
|
for (let yTileNum = 0; yTileNum < this.mapNodeArr.length; yTileNum++) {
|
|||
|
let list = this.mapNodeArr[yTileNum];
|
|||
|
for (let xTileNum = 0; xTileNum < list.length; xTileNum++) {
|
|||
|
if (list[xTileNum] == 1) {
|
|||
|
this.mapNodeArr[yTileNum][xTileNum] = 0;
|
|||
|
}
|
|||
|
let amapnode = this.node.getChildByName(this.mapres + '_' + yTileNum + '_' + xTileNum);
|
|||
|
if (amapnode) {
|
|||
|
amapnode.destroy();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
this.myRole.movePath = [];
|
|||
|
this.gamelogic.clearPlayerObjs();
|
|||
|
CNpcMgr.ReloadNpcJson();
|
|||
|
|
|||
|
// cc.loader.releaseResDir(`Map/jpg/${this.mapres}`, cc.Texture2D);
|
|||
|
// cc.loader.releaseResDir(`Map/jpg/${this.mapres}`, cc.SpriteFrame);
|
|||
|
// this.node.destroyAllChildren();
|
|||
|
// gamelogic.playerObjs = {};
|
|||
|
this.mapId = GameModel.player.mapid;
|
|||
|
this.mapres = GameModel.conf_map[this.mapId].mapid;
|
|||
|
if (this.gamelogic.uiLogic) {
|
|||
|
this.gamelogic.uiLogic.setMapName(GameModel.conf_map[this.mapId].map_name);
|
|||
|
}
|
|||
|
this.MAP_RES_WIDTH = GameModel.conf_map[this.mapId].width;
|
|||
|
this.MAP_RES_HEIGHT = GameModel.conf_map[this.mapId].height;
|
|||
|
this.rowCount = Math.ceil(this.MAP_RES_HEIGHT / this.gridHeight);
|
|||
|
this.lineCount = Math.ceil(this.MAP_RES_WIDTH / this.gridWidth);
|
|||
|
|
|||
|
this.myRole.gridHeight = this.gridHeight;
|
|||
|
this.myRole.gridWidth = this.gridWidth;
|
|||
|
this.myRole.canvasHeight = this.canvasHeight;
|
|||
|
this.myRole.canvasWidht = this.canvasWidht;
|
|||
|
this.myRole.onlyid = GameModel.player.onlyid;
|
|||
|
this.myRole.name = GameModel.player.name;
|
|||
|
|
|||
|
this.mapNodeArr = []; //先聲明一維
|
|||
|
let maprow = Math.ceil(this.MAP_RES_HEIGHT / this.mapNodeSize);
|
|||
|
let mapline = Math.ceil(this.MAP_RES_WIDTH / this.mapNodeSize);
|
|||
|
if (maprow < 1 || mapline < 1) {
|
|||
|
let info = `$警告:地圖[${this.mapId}:${this.mapres}]阻礙大小異常[${maprow}:${mapline}`;
|
|||
|
Report.report(info);
|
|||
|
}
|
|||
|
for (var i = 0; i < maprow; i++) { //一維長度為20
|
|||
|
this.mapNodeArr[i] = new Array(mapline); //在聲明二維
|
|||
|
for (var j = 0; j < mapline; j++) { //二維長度為20
|
|||
|
this.mapNodeArr[i][j] = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
this.width = cc.find('Canvas').width;
|
|||
|
this.height = cc.find('Canvas').height;
|
|||
|
this.mapScale = 0.8;
|
|||
|
this.node.scale = this.mapScale;
|
|||
|
|
|||
|
this.npcInfo = GameModel.conf_map_list[this.mapres].npcInfo;
|
|||
|
this.gridInfoArr = GameModel.conf_map_list[this.mapres].mapInfo;
|
|||
|
this.myRole.gridInfoArr = this.gridInfoArr;
|
|||
|
this.myRole.actlist = [];
|
|||
|
this.gamelogic.autoNode.active = false;
|
|||
|
this.gamelogic.autoPatrolNode.active = false;
|
|||
|
this.gamelogic.mainMap.getComponent('MainMapLogic').removePathNodes();
|
|||
|
|
|||
|
this.startPos = GameModel.conf_map_list[this.mapres].startPos;
|
|||
|
this.assets = GameRes.mapResList[this.mapres];
|
|||
|
|
|||
|
// this.node.x = -this.width / 2;
|
|||
|
// this.node.y = -this.height / 2;
|
|||
|
if (change) {
|
|||
|
if (!pos) {
|
|||
|
this.myRole.setObjPos(this.startPos.x, this.startPos.y);
|
|||
|
// this.setTeamPos(this.startPos.x, this.startPos.y);
|
|||
|
} else {
|
|||
|
this.myRole.setObjPos(pos.x, pos.y);
|
|||
|
// this.setTeamPos(pos.x, pos.y);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
let rolePos = this.node.convertToWorldSpaceAR(this.roleNode.getPosition());
|
|||
|
this.updateMap(cc.v2(this.width / 2 - rolePos.x, this.height / 2 - rolePos.y));
|
|||
|
// this.scheduleOnce(() => {
|
|||
|
// // this.schedule(this.checkRolePos, 0.5, cc.macro.REPEAT_FOREVER);
|
|||
|
// this.complete = true;
|
|||
|
// }, 3);
|
|||
|
|
|||
|
for (const transfer of this.transferList) {
|
|||
|
transfer.destroy();
|
|||
|
}
|
|||
|
this.transferList = [];
|
|||
|
|
|||
|
for (const key in GameModel.conf_transfer) {
|
|||
|
const info = GameModel.conf_transfer[key];
|
|||
|
if (info.mapid == this.mapId) {
|
|||
|
let transfer = cc.instantiate(this.transferPre);
|
|||
|
transfer.x = info.mapx * 20;
|
|||
|
transfer.y = info.mapy * 20;
|
|||
|
// transfer.tag = info.id;
|
|||
|
transfer.__info_id__ = info.id;
|
|||
|
transfer.zIndex = 1;
|
|||
|
transfer.parent = this.node;
|
|||
|
this.transferList.push(transfer);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (this.mapId == 3001) {
|
|||
|
this.showGangBattleGate()
|
|||
|
GangWar.Instance.openBattleMainPanel()
|
|||
|
GameModel.player.getLogic().resetRoleTitle()
|
|||
|
GameModel.send("c2s_detail_statistics", {})
|
|||
|
} else {
|
|||
|
if (this.gateRight)
|
|||
|
this.gateRight.destroy()
|
|||
|
if (this.gateLeft)
|
|||
|
this.gateLeft.destroy()
|
|||
|
GangWar.Instance.destroyPanel()
|
|||
|
}
|
|||
|
|
|||
|
if (this.mapId == 4001) {
|
|||
|
let ui = cc.instantiate(this.homePre);
|
|||
|
ui.parent = this.node;
|
|||
|
ui.name = 'homeUI';
|
|||
|
ui.zIndex = 1;
|
|||
|
} else if (this.node.getChildByName('homeUI') != null) {
|
|||
|
this.node.getChildByName('homeUI').destroy();
|
|||
|
}
|
|||
|
let audio = GameUtil.getMapAudio(this.mapId);
|
|||
|
AudioUtil.playMusic(audio);
|
|||
|
},
|
|||
|
|
|||
|
showGangBattleGate() {
|
|||
|
if (this.gateRight) this.gateRight.destroy()
|
|||
|
if (this.gateLeft) this.gateLeft.destroy()
|
|||
|
let gateRight = cc.instantiate(this.effPre);
|
|||
|
gateRight.x = 3195;
|
|||
|
gateRight.y = 1746;
|
|||
|
gateRight.zIndex = 1;
|
|||
|
gateRight.name = "gateRight"
|
|||
|
gateRight.parent = this.node;
|
|||
|
this.gateRight = gateRight;
|
|||
|
cc.loader.loadRes(`shap/7205/stand_1`, cc.SpriteAtlas, function (error, atlas) {
|
|||
|
if (error) {
|
|||
|
cc.warn(`$警告:加載資源錯誤:${url}`);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!atlas) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
let curFrames = atlas.getSpriteFrames();
|
|||
|
let curClip = cc.AnimationClip.createWithSpriteFrames(curFrames, 10);
|
|||
|
curClip.name = `eff`;
|
|||
|
curClip.wrapMode = cc.WrapMode.Loop;
|
|||
|
if (gateRight)
|
|||
|
gateRight.getComponent("Effect").CreateAndPlayAnimation(curClip, null)
|
|||
|
})
|
|||
|
|
|||
|
let gateLeft = cc.instantiate(this.effPre);
|
|||
|
gateLeft.x = 715;
|
|||
|
gateLeft.y = 495;
|
|||
|
gateLeft.zIndex = 1;
|
|||
|
gateLeft.name = "gateLeft"
|
|||
|
gateLeft.parent = this.node;
|
|||
|
this.gateLeft = gateLeft;
|
|||
|
cc.loader.loadRes(`shap/7205/stand_1`, cc.SpriteAtlas, function (error, atlas) {
|
|||
|
if (error) {
|
|||
|
cc.warn(`$警告:加載資源錯誤:${url}`);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!atlas) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
let curFrames = atlas.getSpriteFrames();
|
|||
|
let curClip = cc.AnimationClip.createWithSpriteFrames(curFrames, 10);
|
|||
|
curClip.name = `eff`;
|
|||
|
curClip.wrapMode = cc.WrapMode.Loop;
|
|||
|
if (gateLeft)
|
|||
|
gateLeft.getComponent("Effect").CreateAndPlayAnimation(curClip, null)
|
|||
|
})
|
|||
|
},
|
|||
|
|
|||
|
showGangBattleGateDie_right(gate = false) {
|
|||
|
if (this.gateRight) this.gateRight.destroy()
|
|||
|
let gateRight = cc.instantiate(this.effPre);
|
|||
|
gateRight.x = 3195;
|
|||
|
gateRight.y = 1746;
|
|||
|
gateRight.zIndex = 1;
|
|||
|
gateRight.name = "gateRight"
|
|||
|
gateRight.parent = this.node;
|
|||
|
this.gateRight = gateRight;
|
|||
|
|
|||
|
if (gate)
|
|||
|
cc.loader.loadRes(`shap/7205/die_1`, cc.SpriteAtlas, function (error, atlas) {
|
|||
|
if (error) {
|
|||
|
cc.warn(`$警告:加載資源錯誤:${url}`);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!atlas) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
let curFrames = atlas.getSpriteFrames();
|
|||
|
let curClip = cc.AnimationClip.createWithSpriteFrames(curFrames, 10);
|
|||
|
curClip.name = `eff`;
|
|||
|
curClip.wrapMode = cc.WrapMode.Loop;
|
|||
|
if (gateRight)
|
|||
|
gateRight.getComponent("Effect").CreateAndPlayAnimation(curClip, null)
|
|||
|
})
|
|||
|
|
|||
|
|
|||
|
let gateEff = cc.instantiate(this.effPre);
|
|||
|
gateEff.x = 0
|
|||
|
gateEff.y = 0
|
|||
|
gateEff.parent = gateRight;
|
|||
|
|
|||
|
cc.loader.loadRes(`shap/7205/die_1_ef`, cc.SpriteAtlas, function (error, atlas) {
|
|||
|
if (error) {
|
|||
|
cc.warn(`$警告:加載資源錯誤:${url}`);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!atlas) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
let curFrames = atlas.getSpriteFrames();
|
|||
|
let curClip = cc.AnimationClip.createWithSpriteFrames(curFrames, 10);
|
|||
|
curClip.name = `eff`;
|
|||
|
curClip.wrapMode = cc.WrapMode.Loop;
|
|||
|
|
|||
|
if (gateEff)
|
|||
|
gateEff.getComponent("Effect").CreateAndPlayAnimation(curClip, null)
|
|||
|
})
|
|||
|
},
|
|||
|
|
|||
|
showGangBattleGateDie_left(gate = false) {
|
|||
|
if (this.gateLeft) this.gateLeft.destroy()
|
|||
|
let gateLeft = cc.instantiate(this.effPre);
|
|||
|
gateLeft.x = 715;
|
|||
|
gateLeft.y = 495;
|
|||
|
gateLeft.zIndex = 1;
|
|||
|
gateLeft.name = "gateLeft"
|
|||
|
gateLeft.parent = this.node;
|
|||
|
this.gateLeft = gateLeft;
|
|||
|
|
|||
|
if (gate)
|
|||
|
cc.loader.loadRes(`shap/7205/die_1`, cc.SpriteAtlas, function (error, atlas) {
|
|||
|
if (error) {
|
|||
|
cc.warn(`$警告:加載資源錯誤:${url}`);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!atlas) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
let curFrames = atlas.getSpriteFrames();
|
|||
|
let curClip = cc.AnimationClip.createWithSpriteFrames(curFrames, 10);
|
|||
|
curClip.name = `eff`;
|
|||
|
curClip.wrapMode = cc.WrapMode.Loop;
|
|||
|
if (gateLeft)
|
|||
|
gateLeft.getComponent("Effect").CreateAndPlayAnimation(curClip, null)
|
|||
|
})
|
|||
|
|
|||
|
|
|||
|
let gateEff = cc.instantiate(this.effPre);
|
|||
|
gateEff.x = 0
|
|||
|
gateEff.y = 0
|
|||
|
gateEff.parent = gateLeft;
|
|||
|
|
|||
|
cc.loader.loadRes(`shap/7205/die_1_ef`, cc.SpriteAtlas, function (error, atlas) {
|
|||
|
if (error) {
|
|||
|
cc.warn(`$警告:加載資源錯誤:${url}`);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!atlas) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
let curFrames = atlas.getSpriteFrames();
|
|||
|
let curClip = cc.AnimationClip.createWithSpriteFrames(curFrames, 10);
|
|||
|
curClip.name = `eff`;
|
|||
|
curClip.wrapMode = cc.WrapMode.Loop;
|
|||
|
if (gateEff)
|
|||
|
gateEff.getComponent("Effect").CreateAndPlayAnimation(curClip, null)
|
|||
|
})
|
|||
|
},
|
|||
|
|
|||
|
boomGangMap(info) {
|
|||
|
if (this.mapId != 3001) return
|
|||
|
if (info.type == 1) {
|
|||
|
// 龍神大砲
|
|||
|
let longshenEff = cc.instantiate(this.effPre);
|
|||
|
longshenEff.x = info.x * 20;
|
|||
|
longshenEff.y = info.y * 20;
|
|||
|
longshenEff.zIndex = 1;
|
|||
|
longshenEff.name = "longshenEff";
|
|||
|
longshenEff.parent = this.node;
|
|||
|
|
|||
|
cc.loader.loadRes(`effect/2098`, cc.SpriteAtlas, function (error, atlas) {
|
|||
|
if (error) {
|
|||
|
cc.warn(`$警告:加載資源錯誤:${url}`);
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!atlas) return;
|
|||
|
|
|||
|
let curFrames = atlas.getSpriteFrames();
|
|||
|
let curClip = cc.AnimationClip.createWithSpriteFrames(curFrames, 10);
|
|||
|
curClip.name = `eff`;
|
|||
|
curClip.wrapMode = cc.WrapMode.normal;
|
|||
|
|
|||
|
longshenEff.getComponent("Effect").CreateAndPlayAnimation(curClip, null)
|
|||
|
})
|
|||
|
}
|
|||
|
else if (info.type == 2) {
|
|||
|
// 烈火
|
|||
|
let liehuoEff = cc.instantiate(this.effPre);
|
|||
|
liehuoEff.x = info.x * 20;
|
|||
|
liehuoEff.y = info.y * 20;
|
|||
|
liehuoEff.zIndex = 1;
|
|||
|
liehuoEff.name = "liehuoEff";
|
|||
|
liehuoEff.parent = this.node;
|
|||
|
|
|||
|
cc.loader.loadRes(`shap/7207/die_1_ef`, cc.SpriteAtlas, function (error, atlas) {
|
|||
|
if (error) {
|
|||
|
cc.warn(`$警告:加載資源錯誤:${url}`);
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!atlas) return;
|
|||
|
|
|||
|
let curFrames = atlas.getSpriteFrames();
|
|||
|
let curClip = cc.AnimationClip.createWithSpriteFrames(curFrames, 10);
|
|||
|
curClip.name = `eff`;
|
|||
|
curClip.wrapMode = cc.WrapMode.normal;
|
|||
|
|
|||
|
liehuoEff.getComponent("Effect").CreateAndPlayAnimation(curClip, null)
|
|||
|
})
|
|||
|
}
|
|||
|
else if (info.type == 3) {
|
|||
|
// 玄冰
|
|||
|
let xuanbingEff = cc.instantiate(this.effPre);
|
|||
|
xuanbingEff.x = info.x * 20;
|
|||
|
xuanbingEff.y = info.y * 20;
|
|||
|
xuanbingEff.zIndex = 1;
|
|||
|
xuanbingEff.name = "xuanbingEff";
|
|||
|
xuanbingEff.parent = this.node;
|
|||
|
|
|||
|
cc.loader.loadRes(`shap/7208/die_1_ef`, cc.SpriteAtlas, function (error, atlas) {
|
|||
|
if (error) {
|
|||
|
cc.warn(`$警告:加載資源錯誤:${url}`);
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!atlas) return;
|
|||
|
|
|||
|
let curFrames = atlas.getSpriteFrames();
|
|||
|
let curClip = cc.AnimationClip.createWithSpriteFrames(curFrames, 10);
|
|||
|
curClip.name = `eff`;
|
|||
|
curClip.wrapMode = cc.WrapMode.normal;
|
|||
|
|
|||
|
xuanbingEff.getComponent("Effect").CreateAndPlayAnimation(curClip, null)
|
|||
|
})
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
updateMap(deltaPos) {
|
|||
|
this.node.x += deltaPos.x;
|
|||
|
this.node.y += deltaPos.y;
|
|||
|
|
|||
|
//地圖層的位置在(-width/2, -height/2)
|
|||
|
let maxX = -this.width / 2;
|
|||
|
let maxY = -this.height / 2;
|
|||
|
if (this.node.x > maxX) {
|
|||
|
this.node.x = maxX;
|
|||
|
}
|
|||
|
if (this.node.y > maxY) {
|
|||
|
this.node.y = maxY;
|
|||
|
}
|
|||
|
let minh = -(this.MAP_RES_HEIGHT * this.mapScale - this.height) + maxY;
|
|||
|
let minw = -(this.MAP_RES_WIDTH * this.mapScale - this.width) + maxX;
|
|||
|
|
|||
|
if (this.node.y < minh) {
|
|||
|
this.node.y = minh;
|
|||
|
}
|
|||
|
if (this.node.x < minw) {
|
|||
|
this.node.x = minw;
|
|||
|
}
|
|||
|
|
|||
|
let tx = Math.abs(this.lastpos.x - this.node.x);
|
|||
|
let ty = Math.abs(this.lastpos.y - this.node.y);
|
|||
|
if (tx < 100 && ty < 100) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
this.lastpos = this.node.position;
|
|||
|
|
|||
|
let currentNodeSize = this.mapNodeSize * this.mapScale;
|
|||
|
let startx = this.node.x + currentNodeSize * this.borderCount - maxX;
|
|||
|
if (startx >= 0) {
|
|||
|
startx = 0;
|
|||
|
}
|
|||
|
let endx = this.node.x - currentNodeSize * this.borderCount - maxX - this.width;
|
|||
|
if (endx < minw - this.width / 2) {
|
|||
|
endx = minw - this.width / 2;
|
|||
|
}
|
|||
|
|
|||
|
let starty = this.node.y + currentNodeSize * this.borderCount - maxY;
|
|||
|
if (starty >= 0) {
|
|||
|
starty = 0;
|
|||
|
}
|
|||
|
|
|||
|
let endy = this.node.y - maxY - this.height;
|
|||
|
if (endy < minh - this.height / 2) {
|
|||
|
endy = minh - this.height / 2;
|
|||
|
}
|
|||
|
let begin_w_n = Math.floor(Math.abs(startx) / currentNodeSize);
|
|||
|
let end_w_n = Math.ceil(Math.abs(endx) / currentNodeSize);
|
|||
|
|
|||
|
let begin_h_n = Math.floor(Math.abs(starty) / currentNodeSize);
|
|||
|
let end_h_n = Math.ceil(Math.abs(endy) / currentNodeSize);
|
|||
|
|
|||
|
for (let yTileNum = 0; yTileNum < this.mapNodeArr.length; yTileNum++) {
|
|||
|
let list = this.mapNodeArr[yTileNum];
|
|||
|
for (let xTileNum = 0; xTileNum < list.length; xTileNum++) {
|
|||
|
const hadadd = list[xTileNum];
|
|||
|
if (xTileNum >= begin_w_n && xTileNum <= end_w_n && yTileNum >= begin_h_n && yTileNum <= end_h_n) {
|
|||
|
if (hadadd == 0) {
|
|||
|
let mapNode = new cc.Node();
|
|||
|
let mapframe = mapNode.addComponent(cc.Sprite);
|
|||
|
let self = this;
|
|||
|
let url = `Map/jpg/${this.mapres}/${this.mapres}_${yTileNum}_${xTileNum}`;
|
|||
|
cc.loader.loadRes(url, cc.SpriteFrame, function (error, frame) {
|
|||
|
if (error) {
|
|||
|
let info = `$警告:加載地圖資源${url}錯誤!`;
|
|||
|
Report.report(info);
|
|||
|
return;
|
|||
|
}
|
|||
|
if (SKUIUtil.isValid(mapframe.node)) {
|
|||
|
mapframe.spriteFrame = frame;
|
|||
|
} else {
|
|||
|
SKLogger.warn(`$警告:地圖塊資源節點無效${url}`);
|
|||
|
}
|
|||
|
mapNode.parent = self.node;
|
|||
|
mapNode.name = self.mapres + '_' + yTileNum + '_' + xTileNum;
|
|||
|
mapNode.setAnchorPoint(cc.v2(0, 0));
|
|||
|
mapNode.setPosition(xTileNum * self.mapNodeSize, yTileNum * self.mapNodeSize);
|
|||
|
if (SKDataUtil.isArray(self.mapNodeArr) && self.mapNodeArr.length >= yTileNum) {
|
|||
|
let temp = self.mapNodeArr[yTileNum];
|
|||
|
if (SKDataUtil.isArray(temp) && temp.length >= xTileNum) {
|
|||
|
self.mapNodeArr[yTileNum][xTileNum] = 1;
|
|||
|
} else {
|
|||
|
SKLogger.warn(`$警告:刷新地圖[${self.mapres}]JPG塊X坐標超出範圍${xTileNum}`);
|
|||
|
}
|
|||
|
} else {
|
|||
|
SKLogger.warn(`$警告:刷新地圖[${self.mapres}]JPG塊Y坐標超出範圍${yTileNum}`);
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
} else {
|
|||
|
if (hadadd == 1) {
|
|||
|
this.node.getChildByName(this.mapres + '_' + yTileNum + '_' + xTileNum).destroy();
|
|||
|
cc.loader.releaseRes(`Map/jpg/${this.mapres}/${this.mapres}_${yTileNum}_${xTileNum}`, cc.Texture2D);
|
|||
|
cc.loader.releaseRes(`Map/jpg/${this.mapres}/${this.mapres}_${yTileNum}_${xTileNum}`, cc.SpriteFrame);
|
|||
|
this.mapNodeArr[yTileNum][xTileNum] = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
update() {
|
|||
|
if (this.loaded) {
|
|||
|
this.checkRolePos();
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
checkRolePos() {
|
|||
|
let rolePos = this.node.convertToWorldSpaceAR(this.roleNode.getPosition());
|
|||
|
let distance = SKUIUtil.distanceByVec2(cc.v2(this.width / 2, this.height / 2), rolePos);
|
|||
|
if (distance > 5) {
|
|||
|
let deltaPos = cc.v2(0, 0);
|
|||
|
if (rolePos.x - this.width / 2 > 0 || rolePos.x - this.width / 2 < 0) {
|
|||
|
// deltaPos.x = (this.width / 2 - rolePos.x) / 10;
|
|||
|
let direction = rolePos.x > this.width / 2 ? -1 : 1;
|
|||
|
deltaPos.x = direction * Math.sqrt(Math.abs(this.width / 2 - rolePos.x)) / 2;
|
|||
|
}
|
|||
|
if (rolePos.y - this.height / 2 > 0 || rolePos.y - this.height / 2 < 0) {
|
|||
|
// deltaPos.y = (this.height / 2 - rolePos.y) / 10;
|
|||
|
let direction = rolePos.y > this.height / 2 ? -1 : 1;
|
|||
|
deltaPos.y = direction * Math.sqrt(Math.abs(this.height / 2 - rolePos.y)) / 2;
|
|||
|
}
|
|||
|
this.updateMap(deltaPos);
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
touchPos(drawPos) {
|
|||
|
if (GameModel.player.teamid > 0 && !GameModel.player.isleader && !GameModel.player.tempLeave) {
|
|||
|
return [];
|
|||
|
}
|
|||
|
// 蓄力中則打斷
|
|||
|
if (GameModel.needKeep)
|
|||
|
GameUtil.breakWaitTip2()
|
|||
|
|
|||
|
this.cleanTeamPath();
|
|||
|
let startX = Math.round((this.roleNode.getPosition().x - this.gridWidth / 2) / this.gridWidth);
|
|||
|
let startY = Math.round((this.roleNode.getPosition().y - this.gridHeight / 2) / this.gridHeight);
|
|||
|
let endX = Math.round((drawPos.x - this.gridWidth / 2) / this.gridWidth);
|
|||
|
let endY = Math.round((drawPos.y - this.gridHeight / 2) / this.gridHeight);
|
|||
|
let result = this.searchMovePath(startX, startY, endX, endY);
|
|||
|
this.myRole.actlist = [];
|
|||
|
this.roleNode.stopAllActions();
|
|||
|
if (result.length > 0) {
|
|||
|
for (const act of result) {
|
|||
|
this.myRole.actlist.push({
|
|||
|
type: 2,
|
|||
|
info: act
|
|||
|
});
|
|||
|
}
|
|||
|
this.myRole.living_state = 0;
|
|||
|
}
|
|||
|
this.myRole.objUpdate();
|
|||
|
this.gamelogic.autoNode.active = false;
|
|||
|
this.gamelogic.autoPatrolNode.active = false;
|
|||
|
this.gamelogic.mainMap.getComponent('MainMapLogic').removePathNodes();
|
|||
|
this.showTouchEffect(drawPos);
|
|||
|
return result;
|
|||
|
},
|
|||
|
|
|||
|
cleanTeamPath() {
|
|||
|
if (GameModel.player.teamid == 0 || !GameModel.player.isleader || GameModel.player.tempLeave) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!GameModel.player.teamInfo.objlist || !Array.isArray(GameModel.player.teamInfo.objlist)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
for (let index = 1; index < GameModel.player.teamInfo.objlist.length; index++) {
|
|||
|
let obj = GameModel.player.teamInfo.objlist[index];
|
|||
|
if (obj.livingtype != 1) {
|
|||
|
break;
|
|||
|
}
|
|||
|
let p = this.gamelogic.GetPlayerObjs(obj.onlyid);
|
|||
|
if (p) {
|
|||
|
let plogic = p.getComponent('role');
|
|||
|
plogic.actlist = [];
|
|||
|
p.stopAllActions();
|
|||
|
plogic.objUpdate();
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
setTeamPos(x, y) {
|
|||
|
if (GameModel.player.teamid == 0 || !GameModel.player.isleader) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!GameModel.player.teamInfo.objlist || !Array.isArray(GameModel.player.teamInfo.objlist)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
for (let index = 1; index < GameModel.player.teamInfo.objlist.length; index++) {
|
|||
|
let obj = GameModel.player.teamInfo.objlist[index];
|
|||
|
if (obj.livingtype != 1 || obj.pause == 1) {
|
|||
|
break;
|
|||
|
}
|
|||
|
let p = this.gamelogic.GetPlayerObjs(obj.onlyid);
|
|||
|
if (p) {
|
|||
|
let plogic = p.getComponent('role');
|
|||
|
plogic.setObjPos(x, y);
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
setTeamPath() {
|
|||
|
if (GameModel.player.teamid == 0 || !GameModel.player.isleader) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!GameModel.player.teamInfo.objlist || !Array.isArray(GameModel.player.teamInfo.objlist)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
let path = this.myRole.movePath;
|
|||
|
if (path.length < 5) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (path.length > 30) {
|
|||
|
path.splice(0, path.length - 30);
|
|||
|
}
|
|||
|
|
|||
|
// this.addTeamPlayerToMap();
|
|||
|
for (let index = 1; index < GameModel.player.teamInfo.objlist.length; index++) {
|
|||
|
let obj = GameModel.player.teamInfo.objlist[index];
|
|||
|
if (obj.livingtype != 1 || obj.pause == 1) {
|
|||
|
break;
|
|||
|
}
|
|||
|
let p = this.gamelogic.GetPlayerObjs(obj.onlyid);
|
|||
|
if (p) {
|
|||
|
let plogic = p.getComponent('role');
|
|||
|
if (path.length > index * 5) {
|
|||
|
let pos = path[path.length - 5 * index - 1];
|
|||
|
|
|||
|
plogic.actlist.push({
|
|||
|
type: 2,
|
|||
|
info: pos
|
|||
|
});
|
|||
|
plogic.objUpdate();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
addTeamPlayerToMap() {
|
|||
|
if (GameModel.player.teamid == 0 || !GameModel.player.isleader) {
|
|||
|
return;
|
|||
|
}
|
|||
|
for (let index = 1; index < GameModel.player.teamInfo.objlist.length; index++) {
|
|||
|
let obj = GameModel.player.teamInfo.objlist[index];
|
|||
|
if (obj.livingtype != 1 || obj.pause == 1) {
|
|||
|
break;
|
|||
|
}
|
|||
|
if (this.gamelogic.playerObjs[obj.onlyid] == null) {
|
|||
|
let curRole = cc.instantiate(this.rolepre);
|
|||
|
curRole.parent = this.node;
|
|||
|
curRole.zIndex = 3;
|
|||
|
curRole.livingtype = obj.livingtype;
|
|||
|
let comRole = curRole.getComponent('role');
|
|||
|
comRole.setObjPos(this.myRole.netInfo.x, this.myRole.netInfo.y);
|
|||
|
comRole.setInfo(obj);
|
|||
|
comRole.onlyid = obj.onlyid;
|
|||
|
this.gamelogic.playerObjs[obj.onlyid] = curRole;
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
showTouchEffect(pos) {
|
|||
|
let teffect = cc.instantiate(this.touchPre);
|
|||
|
teffect.parent = this.node;
|
|||
|
teffect.x = pos.x;
|
|||
|
teffect.y = pos.y;
|
|||
|
teffect.runAction(cc.sequence(cc.delayTime(3), cc.removeSelf()));
|
|||
|
},
|
|||
|
|
|||
|
searchMovePath(startX, startY, endX, endY) {
|
|||
|
let availableStart = this.getAvailabelPoint(startY, startX, this.gridInfoArr, this.rowCount, this.lineCount);
|
|||
|
let availableEnd = this.getAvailabelPoint(endY, endX, this.gridInfoArr, this.rowCount, this.lineCount);
|
|||
|
let result = this.searchRoad(availableStart.r, availableStart.l, availableEnd.r, availableEnd.l, this.gridInfoArr, this.rowCount, this.lineCount);
|
|||
|
return result;
|
|||
|
},
|
|||
|
|
|||
|
getAvailabelPoint(r, l, mapArr, rows, lines) {
|
|||
|
if (r < 0) {
|
|||
|
r = 0;
|
|||
|
}
|
|||
|
if (l < 0) {
|
|||
|
l = 0;
|
|||
|
}
|
|||
|
if (r >= rows) {
|
|||
|
r = rows - 1;
|
|||
|
}
|
|||
|
if (l >= lines) {
|
|||
|
l = lines - 1;
|
|||
|
}
|
|||
|
if (mapArr[r][l] != 0) {
|
|||
|
return {
|
|||
|
r: r,
|
|||
|
l: l
|
|||
|
};
|
|||
|
}
|
|||
|
let count = 1;
|
|||
|
for (let i = 0; i < 10000000; i++) {
|
|||
|
if (count > lines && count > rows) {
|
|||
|
return {
|
|||
|
r: -1,
|
|||
|
l: -1
|
|||
|
};
|
|||
|
}
|
|||
|
if (r + count < rows && mapArr[r + count][l] != 0) {
|
|||
|
return {
|
|||
|
r: r + count,
|
|||
|
l: l
|
|||
|
};
|
|||
|
}
|
|||
|
if (l + count < lines && mapArr[r][l + count] != 0) {
|
|||
|
return {
|
|||
|
r: r,
|
|||
|
l: l + count
|
|||
|
};
|
|||
|
}
|
|||
|
if (r >= count && mapArr[r - count][l] != 0) {
|
|||
|
return {
|
|||
|
r: r - count,
|
|||
|
l: l
|
|||
|
};
|
|||
|
}
|
|||
|
if (l >= count && mapArr[r][l - count] != 0) {
|
|||
|
return {
|
|||
|
r: r,
|
|||
|
l: l - count
|
|||
|
};
|
|||
|
}
|
|||
|
if (r + count < rows && l + count < lines && mapArr[r + count][l + count] != 0) {
|
|||
|
return {
|
|||
|
r: r + count,
|
|||
|
l: l + count
|
|||
|
};
|
|||
|
}
|
|||
|
if (r >= count && l >= count && mapArr[r - count][l - count] != 0) {
|
|||
|
return {
|
|||
|
r: r - count,
|
|||
|
l: l - count
|
|||
|
};
|
|||
|
}
|
|||
|
if (r >= count && l + count < lines && mapArr[r - count][l + count] != 0) {
|
|||
|
return {
|
|||
|
r: r - count,
|
|||
|
l: l + count
|
|||
|
};
|
|||
|
}
|
|||
|
if (l >= count && r + count < rows && mapArr[r + count][l - count] != 0) {
|
|||
|
return {
|
|||
|
r: r + count,
|
|||
|
l: l - count
|
|||
|
};
|
|||
|
}
|
|||
|
count++;
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
/**
|
|||
|
* 小頂堆上升算法
|
|||
|
* list 小頂堆列表
|
|||
|
* pos 起始計算位置,即從改點開始上升
|
|||
|
* indexlist 地圖節點索引,節點地圖坐標對應list中的位置
|
|||
|
* cols 地圖列數
|
|||
|
*/
|
|||
|
minheap_filterup(list, pos, indexlist, cols) {
|
|||
|
let c = pos; // 當前節點(current)的位置
|
|||
|
let p = Math.floor((c - 1) / 2); // 父(parent)結點的位置
|
|||
|
let tmp = list[c]; // 當前節點(current)
|
|||
|
while (c > 0) { // c>0 還未上升到頂部
|
|||
|
if (list[p].F <= tmp.F) // 父節點比當前節點小,上升結束
|
|||
|
break;
|
|||
|
else {
|
|||
|
list[c] = list[p]; // 父節點放到當前位置
|
|||
|
indexlist[list[p].r * cols + list[p].l] = c; //設置父節點的索引位置
|
|||
|
c = p; // 當前位置上升到父節點位置
|
|||
|
p = Math.floor((p - 1) / 2); // 重新計算父節點位置
|
|||
|
}
|
|||
|
}
|
|||
|
list[c] = tmp; // 把傳入節點放到上升位置
|
|||
|
indexlist[tmp.r * cols + tmp.l] = c; // 設置傳入點的索引位置
|
|||
|
},
|
|||
|
|
|||
|
/**
|
|||
|
* 小顶堆下沉算法
|
|||
|
* list 小頂堆列表
|
|||
|
* pos 起始計算位置,即從改點開始上升
|
|||
|
* indexlist 地圖節點索引,節點地圖坐標對應list中的位置
|
|||
|
* cols 地圖列數
|
|||
|
*/
|
|||
|
minheap_filterdown(list, pos, indexlist, cols) {
|
|||
|
let c = pos; // 當前(current)節點的位置
|
|||
|
let l = 2 * c + 1; // 左(left)孩子的位置
|
|||
|
let tmp = list[c]; // 當前(current)節點
|
|||
|
let end = list.length - 1; // 數組終點
|
|||
|
while (l <= end) {
|
|||
|
if (l < end && list[l].F > list[l + 1].F) // "l"是左孩子,"l+1"是右孩子
|
|||
|
l++; // 左右兩孩子中選擇較小者,即list[l+1]
|
|||
|
if (tmp.F <= list[l].F) // 當前節點比最小的子節點小,調整結束
|
|||
|
break;
|
|||
|
else {
|
|||
|
list[c] = list[l];
|
|||
|
indexlist[list[l].r * cols + list[l].l] = c;
|
|||
|
c = l;
|
|||
|
l = 2 * l + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
list[c] = tmp;
|
|||
|
indexlist[tmp.r * cols + tmp.l] = c;
|
|||
|
},
|
|||
|
|
|||
|
existInCloseList(point, list, cols) {
|
|||
|
if (list[point.r * cols + point.l]) return true;
|
|||
|
return false;
|
|||
|
},
|
|||
|
|
|||
|
existInOpenList(point, list, cols) {
|
|||
|
if (list[point.r * cols + point.l]) return list[point.r * cols + point.l];
|
|||
|
return false;
|
|||
|
},
|
|||
|
|
|||
|
//其中的MAP.arr是二維數組
|
|||
|
searchRoad(start_r, start_l, end_r, end_l, mapArr, rows, cols) {
|
|||
|
if (end_r == -1 && end_l == -1) {
|
|||
|
return [];
|
|||
|
}
|
|||
|
|
|||
|
var openList = [], //開啟列表
|
|||
|
closeObjList = {}, //關閉列表索引
|
|||
|
openObjList = {}, //開啟列表索引
|
|||
|
result = [], //結果數組
|
|||
|
result_index = 0; //終點位置
|
|||
|
|
|||
|
if (start_r == end_r && start_l == end_l) {
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
openList.push({
|
|||
|
r: start_r,
|
|||
|
l: start_l,
|
|||
|
G: 0
|
|||
|
}); //把當前點加入到開啟列表中,並且G是0
|
|||
|
openObjList[start_r * cols + start_l] = start_r * cols + start_l;
|
|||
|
|
|||
|
do {
|
|||
|
var currentPoint = openList[0];
|
|||
|
if (openList.length > 1) {
|
|||
|
openList[0] = openList[openList.length - 1];
|
|||
|
this.minheap_filterdown(openList, 0, openObjList, cols);
|
|||
|
}
|
|||
|
openList.splice(openList.length - 1, 1);
|
|||
|
closeObjList[currentPoint.r * cols + currentPoint.l] = currentPoint;
|
|||
|
delete openObjList[currentPoint.r * cols + currentPoint.l];
|
|||
|
|
|||
|
var surroundPoint = this.SurroundPoint(currentPoint);
|
|||
|
for (var i in surroundPoint) {
|
|||
|
var item = surroundPoint[i]; //獲得周圍的八個點
|
|||
|
if (
|
|||
|
item.r >= 0 && //判斷是否在地圖上
|
|||
|
item.l >= 0 &&
|
|||
|
item.r < rows &&
|
|||
|
item.l < cols &&
|
|||
|
mapArr[item.r][item.l] != 0 && //判斷是否是障礙物
|
|||
|
!this.existInCloseList(item, closeObjList, cols) && //判斷是否在關閉列表中
|
|||
|
mapArr[item.r][currentPoint.l] != 0 && //判斷之間是否有障礙物,如果有障礙物是過不去的
|
|||
|
mapArr[currentPoint.r][item.l] != 0) {
|
|||
|
//g 到父節點的位置
|
|||
|
//如果是上下左右位置的則g等於10,斜對角的就是14
|
|||
|
var g = currentPoint.G + ((currentPoint.r - item.r) * (currentPoint.l - item.l) == 0 ? 10 : 14);
|
|||
|
if (!this.existInOpenList(item, openObjList, cols)) { //如果不在開啟列表中
|
|||
|
//計算H,通過水平和垂直距離進行確定
|
|||
|
item['H'] = Math.abs(end_r - item.r) * 10 + Math.abs(end_l - item.l) * 10;
|
|||
|
item['G'] = g;
|
|||
|
item['F'] = item.H + item.G;
|
|||
|
item['parent'] = currentPoint;
|
|||
|
openList.push(item);
|
|||
|
openObjList[item.r * cols + item.l] = openList.length - 1;
|
|||
|
if (item['H'] == 0) {
|
|||
|
break;
|
|||
|
}
|
|||
|
this.minheap_filterup(openList, openList.length - 1, openObjList, cols);
|
|||
|
} else { //存在在開啟列表中,比較目前的g值和之前的g的大小
|
|||
|
var index = this.existInOpenList(item, openObjList, cols);
|
|||
|
//如果當前點的g更小
|
|||
|
if (g < openList[index].G) {
|
|||
|
openList[index].parent = currentPoint;
|
|||
|
openList[index].G = g;
|
|||
|
openList[index].F = g + openList[index].H;
|
|||
|
}
|
|||
|
this.minheap_filterup(openList, index, openObjList, cols);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
//如果開啟列表空了,沒有通路,結果為空
|
|||
|
if (openList.length == 0) {
|
|||
|
break;
|
|||
|
}
|
|||
|
// openList.sort(this.sortF);//這一步是為了循環回去的時候,找出 F 值最小的, 將它從 "開啟列表" 中移掉
|
|||
|
} while (!(result_index = this.existInOpenList({
|
|||
|
r: end_r,
|
|||
|
l: end_l
|
|||
|
}, openObjList, cols)));
|
|||
|
|
|||
|
//判斷結果列表是否為空
|
|||
|
if (!result_index) {
|
|||
|
result = [];
|
|||
|
} else {
|
|||
|
var currentObj = openList[result_index];
|
|||
|
do {
|
|||
|
//把路勁節點添加到result當中
|
|||
|
result.unshift({
|
|||
|
r: currentObj.r,
|
|||
|
l: currentObj.l
|
|||
|
});
|
|||
|
currentObj = currentObj.parent;
|
|||
|
} while (currentObj.r != start_r || currentObj.l != start_l);
|
|||
|
}
|
|||
|
let alpha = 0.8;
|
|||
|
let beta = 0.2;
|
|||
|
let p = result.slice(0);
|
|||
|
for (let i = 1; i <= 8; i++) {
|
|||
|
for (let k = 2; k < p.length - 1; k++) {
|
|||
|
let t = p[k];
|
|||
|
let l = p[k - 1];
|
|||
|
let n = p[k + 1];
|
|||
|
t.l = t.l + alpha * (result[k].l - t.l) + beta * (l.l - 2 * t.l + n.l);
|
|||
|
t.r = t.r + alpha * (result[k].r - t.r) + beta * (l.r - 2 * t.r + n.r);
|
|||
|
}
|
|||
|
}
|
|||
|
return p;
|
|||
|
// return result;
|
|||
|
},
|
|||
|
//用F值對數組排序
|
|||
|
sortF(a, b) {
|
|||
|
return b.F - a.F;
|
|||
|
},
|
|||
|
//獲取周圍八個點的值
|
|||
|
SurroundPoint(curPoint) {
|
|||
|
var r = curPoint.r,
|
|||
|
l = curPoint.l;
|
|||
|
return [{
|
|||
|
r: r - 1,
|
|||
|
l: l - 1
|
|||
|
},
|
|||
|
{
|
|||
|
r: r,
|
|||
|
l: l - 1
|
|||
|
},
|
|||
|
{
|
|||
|
r: r + 1,
|
|||
|
l: l - 1
|
|||
|
},
|
|||
|
{
|
|||
|
r: r + 1,
|
|||
|
l: l
|
|||
|
},
|
|||
|
{
|
|||
|
r: r + 1,
|
|||
|
l: l + 1
|
|||
|
},
|
|||
|
{
|
|||
|
r: r,
|
|||
|
l: l + 1
|
|||
|
},
|
|||
|
{
|
|||
|
r: r - 1,
|
|||
|
l: l + 1
|
|||
|
},
|
|||
|
{
|
|||
|
r: r - 1,
|
|||
|
l: l
|
|||
|
}
|
|||
|
];
|
|||
|
},
|
|||
|
//判斷點是否存在在列表中,是的話返回的是序列號
|
|||
|
existList(point, list) {
|
|||
|
for (var i in list) {
|
|||
|
if (point.r == list[i].r && point.l == list[i].l) {
|
|||
|
return i;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
},
|
|||
|
});
|