Ejemplo n.º 1
0
    /// <summary>
    /// 开始回放
    /// </summary>
    /// <param name="vo"></param>
    public static void StartReplay(BattleReplayVO vo)
    {
#if UNITY_EDITOR
        BattleManager.logClear();
#endif  //  UNITY_EDITOR

        BattleManager.Instance.BattleStartTime = DateTimeUtil.UnixTimestampMSToDateTime(vo.battleStartTime);

        _recordData = vo;

        _operation.Clear();
        //  REMARK:把List转换为LinkedList,提高remove的效率。
        foreach (var op in vo.battleInputs)
        {
            _operation.AddLast(new OpPlaceSoldier()
            {
                frame       = op.frame,
                operationId = op.battleOperationType,
                x           = op.battleOperationPlaceSoldierVO.x,
                y           = op.battleOperationPlaceSoldierVO.y,
                soldierId   = op.battleOperationPlaceSoldierVO.cid
            });
        }

        //  设置随机数种子(TODO:类型不一致)
        BattleRandom.SetSeed((int)vo.seed);

        //  从0帧开始
        _frame = 0;

        _battleEnded = false;
    }
Ejemplo n.º 2
0
 /// <summary>
 /// 从建筑区域随机获取一个移动格子(REMARK:如果当前目标已经在建筑区域内,则根据距离作为权重随机获取,否则直接随机获取。)
 /// </summary>
 /// <param name="inBuildArea"></param>
 /// <returns></returns>
 private TilePoint RandomMoveGrid(bool inBuildArea)
 {
     if (inBuildArea)
     {
         if (_buildArea.Count == 1)
         {
             return(_buildArea[0]);
         }
         else
         {
             //  权重算法:距离越大(权重越低、距离越近权重越高、距离0跳过)
             int maxDis = _buildArea.Count - 1;
             List <TilePoint> randomList = new List <TilePoint>();
             TilePoint        selfPos    = Entity.GetTilePos();
             foreach (var grid in _buildArea)
             {
                 int dis = Mathf.Abs(selfPos.x - grid.x) + Mathf.Abs(selfPos.y - grid.y);
                 if (dis > 0)
                 {
                     int weight = maxDis + 1 - dis;
                     for (int i = 0; i < weight; i++)
                     {
                         randomList.Add(grid);
                     }
                 }
             }
             return(randomList[BattleRandom.Range(0, randomList.Count)]);
         }
     }
     else
     {
         return(_buildArea[BattleRandom.Range(0, _buildArea.Count)]);
     }
 }
Ejemplo n.º 3
0
    /// <summary>
    /// 从目标列表里根据距离时间等权重筛选最有目标
    /// </summary>
    /// <param name="targeters"></param>
    /// <param name="_targetPos"></param>
    /// <param name="_targetRoute"></param>
    /// <returns></returns>
    private List <TileEntity> SelectTargeters(List <TileEntity> targeters, out TilePoint?_targetPos, out LinkedList <IMoveGrid> _targetRoute)
    {
        _targetPos   = null;
        _targetRoute = null;

        //  先在监视范围内寻找时间消耗最低的目标
        IsoGridTarget targetInfos = FindTargetsNearestTimeCost(Attacker, targeters);

        if (targetInfos != null)
        {
            Assert.Should(targetInfos.MoveRoute != null);
            if (targetInfos.MoveRoute.Count > 1)
            {
                _targetRoute = targetInfos.MoveRoute;
            }
            return(AuxConvertToList(targetInfos.Targeter));
        }

        //  未找到则直接寻找直线最近的目标
        var     nearest_targets = FindTargetsNearestLinear(Attacker.GetCurrentPositionCenter(), targeters, 1);
        var     targeter        = nearest_targets[0];
        Vector2 p = targeter.GetCurrentPositionCenter();
        //int randomOffset = Mathf.Min((int)(targeter.blockingRange / 2.0f + Attacker.model.range), targeter.width / 2);  //  TODO:如果该值过大导致移动结束后目标不在攻击范围内(则会导致重新锁定目标) 则需要酌情调整该值算法
        int randomOffset = Mathf.Min((int)Attacker.model.range, targeter.width / 2);
        int x            = (int)p.x;
        int y            = (int)p.y;

        if (randomOffset > 0)
        {
            x = BattleRandom.Range(x - randomOffset, x + randomOffset);
            y = BattleRandom.Range(y - randomOffset, y + randomOffset);
        }
        _targetPos = new TilePoint(x, y);
        return(nearest_targets);
    }
Ejemplo n.º 4
0
    protected override void DoActionIdle()
    {
        //m_tempTargeters = null;
        //Entity.State = EntityStateType.Idle;
        //m_timePassed = BattleRandom.Range(3f, 10f);

        AuxRecycleAllBulletLoopEffect();

        m_tempTargeters = null;
        Entity.State    = EntityStateType.Idle;
        m_timePassed    = BattleRandom.Range(0.5f, 1.5f);

#if UNITY_EDITOR
        BattleManager.logWaitTime.Add(GameRecord.Frame + ":timePassed:" + m_timePassed);
#endif  //  UNITY_EDITOR

        if (Entity.AimTarget)
        {
            //  背向地图中央
            var center = new Vector2(Constants.WIDTH / 2, Constants.HEIGHT / 2);
            var dir    = Entity.GetCurrentPositionCenter() - center;
            var angle  = MathUtil2D.GetAngleFromVector(IsoHelper.TileDirectionToScreenDirection(dir));

            Entity.PlayAnimationAtScreenAngle(AnimationNames.Stand, BattleRandom.Range(angle - 45, angle + 45));
        }
        else
        {
            Entity.PlayAnimation(AnimationNames.Stand);
        }
    }
