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;
|
||
},
|
||
}); |