Ejemplo n.º 1
0
    public void addSoldier(XLSpriteBase soldier)
    {
        if (soldier == null)
        {
            return;
        }

        if (soldier._data.Country == Defaults.Country.Enemy)
        {
            if (!_enemySoldiers.Contains(soldier))
            {
                _enemySoldiers.Add(soldier);
            }
        }

        bool isSelf = (soldier.Country == Defaults.Country.Me || soldier.Country == Defaults.Country.Friend);
        if (isSelf)
        {
            if (!_selfSoldiers.Contains(soldier))
            {
                _selfSoldiers.Add(soldier);
            }
        }
    }
Ejemplo n.º 2
0
    /// <summary>
    /// 逻辑更新
    /// </summary>
    public override void update()
    {
        if(_target == null) // 是否没有目标
        {
            _host.walkStop();

            _target = SpriteMgr.getInstance().getCloselyMatchSprite(_host, null);
            if(_target != null)
            {
                _targetPostion = new Vector3(_target.transform.position.x, _target.transform.position.y, _target.transform.position.z);

                _oldPositionCount = 0;
                _dodgeStartPosition = new Vector3(_host.transform.position.x, _host.transform.position.y, _host.transform.position.z);

                //设置寻路的目标点
                _navmeshAgent.SetDestination(_targetPostion);

                // 如果带转向就过于愣了,所以注视掉
                // _host.transform.LookAt(new Vector3(_targetPostion.x, _host.transform.position.y, _targetPostion.z));
            }
            return;
        }

        // 没在避让
        if (_dodgeFrameCount == 0)
        {
            _oldPositionCount++;
            if (_oldPositionCount > CHECK_MOVE_FRAME_COUNT) // 数帧检测移动量
            {
                float moveDistance = Vector3.Distance(_host.transform.position, _dodgeStartPosition);
                if(moveDistance<3.0f) // 移动量太小
                {
                    // 一半概率向左
                    if (Random.value<0.5f)
                    {
                        _dodgeTargetPosition = _host.DodgeLeftPostion;
                    }
                    else // 一半概率向右
                    {
                        _dodgeTargetPosition = _host.DodgeRightPostion;
                    }
                    _navmeshAgent.SetDestination(_dodgeTargetPosition);

                    //转向
                    _host.transform.LookAt(new Vector3(_dodgeTargetPosition.x, _host.transform.position.y, _dodgeTargetPosition.z));

                    _dodgeFrameCount = DODGE_FRAME_COUNT_MAX;
                }

                _oldPositionCount = 0;
                _dodgeStartPosition = new Vector3(_host.transform.position.x, _host.transform.position.y, _host.transform.position.z);
            }
        }
        else // 避让中
        {
            _dodgeFrameCount--;
            if (_dodgeFrameCount == 0)
            {
                _target = null;
                return;
            }

            float dis = Vector3.Distance(_host.transform.position, _dodgeTargetPosition);
            if (dis<0.2)
            {
                _target = null;
                return;
            }
            return;
        }

        // 判断目标距离<攻击距离的时候,就可以结束了
        float hostToTargetDistance = Vector3.Distance(_host.transform.position, _targetPostion);
        _host._data.AttckDistance = 4f;
        if (hostToTargetDistance <= _host._data.AttckDistance)
        {
            _host.walkStop();

            notifyEvent(EVENT_CHANGE_TO_ATTACK, _target);
            return;
        }
    }
Ejemplo n.º 3
0
    /// <summary>
    /// 初始化
    /// </summary>
    public override void init()
    {
        _target = null;

        //播放移动动作
        _host.GetComponent<Animator>().Play("run01");

        _host.walkStop();

        _host.walkEnable();
    }
