SamsaraGame/assets/Script/game/GameMapLogic.js
2025-04-24 17:03:28 +08:00

1125 lines
40 KiB
JavaScript
Raw Permalink 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 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;
},
});