// Learn cc.Class: // - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/class.html // - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/class.html // Learn Attribute: // - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html // - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/reference/attributes.html // Learn life-cycle callbacks: // - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html // - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/life-cycle-callbacks.html var reGameStates = require('GameStates'); cc.Class({ extends: cc.Component, editor: { requireComponent: 'AI_tourist_Animation' }, properties: { _path: { default: [], serializable: false, }, moveDirection: { default: reGameStates.moveType.none, type: cc.Enum(reGameStates.moveType), serializable: false, }, AIAnimation: { default: null, serializable: false, visible: false, }, DrawNode: cc.Node, // //提示框 // TipLabel: cc.Label, //信息弹窗 TouristTips: cc.Node, followSpeed: { default: 100, serializable: false, visible: false, }, //记录当前在哪里 _workPlace: { default: null, type: cc.Enum(reGameStates.BuildType), serializable: false, visible: false, }, //渲染的index _targetRenderingIndex: { default: 0, type: cc.Integer, visible: false, }, //如果目标到达目的地 //到达终点 _walkEndTiledTile: { default: null, visible: false, }, // //是否存在道路 // _isThereAWay: { // default: false, // visible: false, // }, //是否删除自己 _isDestroySelf: { default: false, visible: false, }, //绘制路径 darwGraphicsPath: { default: false }, //进入过的商店 shopsHaveEntered: { default: [], type: cc.Integer, visible: false, }, //是否去商店 isGoToStore: { default: false, visible: false }, //分配的目标商店 distributionOfTargetStores: null, //每个商人最多寻找的次数,超过这个值,直接走人 upperLimitOfSearchTimes: { default: 0, type: cc.Integer, visible: false, serializable: false, }, //回退旧的位置 _moveOldPos: { default: null, visible: false, serializable: false }, //当前是否回到旧的位置 _isGotoBack: false, // 需要隐藏的节点 HideArray: [cc.Node], }, // LIFE-CYCLE CALLBACKS: onLoad() { //动画脚本组件 this.AIAnimation = this.getComponent('AI_tourist_Animation'); //AI人物属性组件 this.AIAttribute = this.getComponent('AI_tourist_Attribute'); this.buytag = false; }, start() { this.followSpeed = this.AIAttribute.characterSpeed; this.AIAnimation.switchAnimation(this.moveDirection); }, //先寻找第一个商店 _gotoFirstStore() { // cc.log('this.distributionOfTargetStores',this.distributionOfTargetStores.buildInfo.id); //去第一个默认商店 if (this.distributionOfTargetStores && this.distributionOfTargetStores.buildInfo) { if (this.distributionOfTargetStores.buildInfo._inventory <= 0) { if (!this.distributionOfTargetStores.buildInfo.isItStopOperation) { this.distributionOfTargetStores.onSetTipSellOut(); // cc.log('通知商店售罄!',this.distributionOfTargetStores.buildInfo.id); } //随机寻找下一个商店。 this._GetStoreFromRandom(); return; } //查看商店有没有道路 let isHasHighWay = this.onSearchPathFromPositionArray(this.distributionOfTargetStores.buildInfo._gotoPosistion); //如果游客去的首个商店有道路并且没停运的话 if (isHasHighWay && this.distributionOfTargetStores.buildInfo.isItSaleable) { this.AIAttribute.targetBuildingsInfo = this.distributionOfTargetStores; this._isDestroySelf = false; } else { //随机寻找下一个商店。 this._GetStoreFromRandom(); } } else { //如果第一商店为Null //随机寻找下一个商店。 this._GetStoreFromRandom(); } }, _GetStoreFromRandom() { // cc.log('离开', this.upperLimitOfSearchTimes); //寻找的次数过多 if (this.upperLimitOfSearchTimes >= 3) { //没有商店额话。直接离开 this._onLeaveWalking(); return; } this.upperLimitOfSearchTimes++; let shopBuildings = GlobalD.game.shopBuildingSalesArray; if (shopBuildings == null) { return; } let _length = shopBuildings.length; if (_length == 0) { //没有商店额话。直接离开 this._onLeaveWalking(); } else { //随机一个商店的下标 let _randomIndex = Math.floor(Math.random() * _length); let isHasHighWay = this.onSearchPathFromPositionArray(shopBuildings[_randomIndex].buildInfo._gotoPosistion); //如果没有道路到达,是旧的对象,或者停运了。继续寻找商店 if ( !isHasHighWay || !shopBuildings[_randomIndex].buildInfo.isItSaleable || shopBuildings[_randomIndex].buildInfo._inventory <= 0 || (this.AIAttribute.targetBuildingsInfo && this.AIAttribute.targetBuildingsInfo.buildInfo.id === shopBuildings[_randomIndex].buildInfo.id) ) { this._GetStoreFromRandom();//如果随机到是旧的商店,则重新寻找 return; } this._isDestroySelf = false; //如果寻找到,设置为target目标 this.AIAttribute.targetBuildingsInfo = shopBuildings[_randomIndex]; //如果身上物品还没满 if (this.AIAttribute.quantityOfGoodsPurchased < this.AIAttribute.totalQuantityOfGoodsPurchased) { //剩余的购买力 if (this.AIAttribute.totalQuantityOfGoodsPurchased - this.AIAttribute.quantityOfGoodsPurchased < this.AIAttribute.purchasingPower) this.AIAttribute.purchasingPower = this.AIAttribute.totalQuantityOfGoodsPurchased - this.AIAttribute.quantityOfGoodsPurchased; } else { //超过购买量后 this._onLeaveWalking(); } } }, //选中销售的地方 onSearchWorkBuilding() { let shopBuildings = GlobalD.game.MaterialsArray; if (shopBuildings == null) { return; } let length = shopBuildings.length; if (length == 0) { // this.TipLabel.string = '没有原料地!'; return false; } else { for (let i = 0; i < length; i++) { //在激活的状态下,只要有原料,并且可以销售,没有占用,游客就可以买 if (shopBuildings[i].buildInfo.isItActive && shopBuildings[i].buildInfo.isItSaleable && !shopBuildings[i].buildInfo.isItOccupied && 0 < shopBuildings[i].buildInfo._inventory) { //如果身上物品已满,就返回 if (this.AIAttribute.quantityOfGoodsPurchased >= this.AIAttribute.totalQuantityOfGoodsPurchased) { cc.log('可购买的商品已满!totalQuantityOfGoodsPurchased', this.AIAttribute.totalQuantityOfGoodsPurchased); return false; } //剩余的购买力 if (this.AIAttribute.totalQuantityOfGoodsPurchased - this.AIAttribute.quantityOfGoodsPurchased < this.AIAttribute.purchasingPower) this.AIAttribute.purchasingPower = this.AIAttribute.totalQuantityOfGoodsPurchased - this.AIAttribute.quantityOfGoodsPurchased; let isHasHighWay = this.onSearchPathFromPositionArray(shopBuildings[i].buildInfo._gotoPosistion); if (isHasHighWay) { //设置占用 shopBuildings[i].buildInfo.isItOccupied = true; this.AIAttribute.targetBuildingsInfo = shopBuildings[i]; return true; } else { //如果没有路,清空对象, // cc.log('如果没有路,离开!'); this._onLeaveWalking(); return false; } } } return false; } }, onUpdateGotoTarget() { //延迟更新目标 setTimeout(() => { if (this.isGoToStore) { this._gotoFirstStore(); } else { this._isDestroySelf = !this.onSearchWorkBuilding(); } }, 1000); }, //从生成点走到终点图块 onGotoEndTiledTile(_startTilePos, _endTilePos) { // console.log(_startTilePos, _endTilePos); this.getPath(_startTilePos, _endTilePos); this.vmove = -1; this.stepindex = 1; this.smallstepindex = true; //记录终点值 this._walkEndTiledTile = _endTilePos; this._isDestroySelf = true; this.onUpdateGotoTarget(); }, _onLeaveWalking() { this._isDestroySelf = true; this._path = []; if (this._walkEndTiledTile) { let isHas = this.onSearchPathFromPosition(this._walkEndTiledTile); if (!isHas) { cc.log('_onLeaveWalking离开时候没有道路,直接删除。', isHas); this.onDisappearsOnMaps(); } } else { cc.log('this._walkEndTiledTile 为空!'); } }, //根据数组判断是否到达目标位置 onReachTheTargetOrnot(positionArray) { let selfPos = GlobalD.TiledMap._tilePosFromLocation(this.node.position); let length = positionArray.length; for (let i = 0; i < length; i++) { // cc.log("根据数组判断是否到达目标位置",selfPos,positionArray[i]); if (selfPos.sub(positionArray[i]).mag() == 0) { // cc.log("根据数组判断是否到达目标位置"); return true; } } return false; }, //根据数组寻找路径 onSearchPathFromPositionArray(positionArray) { this._path = []; // this._isThereAWay = false; let isThereAWay = false; let length = positionArray.length; for (let i = 0; i < length; i++) { if (this.onSearchPathFromPosition(positionArray[i])) { // this._isThereAWay = true; isThereAWay = true; continue; } } return isThereAWay; }, //根据位置寻找目标 onSearchPathFromPosition(endPos) { var startPos = GlobalD.TiledMap._tilePosFromLocation(this.node.getPosition()); if (startPos.sub(endPos).mag() == 0) { cc.warn('起始点和终点同一个图块!', startPos, endPos); // this._moveToOldPos(); // this.onCurrentAreaIs(); return false; } // cc.log('ai位置', startPos, endPos) let isHasPath = false; isHasPath = this.getPath(startPos, endPos); this.vmove = -1; this.stepindex = 1; this.smallstepindex = true; if (this._path.length >= 2) this._moveOldPos = this._path[this._path.length - 2]; return isHasPath; }, //往回走一段距离 _moveToOldPos() { //一定要设置为空 this._path = []; let _startTilePos = GlobalD.TiledMap._tilePosFromLocation(this.node.getPosition()); let _endTilePos; if (this._moveOldPos) { _endTilePos = this._moveOldPos; } else { let randomIndex = Math.floor(Math.random() * GlobalD.game.AllHighwayStylesAndIndex.length); _endTilePos = GlobalD.TiledMap.analyticalIndexData(GlobalD.game.AllHighwayStylesAndIndex[randomIndex].highwayInfoIndex); } // cc.log('_endTilePos:', this.node.getPosition()); let isHas = this.getPath(_startTilePos, _endTilePos); this.vmove = -1; this.stepindex = 1; this.smallstepindex = true; this._isGotoBack = true; this._isDestroySelf = false; if (!isHas) { cc.log('_moveToOldPos离开时候没有道路,直接删除。', isHas); this.onDisappearsOnMaps(); } }, getPath(start, end) { // AStar.setInitInfo(this.allowDiagonals, this.diagonalCost, this.dotTiebreaker, this.badSorting); AStar.setStart(start); let getPath = AStar.pathFind(start.x, start.y, end.x, end.y); // cc.log("getPath", getPath); //路径取反 getPath.reverse(); if (getPath.length == 0) { return false; } else { if (this._path.length == 0 || this._path.length > getPath.length) { this._path = getPath; // cc.log("this.recordTheNearestPoint2", this.recordTheNearestPoint, end); this.recordTheNearestPoint = end; } if (this.darwGraphicsPath) { var ctx = this.node.parent.getComponent(cc.Graphics); ctx.clear(); ctx.strokeColor = new cc.Color().fromHEX('#FF0000'); for (let i = 0; i < this._path.length; i++) { let location = this.convertPos(this._path[i].x, this._path[i].y); if (i == 0) ctx.moveTo(location.x, location.y); else ctx.lineTo(location.x, location.y); } ctx.stroke(); } return true; } }, convertPos(tiledX, tiledY) { let location = GlobalD.TiledMap._locationFromtilePos(cc.v2(tiledX, tiledY)); location = this.node.parent.convertToNodeSpaceAR(location); //Canvas 的坐标是(360,540),图块的大小是(165,96) //我们计算的点事顶点为起始点,所以y轴要减去图块的一半。 let CanvasPos = GlobalD.game.Canvas.position; let endLocation = cc.v2(location.x + CanvasPos.x, location.y + CanvasPos.y - 48); return endLocation; }, update(dt) { //根据路径移动 this.MoveFromPath(dt); }, MoveFromPath(dt) { //寻路 if (this._path.length != 0) { var herop = this.node.getPosition(); //根据路径移动 if (this.stepindex >= 1) { if (this.smallstepindex) { // 第一个点 var startPosX = this._path[this.stepindex - 1].x; var startPosY = this._path[this.stepindex - 1].y; // 第二个点 var nextPosX = this._path[this.stepindex].x; var nextPosY = this._path[this.stepindex].y; if (startPosX == nextPosX) { if (startPosY > nextPosY) { //往右移动 this.vmove = 2; this.moveDirection = reGameStates.moveType.moveRight; } else if (startPosY < nextPosY) { this.vmove = 4; this.moveDirection = reGameStates.moveType.moveLeft; } else { this.moveDirection = reGameStates.moveType.none; this.vmove = -1; } } else if (startPosY == nextPosY) { if (startPosX > nextPosX) { this.moveDirection = reGameStates.moveType.moveUp; this.vmove = 1; } else if (startPosX < nextPosX) { this.moveDirection = reGameStates.moveType.moveDown; this.vmove = 0; } else { this.moveDirection = reGameStates.moveType.none; this.vmove = -1; } } else { this.moveDirection = reGameStates.moveType.none; this.vmove = -1; } this.AIAnimation.switchAnimation(this.moveDirection); //cc.log('this._path vmove == ', this.vmove, this._path[this.stepindex], this._path[this.stepindex - 1]); herop = this.convertPos(this._path[this.stepindex - 1].x, this._path[this.stepindex - 1].y); //设置深度 // GlobalD.game.onUpdateVertexZFromSlibling(this.node.parent, cc.v2(this._path[this.stepindex - 1].x, this._path[this.stepindex - 1].y), // (this.vmove == 1 || this.vmove == 0)); // GlobalD.game.onUpdateVertexZFromZIndex(this.node.parent, cc.v2(this._path[this.stepindex - 1].x, this._path[this.stepindex - 1].y)); this.smallstepindex = false; //设置第一个点并且画线 if (this.stepindex - 1 == 0) { // cc.log('设置第一个点', herop); //设置旧的渲染值 this.node.parent.zIndex = this._targetRenderingIndex; this.node.setPosition(herop); if (this.DrawNode && this.darwGraphicsPath) this.DrawNode.getComponent('Draw').DrawLineFromTarget(); } } if (this.stepindex != -1) { herop = this.convertPos(this._path[this.stepindex].x, this._path[this.stepindex].y); // if (!this.isMoving) return; var oldPos = this.node.position; // get move direction var direction = herop.sub(oldPos).normalize(); // multiply direction with distance to get new position var newPos = oldPos.add(direction.mul(this.followSpeed * dt)); // set new position this.node.setPosition(newPos); } let _distance = herop.sub(this.node.position).mag(); if (_distance <= 10) { this.smallstepindex = true; if (this.stepindex >= 1) this.onHideChildrenNode(true); //设置渲染深度 GlobalD.game.onUpdateVertexZFromZIndex(this.node.parent, cc.v2(this._path[this.stepindex].x, this._path[this.stepindex].y)); if (this.stepindex >= this._path.length - 1) { this.stepindex = -1; this.vmove = -1; this.moveDirection = reGameStates.moveType.none; this.AIAnimation.switchAnimation(this.moveDirection); this.onCurrentAreaIs(); if (this.AIAttribute.targetBuildingsInfo && this.AIAttribute.targetBuildingsInfo.node) //设置深度 this._targetRenderingIndex = this.AIAttribute.targetBuildingsInfo.node.zIndex; } else { this.stepindex++; this.vmove = -1; } } } } }, onDisappearsOnMaps() { // cc.log('删除游客!'); this.node.parent.destroy(); }, //判断到达的区域是什么地方 onCurrentAreaIs() { //如果走回到旧的位置,重新寻找商店 if (this._isGotoBack) { this._isGotoBack = false; this._GetStoreFromRandom(); return; } //走到终点 if (this._isDestroySelf) { this.onDisappearsOnMaps(); return; } // cc.log('this._isDestroySelf',this._isDestroySelf); //如果有对象 if (this.AIAttribute.targetBuildingsInfo) { if (!this.AIAttribute.targetBuildingsInfo.node) { //目标已经为空(已经拆除?), this._onLeaveWalking(); return; } //游客到了特定区域 //判断是否到达目标,因为目标随时有可能会移动的 let isReach = this.onReachTheTargetOrnot(this.AIAttribute.targetBuildingsInfo.buildInfo._gotoPosistion); if (!isReach) { //如果没有到达,清空对象,走人 cc.log('如果没有路,清空对象,离开!'); this.AIAttribute.targetBuildingsInfo.buildInfo.isItOccupied = false; this.AIAttribute.targetBuildingsInfo = null; this._onLeaveWalking(); return; } } else { //如果到达区域后,目标targetBuildingsInfo为空, this._onLeaveWalking(); return; } let buildInfo = this.AIAttribute.targetBuildingsInfo.buildInfo; // cc.log('到达目的地', this.AIAttribute.targetBuildingsInfo.buildInfo); switch (buildInfo.buildType) { //如果是农田,采木场,矿坑,加工厂。 //购买原料 case reGameStates.BuildType.Farmland: case reGameStates.BuildType.TimberYard: case reGameStates.BuildType.MiningPit: { this.taskCursor0(); } break; case reGameStates.BuildType.Shop: //隐藏 this.onHideChildrenNode(false); //如果没得销售,停运 if (!this.AIAttribute.targetBuildingsInfo.buildInfo.isItSaleable) { this._moveToOldPos(); return; } if (this.AIAttribute.targetBuildingsInfo.buildInfo._inventory == 0) { // 通知商店商品空缺 // cc.log(this.AIAttribute.targetBuildingsInfo); this.AIAttribute.targetBuildingsInfo.onSetTipSellOut(); this.AIAttribute.targetBuildingsInfo.node.getComponent("buildingTips").playSellOutAnim(); //增加金钱 // this.AIAttribute.targetBuildingsInfo.node.getComponent("buildingTips").playCoinAnim(99); this._moveToOldPos(); } else { let purchasingNum = this.AIAttribute.targetBuildingsInfo.buildInfo.onSetCurrentInventory(-this.AIAttribute.purchasingPower); this.AIAttribute.quantityOfGoodsPurchased += purchasingNum; // this.TipLabel.string = '购买的商品数量' + this.AIAttribute.quantityOfGoodsPurchased; //如果不是对应购买的数量,就判断是没有购买完全,商品售罄。 if (purchasingNum != this.AIAttribute.purchasingPower) { this.AIAttribute.targetBuildingsInfo.onSetTipSellOut(); this.AIAttribute.targetBuildingsInfo.node.getComponent("buildingTips").playSellOutAnim(); //增加金钱 // this.AIAttribute.targetBuildingsInfo.node.getComponent("buildingTips").playCoinAnim(99); this._moveToOldPos(); } else { let prise = this.AIAttribute.targetBuildingsInfo.buildInfo.goodsArray[0].goodsPrice + this.AIAttribute.targetBuildingsInfo.buildInfo.goodsPriceAddValue; let _buildingTips = this.AIAttribute.targetBuildingsInfo.node.getComponent("buildingTips"); if (!_buildingTips) { this.AIAttribute.targetBuildingsInfo.node.addComponent("buildingTips").playCoinAnim(prise * this.AIAttribute.quantityOfGoodsPurchased); } else { _buildingTips.playCoinAnim(prise * this.AIAttribute.quantityOfGoodsPurchased); } GlobalD.GameData.PlusGolden(prise * this.AIAttribute.quantityOfGoodsPurchased); this.AIAttribute.targetBuildingsInfo.node.getComponent('Collect').addCount(); this._moveToOldPos(); //如果购买了商品后,商店没有商品了,通知售罄 if (this.AIAttribute.targetBuildingsInfo.buildInfo._inventory <= 0) { this.AIAttribute.targetBuildingsInfo.node.getComponent("buildingTips").playSellOutAnim(); this.AIAttribute.targetBuildingsInfo.onSetTipSellOut(); } } } break; } }, //欢迎光临 taskCursor0: function () { //引导task.taskCursor == 2 //isCanTasksbeTriggered 是否可以触发任务的游客,true是可以触发 if (this.AIAttribute.isCanTasksbeTriggered && task.TaskIconCountClick == 13 && !task.taskGotoBuyOnly) { task.taskGotoBuyOnly = true; task.buyFarming(function () { this.gobuy(); }.bind(this)); } else { this.gobuy(); } }, gobuy: function () { let buildInfo = this.AIAttribute.targetBuildingsInfo.buildInfo; let purchasingNum = this.AIAttribute.targetBuildingsInfo.buildInfo.onSetCurrentInventory(-this.AIAttribute.targetBuildingsInfo.buildInfo._inventory); this.AIAttribute.quantityOfGoodsPurchased += purchasingNum; //重置农田 this.AIAttribute.targetBuildingsInfo.node.getComponent('WorkingBuilding').onResetSprite(buildInfo.buildType); this.AIAttribute.targetBuildingsInfo.buildInfo._inventory = 0; GlobalD.game.onUpdatePersonInventory(buildInfo.buildType, -purchasingNum); //设置目标点的占用状态 this.AIAttribute.targetBuildingsInfo.buildInfo.isItOccupied = false; GlobalD.game.onUpdateMaterialsArray(this.AIAttribute.targetBuildingsInfo, false); //增加金钱(商品加上环境影响的附加值) let prise = this.AIAttribute.targetBuildingsInfo.buildInfo.goodsArray[0].goodsPrice + this.AIAttribute.targetBuildingsInfo.buildInfo.goodsPriceAddValue; this.AIAttribute.targetBuildingsInfo.node.getComponent("buildingTips").playCoinAnim(prise * this.AIAttribute.quantityOfGoodsPurchased); GlobalD.GameData.PlusGolden(prise * this.AIAttribute.quantityOfGoodsPurchased); if (this.AIAttribute.targetBuildingsInfo.node.getComponent('Collect') != null) { this.AIAttribute.targetBuildingsInfo.node.getComponent('Collect').addCount(); } //购买完成,目标清空 this.AIAttribute.targetBuildingsInfo = null; this._onLeaveWalking(); }, onHideChildrenNode(isActive) { let length = this.HideArray.length; for (let i = 0; i < length; i++) { this.HideArray[i].active = isActive; } }, });