/// <summary> /// 是否所有目标都在攻击范围内 /// </summary> /// <param name="attacker"></param> /// <returns></returns> protected bool AuxIsAllTargeterInAttackRange(TileEntity attacker) { Vector2 p = attacker.GetCurrentPositionCenter(); float blindRange2 = attacker.model.blindRange * attacker.model.blindRange; return(m_tempTargeters.RubyAll(targeter => targeter.IsInAttackRange(p.x, p.y, attacker.model.range, blindRange2))); }
/// <summary> /// 根据自身和目标之间的位置获取8方向之一。 /// </summary> /// <param name="targeter"></param> /// <returns></returns> public EntityDirection GetDir8FromTargeter(TileEntity targeter) { var direction = (targeter.GetCurrentPositionCenter() - GetCurrentPositionCenter()).normalized; var logicAngle = MathUtil2D.GetAngleFromVector(direction); return(GetDir8FromLogicAngle(logicAngle)); }
/// <summary> /// 是否有任意目标移出了攻击范围 /// </summary> /// <param name="attacker"></param> /// <returns></returns> protected bool AuxIsAnyMoveoutAttackRange(TileEntity attacker) { Assert.Should(m_tempTargeters != null); Vector2 p = attacker.GetCurrentPositionCenter(); float blindRange2 = attacker.model.blindRange * attacker.model.blindRange; return(m_tempTargeters.RubyAny(targeter => !targeter.IsInAttackRange(p.x, p.y, attacker.model.range, blindRange2))); }
private void RefreshWallLinkerAndDirection(TileEntity entity, int entity_id) { Vector2 c = entity.GetCurrentPositionCenter(); int x = (int)c.x; int y = (int)c.y; int w = entity.width; // entity_id为0则取消连接,不为0则设置连接。 int wallLinkerId = (entity_id != 0 ? m_wallLinkerId : 0); // REMARK:目前这里只连接了一个格子(如果墙的尺寸有变 这里需要相应的调整 否则会出BUG) // +Y // w w // w // w w // -X-Y +X TileEntity wall; // 左上 if ((wall = GetWallStrict(x, y + w)) != null) { m_routeMap[x, y + 1].EntityID = wallLinkerId; wall.GetComponent <WallComponent>().RefreshWallDirection(); } // 右上 if ((wall = GetWallStrict(x + w, y)) != null) { m_routeMap[x + 1, y].EntityID = wallLinkerId; wall.GetComponent <WallComponent>().RefreshWallDirection(); } // 左下 if ((wall = GetWallStrict(x - w, y)) != null) { m_routeMap[x - 1, y].EntityID = wallLinkerId; wall.GetComponent <WallComponent>().RefreshWallDirection(); } // 右下 if ((wall = GetWallStrict(x, y - w)) != null) { m_routeMap[x, y - 1].EntityID = wallLinkerId; wall.GetComponent <WallComponent>().RefreshWallDirection(); } // 刷新新建的墙自身的显示 if (entity_id != 0) { entity.GetComponent <WallComponent>().RefreshWallDirection(); } }
/// <summary> /// 更新追踪阶段 /// </summary> /// <param name="dt"></param> private void UpdateFlyTrace(float dt) { Vector2 targetPos = m_currTraceTargeter.GetCurrentPositionCenter(); var currPosition = Entity.view.body.position; var currPosition2 = new Vector2(currPosition.x, currPosition.z); float dis = Entity.model.bulletSpeed * dt; Vector2 vdir = targetPos - currPosition2; Vector2 vadd = vdir.normalized * dis; // 更新水平位置 currPosition2 += vadd; // 更新 body 位置 Entity.view.body.position = new Vector3(currPosition2.x, Mathf.Min(currPosition.y + dis, Constants.FLY_HEIGHT), currPosition2.y); // 命中 if (IsHitted(targetPos, currPosition2, vdir, vadd)) { ProcessExplode(true); } }
protected override List <TileEntity> TryLockTargeters(out TilePoint?_targetPos, out LinkedList <IMoveGrid> _targetRoute) { _targetPos = null; _targetRoute = null; ///< 有目标了直接返回 if (m_tempTargeters != null) { return(m_tempTargeters); } ///< 方案1:计算全地图目标时间最近(并且有墙的路线)REMARK:有墙基本就可以理解为封闭区域 Dictionary <TilePoint, IsoGridTarget> gridTargets = new Dictionary <TilePoint, IsoGridTarget>(); var targets = IsoMap.Instance.GetEntitiesByTT(Attacker.GetTargetOwner(), EntityAiType.Other, Attacker); foreach (var tar in targets) { Vector2 p = tar.GetCurrentPositionCenter(); TilePoint grid = new TilePoint((int)p.x, (int)p.y); IsoGridTarget tarInfos = new IsoGridTarget() { Targeter = tar, Distance = 0, X = grid.x, Y = grid.y }; gridTargets.Add(grid, tarInfos); } LinkedList <IMoveGrid> route = IsoMap.Instance.SearchDijkstraNearestWall(Attacker, gridTargets); if (route != null) { Assert.Should(route.Count >= 2); // 墙的位置 IMoveGrid wallGrid = route.Last.Value; route.RemoveLast(); // 墙的前一格 IMoveGrid lastGrid = route.Last.Value; // 获取墙 TileEntity wallTargeter = IsoMap.Instance.GetWallTargeter(lastGrid.X, lastGrid.Y, wallGrid.X, wallGrid.Y); Assert.Should(wallTargeter != null); // 返回 _targetRoute = route; return(AuxConvertToList(wallTargeter)); } ///< 方案2:求最近的墙o.o TileEntity targeter = GetWallEntityNearest(Attacker); if (targeter == null) { return(null); } // 查找移动目标点(墙四周离自身最近的点) int self_x = Entity.GetTilePos().x; int self_y = Entity.GetTilePos().y; Vector2 c = targeter.GetCurrentPositionCenter(); int wall_x = (int)c.x; int wall_y = (int)c.y; int wall_w = 1; // REMARK:连接器到墙中心的距离 int mindiff = 999999; int goal_x = -1; int goal_y = -1; // 依次为 左上、右上、左下、右下 DetectNearestGrid(ref mindiff, ref goal_x, ref goal_y, self_x, self_y, wall_x, wall_y + wall_w); DetectNearestGrid(ref mindiff, ref goal_x, ref goal_y, self_x, self_y, wall_x + wall_w, wall_y); DetectNearestGrid(ref mindiff, ref goal_x, ref goal_y, self_x, self_y, wall_x - wall_w, wall_y); DetectNearestGrid(ref mindiff, ref goal_x, ref goal_y, self_x, self_y, wall_x, wall_y - wall_w); // 找到目标点 并且 目标点位置不是自身位置 if (goal_x >= 0 && goal_y >= 0 && ((goal_x != self_x || goal_y != self_y))) { _targetPos = new TilePoint(goal_x, goal_y); } return(AuxConvertToList(targeter)); }
/// <summary> /// 根据阵营已经攻击者对象获取攻击范围内的对象列表 /// </summary> /// <param name="self"></param> /// <param name="ownerType"></param> /// <returns></returns> public List <TileEntity> GetEntitiesByRange(TileEntity attacker, OwnerType ownerType) { Vector2 p = attacker.GetCurrentPositionCenter(); return(GetEntitiesByRange(attacker, ownerType, p.x, p.y, attacker.model.range, attacker.model.blindRange)); }