SamsaraGame/assets/Script/game/GameMapLogic.js

1125 lines
40 KiB
JavaScript
Raw Permalink Normal View History

2025-04-24 17:03:28 +08:00
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;
},
});