Ejemplo n.º 4
0
    /// <summary>
    /// 获取距离我最近的对手
    /// </summary>
    /// <param name="sprite"></param>
    /// <returns></returns>
    public XLSpriteBase getCloselyMatchSprite1(XLSpriteBase sprite, XLSpriteBase ignoreSprite)
    {
        if (sprite == null)
        {
            return null;
        }

        List<XLSpriteBase> matchSprites = null;
        if (sprite.Country == Defaults.Country.Enemy)
        {
            matchSprites = _selfSoldiers;
        }
        else if(sprite.Country == Defaults.Country.Me || sprite.Country == Defaults.Country.Friend){
            matchSprites = _enemySoldiers;
        }

        if(matchSprites == null){
            return null;
        }

        XLSpriteBase ret = null;
        float retDistance = -1;

        List<float> distArray = new List<float>(matchSprites.Count);
        //float[] distArray = new float[matchSprites.Count];
        float maxDist = 100000f;
        float totalHP = 0;
        for (int i = 0; i < matchSprites.Count; i++)
        {
            XLSpriteBase matchSprite = matchSprites[i];
            if (!matchSprite.isCanBeTarget())
            {
                distArray.Add(maxDist);
                continue;
            }

            // 如果对手就只有一个那就不用换目标了 && 更换目标
            if (matchSprites.Count>1 && matchSprite == ignoreSprite)
            {
                distArray.Add(maxDist);
                continue;
            }

            float matchDistance = Vector3.Distance(sprite.transform.position, matchSprite.transform.position);
            distArray.Add(matchDistance);

            totalHP += matchSprite._data.HP;

        }

        // 对距离进行排序,然后在距离最短的几个里面找一个血量最小的攻击
        var sorted = distArray.Select((x, i) => new KeyValuePair<float, int>(x, i)).OrderBy(x => x.Key).ToList();
        List<float> sortedDistArray = sorted.Select(x => x.Key).ToList();
        List<int> idx = sorted.Select(x => x.Value).ToList();

        float minRatio = 1;
        //if (sprite._data.Country == Defaults.Country.Me)  // 只有我方士兵才适用这种寻敌方式
        if(true)    // 双方士兵都用这种寻敌方式
        {
            //Debug.Log("xueliang--------");
            for (int i = 0; i < Math.Min(8, distArray.Count); i++)  // 以8人为小组单位,在里面选一个血量最小的士兵进行攻击。
            {
                float ratio = (float)matchSprites[idx[i]]._data.HP / (float)sprite._data.HP; // *UnityEngine.Random.Range(0.1f, 1);
                if (ret == null || ratio < minRatio)
                {
                    ret = matchSprites[idx[i]];
                    minRatio = ratio;
                    continue;
                }
            }
        }
        else
        {
            ret = matchSprites[idx[0]];
        }

        // 调试用的,用来显示最后有多少士兵存活,总共还剩多少血量
        //string strTotal = String.Format("#.{0},HP={1}", matchSprites.Count, totalHP);
        //if(matchSprites[0]._data.Country != Defaults.Country.Me)
        //    Debug.Log(strTotal);

        return ret;
    }
Ejemplo n.º 5
0
    /// <summary>
    /// 获取距离我最近的对手
    /// </summary>
    /// <param name="sprite"></param>
    /// <returns></returns>
    public XLSpriteBase getCloselyMatchSprite(XLSpriteBase sprite, XLSpriteBase ignoreSprite)
    {
        if (sprite == null)
        {
            return null;
        }

        List<XLSpriteBase> matchSprites = null;
        if (sprite.Country == Defaults.Country.Enemy)
        {
            matchSprites = _selfSoldiers;
        }
        else if (sprite.Country == Defaults.Country.Me || sprite.Country == Defaults.Country.Friend)
        {
            matchSprites = _enemySoldiers;
        }

        if (matchSprites == null)
        {
            return null;
        }

        XLSpriteBase ret = null;
        float retDistance = -1;
        for (int i = 0; i < matchSprites.Count; i++)
        {
            XLSpriteBase matchSprite = matchSprites[i];
            if (!matchSprite.isCanBeTarget())
            {
                continue;
            }

            // 如果对手就只有一个那就不用换目标了 && 更换目标
            if (matchSprites.Count > 1 && matchSprite == ignoreSprite)
            {
                continue;
            }

            float matchDistance = Vector3.Distance(sprite.transform.position, matchSprite.transform.position);
            if (ret == null || matchDistance < retDistance)
            {
                ret = matchSprite;
                retDistance = matchDistance;
                continue;
            }
        }

        return ret;
    }