//TODO: 添加判断是否处于遭遇战以使用遭遇战胜利条件判断 //TODO: 等待胜利条件指定单位及战区接口 #region 遭遇战胜利条件 // 胜利条件先这样写着吧,胜利条件看的有点迷迷糊糊 // 里面的指定单位和战区都是遭遇战里面的吧,先空着等待接口 /// <summary> /// 护送某单位到指定战区 /// 判断单位位置是否在指定战区范围内 /// 己方单位先到战区则胜利 /// 敌方单位先到战区则失败 /// 都没到但是己方单位死亡也失败 /// </summary> public void EscortUnitToArea() { //TODO: 获取进入遭遇战后指定单位接口 const int success = 0; const int failure = 1; const int notUnit = -1; GameUnit.GameUnit player = null; // 被护送单位 GameUnit.GameUnit enemy = null; // 敌方单位 int AreaID = 0; // 指定战区id BattleMap.BattleMap battleMap = BattleMap.BattleMap.Instance(); // if (_battleAreaDictionary[AreaID].Contains(currentPos)) // 到达指定战区 // { // Gameplay.Instance().roundProcessController.Win(); // } // else if(player.IsDead()) // 未到达指定战区且死亡则失败 // { // Gameplay.Instance().roundProcessController.Lose(); // } if (battleMap.ProjectUnit(AreaID, player, enemy) == success) { Gameplay.Instance().roundProcessController.Win(); } else if (battleMap.ProjectUnit(AreaID, player, enemy) == failure) { Gameplay.Instance().roundProcessController.Lose(); } if (battleMap.ProjectUnit(AreaID, player, enemy) == notUnit && player.IsDead()) { Gameplay.Instance().roundProcessController.Lose(); } }
/// <summary> /// 战斗胜利条件之一:守卫某战区存活指定回合数 /// </summary> /// <param name="area">要守卫的战区</param> /// <param name="curRounds">当前回合数</param> /// <param name="targetRounds">要守卫的目标回合数</param> /// <param name="mapBlock"></param> /// <returns></returns> public bool ProtectBattleZooe(int area, int curRounds, int targetRounds) { int unitAmout = 0;//该战区上我方单位数量 List <Vector2> battleAreas = null; battleAreaDic.TryGetValue(area, out battleAreas); foreach (Vector2 pos in battleAreas) { if (BattleMap.Instance().CheckIfHasUnits(pos)) { GameUnit.GameUnit unit = BattleMap.Instance().GetUnitsOnMapBlock(pos); if (unit.owner == GameUnit.OwnerEnum.Player && curRounds <= targetRounds) { unitAmout++; } } } if (unitAmout == 0) { return(false); } else { return(true); } }
/// <summary> /// AI移动 /// 一格一格移动处理函数 /// </summary> /// <returns></returns> public IEnumerator moveStepByStepAI(Unit unit, List <Vector2> paths, System.Action callback) { #region 测试一哈 先固定(0.0)为灼烧块,(0.1)为粘滞块 List <Vector2> vector2s = new List <Vector2>(); vector2s.Add(new Vector2(0, 0)); BattleMap.Instance().debuffBM.SetBattleMapBlockBurning(vector2s); List <Vector2> vector22s = new List <Vector2>(); vector22s.Add(new Vector2(1, 1)); BattleMap.Instance().debuffBM.SetBattleMapBlockRetrad(vector22s); #endregion Vector2 tempVector; BattleMapBlock battleMap; bool isRetire = false; for (int i = paths.Count - 2; i >= 0; i--) { //移除上一步的地图块儿下面的units_on_me tempVector = new Vector2((int)paths[i + 1].x, (int)paths[i + 1].y); battleMap = BattleMap.Instance().GetSpecificMapBlock(tempVector); battleMap.RemoveUnit(unit); //添加当前unit到地图块儿下面的units_on_me内 tempVector = new Vector2((int)paths[i].x, (int)paths[i].y); battleMap = BattleMap.Instance().GetSpecificMapBlock(tempVector); if (i != 0) { battleMap.AddUnit(unit); } else { battleMap.AddUnit(unit, false); } unit.transform.localPosition = Vector3.zero; if (battleMap.blockType == EMapBlockType.Burnning)//如果经过灼烧块 { BattleMap.Instance().debuffBM.UnitEnterBurning(tempVector); } else if (battleMap.blockType == EMapBlockType.Retire)//如果经过滞留块 { BattleMap.Instance().debuffBM.UnitEnterRetire(unit, battleMap); unit.nextPos = paths[i]; MsgDispatcher.SendMsg((int)MessageType.Aftermove); isRetire = true; break; } unit.nextPos = paths[i]; MsgDispatcher.SendMsg((int)MessageType.Move); yield return(new WaitForSeconds(0.4f)); } if (isRetire == false) { MsgDispatcher.SendMsg((int)MessageType.Aftermove); } if (callback != null) { callback(); } }
//寻路入口 public bool PathSearch(Vector2 startPos, Vector2 endPos) { if (BattleMap.Instance().GetSpecificMapBlock((int)startPos.x, (int)startPos.y) == null || BattleMap.Instance().GetSpecificMapBlock((int)endPos.x, (int)endPos.y) == null) { Debug.Log("In MapNavigator: invalid Pos"); return(false); } //初始化openList和closeList openList = new Dictionary <Vector2, Node>(); closeList = new Dictionary <Vector2, Node>(); //加入起点 openList.Add(startPos, new Node(startPos, endPos, 0)); do { //遍历OpenList,寻找F值最小的节点,设为A Node A = new Node(startPos, endPos, int.MaxValue / 2); //遍历OpenList,寻找F值最小的节点,设为A foreach (Node node in openList.Values) { if (node.H + node.G < A.H + A.G) { A = node; } } AStarSearch(A, startPos, endPos); openList.Remove(A.position); closeList.Add(A.position, A); //如果找到了endPos if (A.H < Mathf.Epsilon) { paths = new List <Node>(); paths.Add(closeList[endPos]); //Debug.Log("找到路径"); for (int i = 0; i < closeList.Count; i++) { paths.Add(closeList[paths[i].parentPosition]); if (paths[i + 1].G == 0) { break; } } //判断移动力与路径长度 if (IsExcessUnitMove()) { return(false); } return(true); } //OpenList是否还有节点 } while (openList.Count > 0); return(false); }
//攻击范围染色 public void HandleAtkConfirm(Vector2 target) { BattleMap.BattleMap map = BattleMap.BattleMap.Instance(); if (map.CheckIfHasUnits(target)) { GameUnit.GameUnit unit = BattleMap.BattleMap.Instance().GetUnitsOnMapBlock(target); unit.GetComponent <ShowRange>().MarkAttackRange(target); } }
//单位进入灼烧块 public void UnitEnterBurning(Vector2 vector2) { if (BattleMap.Instance().CheckIfHasUnits(vector2)) { Unit unit = BattleMap.Instance().GetUnitsOnMapBlock(vector2); unit.hp -= 1;//TODO更新HP显示 Debug.Log(unit.hp); } }
//技能可释放范围染色 public void HandleSkillConfim(Vector2 target, int range) { BattleMap.BattleMap map = BattleMap.BattleMap.Instance(); if (map.CheckIfHasUnits(target)) { GameUnit.GameUnit unit = BattleMap.BattleMap.Instance().GetUnitsOnMapBlock(target); unit.GetComponent <ShowRange>().MarkSkillRange(target, range); } }
//创造滞留块 public void SetBattleMapBlockRetrad(List <Vector2> vector2s) { BattleMapBlock bm = null; foreach (Vector2 vector2 in vector2s) { bm = BattleMap.Instance().GetSpecificMapBlock(vector2); bm.blockType = EMapBlockType.Retire; } }
//创造灼烧块 public void SetBattleMapBlockBurning(List <Vector2> vector2s) { BattleMapBlock bm = null; foreach (Vector2 vector2 in vector2s) { bm = BattleMap.Instance().GetSpecificMapBlock(vector2); bm.blockType = EMapBlockType.Burnning; } }
/// <summary> /// 判断A星算法给出的路径是否超过单位行动力 /// </summary> /// <param name="unit">当前控制单位</param> /// <returns></returns> private bool IsExcessUnitMove() { Vector2 startPos = paths[paths.Count - 1].position; Unit gameUnit = BattleMap.Instance().GetUnitsOnMapBlock(startPos); Debug.Log(gameUnit.name + "行动力为 " + gameUnit.mov); if (paths.Count - 1 > gameUnit.mov) { Debug.Log("超过移动力,无法移动到指定目标"); return(true); } return(false); }
/// <summary> /// 获取单位即信息,用于fgui显示 /// </summary> private void Show() { // 分隔符 string separator = " / "; _unit = BattleMap.Instance().GetUnitsOnMapBlock(GetSelfPosition()); if (_unit == null) { return; } // 多个tag, 一起显示,/ 隔开 string tagInTotal = ""; if (_unit.tag.Count != 0) { for (int i = 0; i < _unit.tag.Count; i++) { tagInTotal += _unit.tag[i]; tagInTotal += separator; } tagInTotal = tagInTotal.Substring(0, tagInTotal.Length - separator.Length); // 删掉最后一个 / } // 多个priority, 一起显示,/ 隔开 string priorityInTotal = ""; if (_unit.priority.Count != 0) { for (int i = 0; i < _unit.priority.Count; i++) { priorityInTotal += _unit.priority[i].ToString(); priorityInTotal += separator; } priorityInTotal = priorityInTotal.Substring(0, priorityInTotal.Length - separator.Length); // 删掉最后一个 / } // 单位基础信息 string valueInfo = "颜色: " + _unit.Color + " 生命: " + _unit.hp + "\n攻击: " + _unit.atk + " 范围: " + _unit.rng + "\n移动: " + _unit.mov + " 优先级: " + priorityInTotal; // 标签及效果信息,可能过长显示截断 string effectInfo = tagInTotal + " " + _unit.Effort; _fguiInterfaces.setDescribeWindowContentText(_unit.name, valueInfo, effectInfo); }
//一格一格移动 public IEnumerator moveStepByStep(Unit unit) { #region 测试一哈 先固定(0.0)为灼烧块,(0.1)为粘滞块 List <Vector2> vector2s = new List <Vector2>(); vector2s.Add(new Vector2(0, 0)); BattleMap.Instance().debuffBM.SetBattleMapBlockBurning(vector2s); List <Vector2> vector22s = new List <Vector2>(); vector22s.Add(new Vector2(1, 1)); BattleMap.Instance().debuffBM.SetBattleMapBlockRetrad(vector22s); #endregion Vector2 tempVector; BattleMapBlock battleMap; for (int i = paths.Count - 2; i >= 0; i--) { //移除上一步的地图块儿下面的units_on_me tempVector = new Vector2((int)paths[i + 1].position.x, (int)paths[i + 1].position.y); battleMap = BattleMap.Instance().GetSpecificMapBlock(tempVector); battleMap.RemoveUnit(unit); //添加当前unit到地图块儿下面的units_on_me内 tempVector = new Vector2((int)paths[i].position.x, (int)paths[i].position.y); battleMap = BattleMap.Instance().GetSpecificMapBlock(tempVector); battleMap.AddUnit(unit); unit.transform.localPosition = Vector3.zero; if (battleMap.blockType == EMapBlockType.Burnning)//如果经过灼烧块 { BattleMap.Instance().debuffBM.UnitEnterBurning(tempVector); } else if (battleMap.blockType == EMapBlockType.Retire)//如果经过滞留块 { BattleMap.Instance().debuffBM.UnitEnterRetire(unit, battleMap); unit.nextPos = paths[i].position; GamePlay.Gameplay.Instance().bmbColliderManager.Fresh(unit); break; } unit.nextPos = paths[i].position; GamePlay.Gameplay.Instance().bmbColliderManager.Fresh(unit); MsgDispatcher.SendMsg((int)MessageType.Move); yield return(new WaitForSeconds(0.2f)); } unit.restrain = true; MsgDispatcher.SendMsg((int)MessageType.Aftermove); }
//战斗胜利条件之一:战区所属权 public bool WarZoneBelong(Vector3 position, BattleMapBlock[,] mapBlock) { int unitAmout = 0; //战区上单位的数量 int enemyAmout = 0; //战区上敌方单位数量 int area = mapBlock[(int)position.x, (int)position.y].area; List <Vector2> battleAreas = null; battleAreaDic.TryGetValue(area, out battleAreas); foreach (Vector2 pos in battleAreas) { int x = (int)pos.x; int y = (int)pos.y; if (BattleMap.Instance().CheckIfHasUnits(pos)) { unitAmout++; GameUnit.GameUnit unit = mapBlock[x, y].GetComponentInChildren <GameUnit.GameUnit>(); if (unit.owner == GameUnit.OwnerEnum.Enemy) { enemyAmout++; } } } if (unitAmout == 0) { //该战区没有所属权 return(true); } else if (enemyAmout == unitAmout) { //该战区被敌方控制 return(false); } else if (enemyAmout < unitAmout && enemyAmout != 0) { //该战区处于争夺状态 return(false); } else { //该战区被玩家控制 return(true); } }
//查找周边方块 private void AStarSearch(Node A, Vector2 startPos, Vector2 endPos) { //获得A的周边MapBlock List <BattleMapBlock> neighbourBlock = BattleMap.Instance().GetNeighbourBlock(A); //将MapBlock转为Node格式 List <Node> neighourNode = new List <Node>(); foreach (BattleMapBlock mapBlock in neighbourBlock) { neighourNode.Add(new Node(mapBlock.position, A.position, endPos, A.G + 1)); } //遍历A的周边Node for (int i = 0; i < neighourNode.Count; i++) { Node B = neighourNode[i]; //如果在关闭列表中直接忽略跳到下一个 if (closeList.ContainsKey(B.position)) { continue; } //如果在开放列表中 if (openList.ContainsKey(B.position)) { if (B.G > A.G + 1) { B.parentPosition = A.position; B.G = A.G + 1; } continue; } //如果不在两个列表里 else if (!openList.ContainsKey(B.position)) { openList.Add(B.position, B); continue; } } }
/// <summary> /// 战斗胜利条件与失败之一:将某单位护送到指定战区/某敌人进入指定战区 /// </summary> /// <param name="area">玩家单位或敌方单位要到到达的目标战区(同一战区)</param> /// <param name="player">哪个玩家的单位到达</param> /// /// <param name="enemy">哪个敌方单位到达</param> /// <returns></returns> public int ProjectUnit(int area, GameUnit.GameUnit player, GameUnit.GameUnit enemy)//不好直接返回bool值,万一都还没见进入这个战区该返回什么?暂时就这样吧 { List <Vector2> battleAreas = null; battleAreaDic.TryGetValue(area, out battleAreas); foreach (Vector2 pos in battleAreas) { if (BattleMap.Instance().CheckIfHasUnits(pos)) { GameUnit.GameUnit tempUnit = BattleMap.Instance().GetUnitsOnMapBlock(pos); if (player != null && tempUnit.id == player.id) { return(0); //胜利 } else if (enemy != null && tempUnit.id == enemy.id) { return(1);//失败 } } } return(-1);//都还没进入指定战区 }