Ejemplo n.º 5
0
    /// <summary>
    /// 执行行动-发呆
    /// </summary>
    protected virtual void DoActionIdle()
    {
        AuxRecycleAllBulletLoopEffect();

        m_tempTargeters = null;
        Entity.State    = EntityStateType.Idle;
        m_timePassed    = BattleRandom.Range(0.5f, 1.5f);
        Entity.PlayAnimation(AnimationNames.Stand);
    }
Ejemplo n.º 6
0
    /// <summary>
    /// [回调] 子弹命中目标 或 子弹命中目标点
    /// </summary>
    /// <param name="bullet"></param>
    private void OnBulletHitted(GameBullet bullet)
    {
        //  TODO:如果子弹命中回调时自身已经挂了的情况是否需要考虑??
        //if (this.Entity.IsDead())
        //    return;

        Vector2 hitPos       = Vector2.zero;
        float   randomRadius = 0.0f;

        switch (bullet.bulletType)
        {
        case EntityBulletType.Point:        //  对地点伤害
        {
            Assert.Should(bullet.targetEntity == null);
            ProcessDamagePoint(bullet.targetPosition);
            hitPos       = bullet.targetPosition;
            randomRadius = 0.3f;            //  REMARK:打目标点的按照半格计算
        }
        break;

        case EntityBulletType.Target:       //  对目标伤害
        {
            Assert.Should(bullet.targetEntity != null);
            if (Entity.model.splashRange > 0)
            {
                ProcessDamagePoint(bullet.targetEntity.GetCurrentPositionCenter());
            }
            else
            {
                GameDamageManager.ProcessDamageOneTargeter(bullet.targetEntity, Entity.model, Entity);
            }
            hitPos       = bullet.targetEntity.GetCurrentPositionCenter();
            randomRadius = Mathf.Max(0.3f, bullet.targetEntity.blockingRange / 6.0f);
        }
        break;

        default:
            Assert.Should(false, "invalid bullet type...");
            break;
        }

        //  命中效果(范围内随机设置个命中点)
        if (randomRadius > 0)
        {
            hitPos.x = BattleRandom.Range(hitPos.x - randomRadius, hitPos.x + randomRadius);
            hitPos.y = BattleRandom.Range(hitPos.y - randomRadius, hitPos.y + randomRadius);
        }
        GameEffectManager.Instance.AddEffect(Entity.model.hitEffectName, new Vector3(hitPos.x, 0, hitPos.y));
    }
Ejemplo n.º 7
0
    /// <summary>
    /// 开始录像
    /// </summary>
    /// <param name="attacker"></param>
    /// <param name="defender"></param>
    public static void StartRecord()
    {
#if UNITY_EDITOR
        BattleManager.logClear();
#endif  //  UNITY_EDITOR

        BattleManager.Instance.BattleStartTime = ServerTime.Instance.Now();

        _battleEnded = false;
        _frame       = 0;
        _recordData  = new BattleReplayVO()
        {
            seed            = BattleRandom.Range(0, 0xffff),
            battleStartTime = DateTimeUtil.DateTimeToUnixTimestampMS(BattleManager.Instance.BattleStartTime),
        };
        BattleRandom.SetSeed((int)_recordData.seed);
    }
Ejemplo n.º 8
0
    private void DoActionBuild()
    {
        Entity.State = EntityStateType.Attacking;
        var dir = Entity.GetDir8FromTargeter(_buildTargeter);

        //工人只有攻击右上动画
        if (dir == EntityDirection.Right)
        {
            dir = EntityDirection.TopRight;
        }
        else if (dir == EntityDirection.Left)
        {
            dir = EntityDirection.TopLeft;
        }
        Entity.PlayAnimationAtDir8(AnimationNames.Attack, dir);
        m_timePassed = BattleRandom.Range(1.0f, 3.5f);
    }
Ejemplo n.º 9
0
    private TilePoint RandomGrid()
    {
        float            mindiff          = Mathf.Max(Entity.model.speed * 2.0f, 1.5f);
        float            mindiff2         = mindiff * mindiff;
        List <TilePoint> recommendedGrids = new List <TilePoint>();

        foreach (var grid in m_passableGrids)
        {
            float diff2 = Entity.DistanceSquareTo(grid.x, grid.y);
            if (diff2 >= mindiff2)
            {
                recommendedGrids.Add(grid);
            }
        }

        if (recommendedGrids.Count > 0)
        {
            return(recommendedGrids[BattleRandom.Range(0, recommendedGrids.Count)]);
        }
        else
        {
            return(m_passableGrids[BattleRandom.Range(0, m_passableGrids.Count)]);
        }
    }
Ejemplo n.º 10
0
 private void DoActionIdle(float min = 0.5f, float max = 1.5f)
 {
     Entity.State = EntityStateType.Idle;
     m_timePassed = BattleRandom.Range(min, max);
     Entity.PlayAnimation(AnimationNames.Stand);
 }