コード例 #1
0
    /**********************************************************************************/
    // функция стрельбы
    //
    /**********************************************************************************/
    protected virtual void FireWeapon(Vector2 position, Base.DIREC direction)
    {
        GameObject bulletObj = ObjectFactory.GetInstance().CreateGObject(position, direction, BulletType);
        Bullet     bulletCtr = bulletObj.GetComponent <Bullet>();

        if (bulletCtr != null)
        {
            bulletCtr.Owner       = m_ownerID;
            bulletCtr.OwnerUnitID = m_unitID;
        }
        else
        {
            // некоторые типы оружия используют других существ в качестве снаряда
            // в этом случае используем GMovingObject
            CIGameObject gmo = bulletObj.GetComponent <CIGameObject>();
            gmo.Owner = m_ownerID;
        }


        m_currentNumOfFiredBullets++;
        if (m_currentNumOfFiredBullets >= NumberOfBullet)
        {
            m_state = WEAPON_STATE.RECHARGE;
            m_currentRechargeTimer = FireRechargeTime;
        }
    }
コード例 #2
0
    /**********************************************************************************/
    // производим поиск цели
    // в случае обнаружения, функция сгенерирует
    //
    /**********************************************************************************/
    protected override void UpdateTarget()
    {
        // если ещё не начали никуда двигаться, стрелять тоже не будем
        // защита от дурака
        Base.DIREC direction = m_unitWithRadar.MoveDirection;
        if (direction == Base.DIREC.NO_DIRECTION)
        {
            m_targetCheckTimer += m_targetCheckTimerLimit;
            return;
        }

        // получаем список впомогательных точек для поиска
        List <Point> pointsToCheck = m_cachePoints[(int)direction];

        foreach (Point specPoint in pointsToCheck)
        {
            Point realPointToCheck = specPoint + m_currentPosition;
            List <BuildingController> buildingsInPoint = GameObjectMapController.GetInstance().SearchEnemiesBuildingInRadius(realPointToCheck, 0, m_owner);

            if (buildingsInPoint.Count > 0)
            {
                BuildingController targetCtr = buildingsInPoint[Random.Range(0, buildingsInPoint.Count)];
                if (RadarUpdate != null)
                {
                    RadarData data = new RadarData();
                    data.EnemyDirection.Add(direction);
                    data.DetectedEnemy.Add(targetCtr.gameObject);
                    RadarUpdate(data);
                }
            }

            m_targetCheckTimer += m_targetCheckTimerLimit;
        }
    }
コード例 #3
0
ファイル: LaserCtr.cs プロジェクト: ExShini/Crazy-Invasion
 /**********************************************************************************/
 // запускаем анимацию стрельбы и настраиваем игровые объекты
 /**********************************************************************************/
 public void Fire(Vector2 position, Base.DIREC direction)
 {
     m_laserDirection = direction;
     UpdateCoordinates();
     m_lineRenderer.enabled = true;
     LaserHitPoint.gameObject.SetActive(true);
 }
コード例 #4
0
    /**********************************************************************************/
    // перемещает объект в указанном направлении
    //
    /**********************************************************************************/
    virtual public void MoveGObject(Base.DIREC direction)
    {
        Vector2 movement = new Vector2();

        switch (direction)
        {
        case Base.DIREC.DOWN:
            movement.y = -1f;
            break;

        case Base.DIREC.UP:
            movement.y = 1f;
            break;

        case Base.DIREC.LEFT:
            movement.x = -1f;
            break;

        case Base.DIREC.RIGHT:
            movement.x = 1f;
            break;
        }

        Vector3 newPosition = m_rb2d.position + movement * speed * speedMultiplier * Time.deltaTime;

        m_rb2d.MovePosition(newPosition);
    }
コード例 #5
0
    public void ShiftPoint(Base.DIREC direction)
    {
        switch (direction)
        {
        case Base.DIREC.DOWN:
            this.y--;
            break;

        case Base.DIREC.UP:
            this.y++;
            break;

        case Base.DIREC.LEFT:
            this.x--;
            break;

        case Base.DIREC.RIGHT:
            this.x++;
            break;

        case Base.DIREC.NO_DIRECTION:
            break;

        default:
            Debug.LogError("");
            break;
        }
    }
コード例 #6
0
    /**********************************************************************************/
    // функция стрельбы
    //
    /**********************************************************************************/
    protected override void FireWeapon(Vector2 position, Base.DIREC direction)
    {
        for (int shell = 0; shell < ShellsInShot; shell++)
        {
            if (m_currentAmmo > 0 && m_currentMagazineAmmo > 0)
            {
                CreateBullet(position, direction);

                m_currentAmmo--;
                m_currentMagazineAmmo--;
            }
        }

        if (m_currentAmmo <= 0)
        {
            m_state = WEAPON_STATE.EMPTY;
            return;
        }

        if (m_currentMagazineAmmo == 0)
        {
            m_state = WEAPON_STATE.RECHARGE;
            m_currentRechargeTimer = FireRechargeTime;
        }
        else
        {
            m_state = WEAPON_STATE.READY;
        }
    }
コード例 #7
0
    /**********************************************************************************/
    // основная процессинговая функция
    // обновляем состояния всего вооружения
    //
    /**********************************************************************************/
    public void Update()
    {
        if (!m_isActive)
        {
            return;
        }

        Base.DIREC directionOfMovement  = m_unitWithWeapon.MoveDirection;
        Vector2    physicalUnitPosition = m_unitWithWeapon.GetGlobalPositionCenter_Unity();

        bool weaponFiring = false;

        foreach (var weapon in m_weapons)
        {
            WeaponController wCtr = weapon.Value;
            wCtr.UpdateWeaponState(physicalUnitPosition, directionOfMovement);

            // проверяем состояние оружия
            // в случае, если мы прекратили стрелять, мы должны вновь запустить движение
            weaponFiring |= wCtr.State == WeaponController.WEAPON_STATE.FIRE;
        }

        // стреляли, но прекратили
        if (weaponFiring == false && m_isFiring == true && ResumeDrive != null)
        {
            ResumeDrive();
        }
    }
コード例 #8
0
    public override void UpdateWeaponState(Vector2 position, Base.DIREC direction)
    {
        if (m_state == WEAPON_STATE.FIRE)
        {
            if (HitSoundKey != "")
            {
                GameAudioManager.Instance.PlaySound(HitSoundKey);
            }

            m_currentNumOfFiredBullets++;
            if (m_currentNumOfFiredBullets >= NumberOfBullet)
            {
                m_state = WEAPON_STATE.RECHARGE;
                m_currentRechargeTimer = FireRechargeTime;
            }
        }
        else if (m_state == WEAPON_STATE.RECHARGE)
        {
            m_currentRechargeTimer -= Time.deltaTime;
            if (m_currentRechargeTimer <= 0)
            {
                m_currentRechargeTimer = 0;
                m_state = WEAPON_STATE.READY;
                m_currentNumOfFiredBullets = 0;
            }
        }
    }
コード例 #9
0
    /**********************************************************************************/
    // перемещает объект к указанной точке
    // возвращаем true если уже находимся рядом с этой точкой и движение не требуется
    //
    /**********************************************************************************/
    virtual public bool MoveGObjectToPoint(Point movePoint)
    {
        Vector2 unitPoint   = GetGlobalPosition_Unity();
        Vector2 pointToMove = movePoint.GetUnityPoint();

        // проверяем - дошли мы до следующей точки
        // считаем разницу координат
        float xCorDiff = pointToMove.x - unitPoint.x;
        float yCorDiff = pointToMove.y - unitPoint.y;

        float diffCorr = Mathf.Abs(xCorDiff) + Mathf.Abs(yCorDiff);

        // рассчитываем точность движения
        // для скоростных юнитов значение будет увеличено
        float accurasity    = 0.01f;
        float expectedSpead = speed * speedMultiplier * Time.deltaTime;

        if (expectedSpead > accurasity)
        {
            accurasity += expectedSpead;
        }

        if (diffCorr <= accurasity)
        {
            // если добрались, окончательно выравниваем объект по точке
            // и возвращаем true как сигнал об окончании движения
            MoveGObjectToPosition(pointToMove);
            return(true);
        }

        Base.DIREC direction = Base.DIREC.NO_DIRECTION;
        // выбираем направление для сближения
        if (Mathf.Abs(xCorDiff) > Mathf.Abs(yCorDiff))
        {
            if (xCorDiff > 0)
            {
                direction = Base.DIREC.RIGHT;
            }
            else
            {
                direction = Base.DIREC.LEFT;
            }
        }
        else
        {
            if (yCorDiff > 0)
            {
                direction = Base.DIREC.UP;
            }
            else
            {
                direction = Base.DIREC.DOWN;
            }
        }

        MoveGObject(direction);

        return(false);
    }
コード例 #10
0
ファイル: Unit.cs プロジェクト: ExShini/Crazy-Invasion
 /**********************************************************************************/
 // устанавливаем направление движения
 //
 /**********************************************************************************/
 public void SetMovementDirection(Base.DIREC direction)
 {
     m_movementDirection = direction;
     foreach (var animator in m_animators)
     {
         animator.SetInteger("direction", (int)direction);
     }
 }
コード例 #11
0
 /**********************************************************************************/
 // вращаем "турель"
 //
 /**********************************************************************************/
 public void SwitchDirection()
 {
     if (m_currentSwitchDirectionTimer <= 0.0f)
     {
         Base.DIREC direction = Base.GetRandomDirection();
         m_unitToStay.SetMovementDirection(direction);
         m_currentSwitchDirectionTimer += m_switchDirectionTimerLimit;
     }
 }
コード例 #12
0
    /**********************************************************************************/
    // производим поиск цели
    // в случае обнаружения произвойдёт RadarUpdate эвент
    //
    /**********************************************************************************/
    protected override void UpdateTarget()
    {
        if (m_targetCheckTimer <= 0)
        {
            // если ещё не начали никуда двигаться, стрелять тоже не будем
            // защита от дурака
            Base.DIREC direction = m_unitWithRadar.MoveDirection;
            if (direction == Base.DIREC.NO_DIRECTION)
            {
                m_targetCheckTimer += m_targetCheckTimerLimit;
                return;
            }

            // получаем список впомогательных точек для поиска врагов
            // и проводим поиск целей для стрельбы
            List <Point> pointsToCheck = m_cachePoints[(int)direction];
            foreach (Point specPoint in pointsToCheck)
            {
                Point realPointToCheck           = specPoint + m_currentPosition;
                List <CIGameObject> unitsInPoint = GameObjectMapController.GetInstance().SearchEnemiesInRadius(realPointToCheck, m_scaningAreaRadius, m_owner);

                if (unitsInPoint.Count > 0)
                {
                    CIGameObject targetCtr = unitsInPoint[Random.Range(0, unitsInPoint.Count)];
                    if (RadarUpdate != null)
                    {
                        RadarData data = new RadarData();
                        data.EnemyDirection.Add(direction);
                        data.DetectedEnemy.Add(targetCtr.gameObject);
                        RadarUpdate(data);
                    }
                }
                else
                {
                    // проверяем игроков
                    foreach (CIGameObject plObject in m_players)
                    {
                        // считаем расстояние от точки метания снаряда до игроков
                        // если расстояние меньше m_scaningAreaRadius - вызываем RadarUpdate эвент
                        Point playerPosition = plObject.GetGlobalPosition();
                        Point positionDiff   = playerPosition - realPointToCheck;

                        if (positionDiff.GetSimpleLength() < m_scaningAreaRadius)
                        {
                            RadarData data = new RadarData();
                            data.EnemyDirection.Add(direction);
                            data.DetectedEnemy.Add(plObject.gameObject);
                            RadarUpdate(data);
                        }
                    }
                }
            }

            m_targetCheckTimer += m_targetCheckTimerLimit;
        }
    }
コード例 #13
0
    /**********************************************************************************/
    // производим поиск цели
    // в случае обнаружения произвойдёт RadarUpdate эвент
    //
    /**********************************************************************************/
    protected override void UpdateTarget()
    {
        if (m_targetCheckTimer <= 0)
        {
            // если ещё не начали никуда двигаться, стрелять тоже не будем
            // защита от дурака
            Base.DIREC direction = m_unitWithRadar.MoveDirection;
            if (direction == Base.DIREC.NO_DIRECTION)
            {
                m_targetCheckTimer += m_targetCheckTimerLimit;
                return;
            }

            // получаем список впомогательных точек для поиска врагов
            // и проводим поиск целей для стрельбы
            List <Point> pointsToCheck = m_cachePoints[(int)direction];
            foreach (Point specPoint in pointsToCheck)
            {
                Point realPointToCheck           = specPoint + m_currentPosition;
                List <CIGameObject> unitsInPoint = GameObjectMapController.GetInstance().SearchEnemiesInRadius(realPointToCheck, 0, m_owner);

                if (unitsInPoint.Count > 0)
                {
                    CIGameObject targetCtr = unitsInPoint[Random.Range(0, unitsInPoint.Count)];
                    if (RadarUpdate != null)
                    {
                        RadarData data = new RadarData();
                        data.EnemyDirection.Add(direction);
                        data.DetectedEnemy.Add(targetCtr.gameObject);
                        RadarUpdate(data);
                    }
                }
                else
                {
                    // проверяем игроков
                    foreach (CIGameObject plObject in m_players)
                    {
                        if (plObject.Owner == (int)m_owner)
                        {
                            continue;
                        }

                        if (plObject.GetGlobalPosition().IsSamePoint(realPointToCheck))
                        {
                            RadarData data = new RadarData();
                            data.EnemyDirection.Add(direction);
                            data.DetectedEnemy.Add(plObject.gameObject);
                            RadarUpdate(data);
                        }
                    }
                }
            }

            m_targetCheckTimer += m_targetCheckTimerLimit;
        }
    }
コード例 #14
0
 /**********************************************************************************/
 // функция обработки оружия
 // если начали стрелять - стреляем пока не выпустим всю очередь
 // если перезаряжаемся - считаем время до окончания перезарядки
 //
 /**********************************************************************************/
 public virtual void UpdateWeaponState(Vector2 position, Base.DIREC direction)
 {
     if (m_state == WEAPON_STATE.FIRE)
     {
         FireWeapon(position, direction);
     }
     else if (m_state == WEAPON_STATE.RECHARGE)
     {
         RechargeWeapon();
     }
 }
コード例 #15
0
    /**********************************************************************************/
    // функция создания игровых объектов
    // создаём новый объект
    /**********************************************************************************/
    protected GameObject GetNewGObjectInstance(Vector2 from, Base.DIREC direction, Base.GO_TYPE objectType, bool useOffset)
    {
        GameObject instance      = null;
        GameObject toInstantiate = ObjectLibrary.GetInstance().GetPrefab(objectType);

        if (toInstantiate == null)
        {
            Debug.LogError("ObjectFactory::GetNewGObjectInstance: toInstantiate is null!!!");
            return(null);
        }

        float OffsetSize = offset;

        if (!useOffset)
        {
            OffsetSize = 0;
        }

        Vector2 objectDirection = new Vector2(0f, 0f);

        switch (direction)
        {
        case Base.DIREC.DOWN:
            instance          = Instantiate(toInstantiate, new Vector3(from.x, from.y - OffsetSize, 0f), Quaternion.identity) as GameObject;
            objectDirection.y = -1f;
            break;

        case Base.DIREC.UP:
            instance          = Instantiate(toInstantiate, new Vector3(from.x, from.y + OffsetSize, 0f), Quaternion.identity) as GameObject;
            objectDirection.y = 1f;
            break;

        case Base.DIREC.LEFT:
            instance          = Instantiate(toInstantiate, new Vector3(from.x - OffsetSize, from.y, 0f), Quaternion.identity) as GameObject;
            objectDirection.x = -1f;
            break;

        case Base.DIREC.RIGHT:
            instance          = Instantiate(toInstantiate, new Vector3(from.x + OffsetSize, from.y, 0f), Quaternion.identity) as GameObject;
            objectDirection.x = 1f;
            break;
        }

        // бонусы у нас недвижимые объекты и контроллер у них соответсвенно свой
        if (instance.tag != "Bonus")
        {
            CIGameObject ctr = instance.GetComponent <CIGameObject>();
            ctr.ID = GetUnitID();
            ctr.SetDirection(objectDirection);
        }

        return(instance);
    }
コード例 #16
0
    /**********************************************************************************/
    // функция контроля скорости
    // снаряд в процессе полёта замедляется
    //
    /**********************************************************************************/
    private void SpeedManipualation()
    {
        if (m_state != BULLET_STATE.BURN)
        {
            m_currentFlyTime += Time.deltaTime;
            int currentStep = (int)Mathf.Floor(m_currentFlyTime / m_timeStep);

            // проверяем, надо ли обновить скорость и высоту полёта гранаты
            if (currentStep > m_appliedStep)
            {
                if (currentStep >= m_numOfSpeedHeshes)
                {
                    m_state = BULLET_STATE.BURN;
                    speed   = 0.0f;
                    m_animator.SetBool("Burn", true);
                    BurstSystem.Play();
                    PlayBurstSoundEffect();

                    BlowUpGrenade();
                    return;
                }

                Point      directionVector = new Point((int)m_direction.x, (int)m_direction.y);
                Base.DIREC direction       = directionVector.ToDirection();

                switch (direction)
                {
                case Base.DIREC.LEFT:
                case Base.DIREC.RIGHT:
                    speed           = m_horisontalSpeed;
                    m_rb2d.position = new Vector2(m_rb2d.position.x, m_rb2d.position.y + m_heightDiff[currentStep]);
                    break;

                case Base.DIREC.UP:
                    speed = m_speedYHashUp[currentStep];
                    break;

                case Base.DIREC.DOWN:
                    speed = m_speedYHashDown[currentStep];
                    break;
                }

                m_appliedStep = currentStep;
            }
        }
    }
コード例 #17
0
    /**********************************************************************************/
    // создаём поражающий элемент
    //
    /**********************************************************************************/
    protected virtual void CreateBullet(Vector2 position, Base.DIREC direction)
    {
        GameObject bulletObj = ObjectFactory.GetInstance().CreateGObject(position, direction, BulletType);
        Bullet     bulletCtr = bulletObj.GetComponent <Bullet>();

        if (bulletCtr != null)
        {
            bulletCtr.Owner       = m_ownerID;
            bulletCtr.OwnerUnitID = m_unitID;
        }
        else
        {
            // некоторые типы оружия используют других существ в качестве снаряда
            // в этом случае используем GMovingObject
            CIGameObject gmo = bulletObj.GetComponent <CIGameObject>();
            gmo.Owner = m_ownerID;
        }
    }
コード例 #18
0
    /**********************************************************************************/
    // используем указанное оружие
    //
    /**********************************************************************************/
    private void UseWeapon(WeaponController ctr)
    {
        ctr.Fire();

        // приостанавливаем движени на стрельбу
        if (!m_isFiring && ResumeDrive != null)
        {
            m_isFiring = true;
            PauseDrive();
        }

        // если оружие предполагает саморазрушение юнита/объекта после использования - наносим себе ультимативный урон
        if (ctr.SelfDamaged)
        {
            Vector2    physicalUnitPosition = m_unitWithWeapon.GetGlobalPositionCenter_Unity();
            Base.DIREC directionOfMovement  = m_unitWithWeapon.MoveDirection;
            ctr.UpdateWeaponState(physicalUnitPosition, directionOfMovement);
            m_unitWithWeapon.ApplyDamage(new DamageData(100, DamageData.DAMAGE_TYPE.PHYSICAL, m_unitWithWeapon, DamageData.RESPONSE.NOT_EXPECTED));
        }
    }
コード例 #19
0
    /**********************************************************************************/
    // функция создания игровых объектов
    // используется, когда надо добавить что-то на игровую сцену
    /**********************************************************************************/
    public GameObject CreateGObject(Vector2 from, Base.DIREC direction, Base.GO_TYPE objectType, bool useOffset = true)
    {
        GameObject instance = null;

        // пробуем получить объект из кеша
        instance = GetGObjectFromCash(from, direction, objectType, useOffset);

        // если в кеше ничего нет, создаём новые объект
        if (instance == null)
        {
            instance = GetNewGObjectInstance(from, direction, objectType, useOffset);
        }

        if (instance == null)
        {
            Debug.Log("CreateGObject:: MAIN ERROR!");
        }

        return(instance);
    }
コード例 #20
0
ファイル: PathFinder.cs プロジェクト: ExShini/Crazy-Invasion
    /**********************************************************************************/
    // строим путь из from в to
    // !!!!!!! используется ТОЛЬКО при построении системы указателей !!!!!!!
    //
    /**********************************************************************************/
    private void BuildPath(Point from, Point to)
    {
        if (from.IsSamePoint(to))
        {
            Debug.LogError("We cann't build path from 1 same point");
            return;
        }

        WayNode[,] bluprintOfRoad = new WayNode[m_xSizeOfMap, m_ySizeOfMap];
        for (int x = 0; x < m_xSizeOfMap; x++)
        {
            for (int y = 0; y < m_ySizeOfMap; y++)
            {
                bluprintOfRoad[x, y] = new WayNode();
            }
        }

        PrepareBluprintOfPath(bluprintOfRoad, from, to, m_blockConnectionData, m_sizeOfBlock * 4);

        // проходим по результирующему пути задом наперёд и запоминаем направление движения
        // для системы указателей важно только направление первого шага в пути
        Base.DIREC nextDirection = Base.DIREC.NO_DIRECTION;
        Point      toProcess     = new Point(to);

        do
        {
            WayNode nodeToProcess = bluprintOfRoad[toProcess.x, toProcess.y];
            toProcess.ShiftPoint(nodeToProcess.previusRoadDirection);
            nextDirection = Base.InvertDirection(nodeToProcess.previusRoadDirection);
        } while (!toProcess.IsSamePoint(from));

        // по окончанию обработки nextDirection содержит направление первого шага по достижению точки "to" из "from"
        // его и сохраняем в таблице

        int keyToMark    = GetSingKey(from.x, from.y);  // ключик блока "from"
        int keyToConnect = GetSingKey(to.x, to.y);      // ключик блока "to"

        m_singMap[keyToMark, keyToConnect] = nextDirection;
    }
コード例 #21
0
    /**********************************************************************************/
    // создаём поражающий элемент
    //
    /**********************************************************************************/
    protected override void CreateBullet(Vector2 position, Base.DIREC direction)
    {
        // определяем направления запуска снаряда
        Point targetPosition            = m_target.GetComponent <CIGameObject>().GetGlobalPosition();
        Point unitPosition              = new Point((int)(position.x / Base.SIZE_OF_CELL), (int)(position.y / Base.SIZE_OF_CELL));
        LinkedList <Point> pathToTarget = PathFinder.GetInstance().GetWay(unitPosition, targetPosition);

        // если объект находится не в той же клетке, что и цель, используем вторую точку пути, так как она находится в направлении движения
        if (pathToTarget.Count > 1)
        {
            pathToTarget.RemoveLast();
            Point launcherPoint = pathToTarget.Last.Value;
            direction = (launcherPoint - unitPosition).ToDirection();
        }


        GameObject bulletObj = ObjectFactory.GetInstance().CreateGObject(position, direction, BulletType);
        Bullet     bulletCtr = bulletObj.GetComponent <Bullet>();

        if (bulletCtr != null)
        {
            bulletCtr.Owner       = m_ownerID;
            bulletCtr.OwnerUnitID = m_unitID;
        }
        else
        {
            // некоторые типы оружия используют других существ в качестве снаряда
            // в этом случае используем GMovingObject
            CIGameObject gmo = bulletObj.GetComponent <CIGameObject>();
            gmo.Owner = m_ownerID;

            ScarabCtr scarabCtr = bulletObj.GetComponent <ScarabCtr>();
            if (scarabCtr != null)
            {
                scarabCtr.SetTarget(m_target);
            }
        }
    }
コード例 #22
0
    /**********************************************************************************/
    // строим дорогу из точки from в точку to
    // результат записываем в bluprintOfRoadMap
    //
    /**********************************************************************************/
    void PrepareBluprintOfRoads(BlockDescriptor descriptor, WayNode[,] bluprintOfRoadMap, Point from, Point to, int sizeOfBlock)
    {
        // проверки параметров
        if (from == null || to == null || descriptor == null || bluprintOfRoadMap == null || bluprintOfRoadMap.Length == 0)
        {
            Debug.LogError("PrepareBluprintOfRoads: Wrong arguments! " + "descriptor is null? " + (descriptor == null).ToString()
                           + " from is null? " + (from == null).ToString()
                           + " to is null? " + (to == null).ToString()
                           + " bluprintOfRoadMap is null? " + (bluprintOfRoadMap == null).ToString()
                           + " bluprintOfRoadMap.Length " + bluprintOfRoadMap.Length);
            return;
        }

        LinkedList <Point> currentPontsToProcess       = new LinkedList <Point>();
        LinkedList <Point> nextIterationPontsToProcess = new LinkedList <Point>();

        // устанавливаем стартовые параметры алгоритма - начальную точку и её стоимость пути
        bluprintOfRoadMap[from.x, from.y].wayCost = 0;
        currentPontsToProcess.AddFirst(from);
        int possibleClosestDist = Mathf.Abs(from.x - to.x) + Mathf.Abs(from.y - to.y);



        int  nodeClosestDist  = possibleClosestDist;
        bool buildingComplite = false;
        int  maxSteps         = sizeOfBlock * 4;

        while (!buildingComplite && maxSteps > 0)
        {
            while (currentPontsToProcess.Count > 0)
            {
                // забираем точку для просчёта и работаем с ней
                Point currentPoint = currentPontsToProcess.First.Value;
                currentPontsToProcess.RemoveFirst();


                int currentWayCost = bluprintOfRoadMap[currentPoint.x, currentPoint.y].wayCost;

                // просчитываем верхную точку
                CalculatePoint(descriptor, bluprintOfRoadMap, currentPoint, to, Base.DIREC.DOWN, sizeOfBlock, currentWayCost, ref nodeClosestDist, currentPontsToProcess, nextIterationPontsToProcess);

                // просчитываем нижнюю точку
                CalculatePoint(descriptor, bluprintOfRoadMap, currentPoint, to, Base.DIREC.UP, sizeOfBlock, currentWayCost, ref nodeClosestDist, currentPontsToProcess, nextIterationPontsToProcess);

                // просчитываем левую точку
                CalculatePoint(descriptor, bluprintOfRoadMap, currentPoint, to, Base.DIREC.RIGHT, sizeOfBlock, currentWayCost, ref nodeClosestDist, currentPontsToProcess, nextIterationPontsToProcess);

                // просчитываем правую точку
                CalculatePoint(descriptor, bluprintOfRoadMap, currentPoint, to, Base.DIREC.LEFT, sizeOfBlock, currentWayCost, ref nodeClosestDist, currentPontsToProcess, nextIterationPontsToProcess);
            }


            // принимаем решение о дальнейших итерациях

            WayNode WayNodeFinal = bluprintOfRoadMap[to.x, to.y];
            if (WayNodeFinal.wayCost == possibleClosestDist)
            {
                buildingComplite = true;
            }
            else
            {
                // если мы исчерпали возможности для построения маршрута - завершаем проектирование маршрута
                if (WayNodeFinal.wayCost != WayNode.UNREACHABLE && nextIterationPontsToProcess.Count == 0)
                {
                    buildingComplite = true;
                }
                // в противном случае продолжаем
                else
                {
                    // меняем местами коллекции
                    LinkedList <Point> supportPointer = currentPontsToProcess;
                    currentPontsToProcess       = nextIterationPontsToProcess;
                    nextIterationPontsToProcess = supportPointer;
                }
            }

            maxSteps--;
        }


        if (!buildingComplite)
        {
            Debug.LogError("PrepareBluprintOfRoads: We cann't build way");
            Logger.CreatePathFinderErrorReport(bluprintOfRoadMap, from, to, descriptor.FreeSpaceMap);
        }
        else
        {
            // формируем направления дороги по окончанию работы алгоритма "А star!"
            Point      pointToBuild      = new Point(to);
            WayNode    nodeForBuilding   = null;
            WayNode    finalBuildingNode = bluprintOfRoadMap[from.x, from.y];
            Base.DIREC nextDirection     = Base.DIREC.NO_DIRECTION;

            maxSteps = sizeOfBlock * 4;
            do
            {
                // проверяем координыты
                if (pointToBuild.x < 0 || pointToBuild.x >= sizeOfBlock || pointToBuild.y < 0 || pointToBuild.y >= sizeOfBlock)
                {
                    continue;
                }

                nodeForBuilding = bluprintOfRoadMap[pointToBuild.x, pointToBuild.y];

                // добавляем направления, если надо
                Base.DIREC newDirection = nodeForBuilding.previusRoadDirection;
                if (!nodeForBuilding.approvedDirections.Contains(newDirection))
                {
                    nodeForBuilding.approvedDirections.Add(newDirection);
                }

                if (!nodeForBuilding.approvedDirections.Contains(nextDirection) && nextDirection != Base.DIREC.NO_DIRECTION)
                {
                    nodeForBuilding.approvedDirections.Add(nextDirection);
                }

                // устанавливаем цену дороги
                nodeForBuilding.cellCost = WayNode.ROAD_COST;

                switch (newDirection)
                {
                case Base.DIREC.DOWN:
                    pointToBuild.y--;
                    break;

                case Base.DIREC.UP:
                    pointToBuild.y++;
                    break;

                case Base.DIREC.LEFT:
                    pointToBuild.x--;
                    break;

                case Base.DIREC.RIGHT:
                    pointToBuild.x++;
                    break;

                default:
                    Debug.LogError("PrepareBluprintOfRoads: wrong direction!");
                    break;
                }

                nextDirection = Base.InvertDirection(newDirection);
                maxSteps--;
            } while (nodeForBuilding != finalBuildingNode && maxSteps > 0);
        }
    }
コード例 #23
0
    /**********************************************************************************/
    // функция создания игровых объектов
    // пытаемся найти объект в кеше
    /**********************************************************************************/
    protected GameObject GetGObjectFromCash(Vector2 from, Base.DIREC direction, Base.GO_TYPE objectType, bool useOffset)
    {
        GameObject instance        = null;
        Vector2    objectDirection = new Vector2(0f, 0f);
        Vector2    newPosition     = new Vector2(0f, 0f);

        // проверяем кеш объектов
        // если он у нас уже имеется - реиспользуем
        if (m_objectColection.ContainsKey(objectType))
        {
            LinkedList <GameObject> objectPull = m_objectColection[objectType];

            if (objectPull.Count > 0)
            {
                instance = objectPull.First.Value;
                objectPull.RemoveFirst();

                float OffsetSize = offset;
                if (!useOffset)
                {
                    OffsetSize = 0;
                }

                switch (direction)
                {
                case Base.DIREC.DOWN:
                    newPosition       = new Vector2(from.x, from.y - OffsetSize);
                    objectDirection.y = -1f;
                    break;

                case Base.DIREC.UP:
                    newPosition       = new Vector2(from.x, from.y + OffsetSize);
                    objectDirection.y = 1f;
                    break;

                case Base.DIREC.LEFT:
                    newPosition       = new Vector2(from.x - OffsetSize, from.y);
                    objectDirection.x = -1f;
                    break;

                case Base.DIREC.RIGHT:
                    newPosition       = new Vector2(from.x + OffsetSize, from.y);
                    objectDirection.x = 1f;
                    break;
                }
            }
        }
        else
        {
            // если это первое создание объекта - создаем так же для него LinkedList для последующего хранения
            m_objectColection[objectType] = new LinkedList <GameObject>();
        }

        // если нашёлся объект - устанавливаем ему направление
        if (instance != null)
        {
            Transform objTransform = instance.GetComponent <Transform>();
            objTransform.position = new Vector3(newPosition.x, newPosition.y, 0);

            if (instance.tag != "Bonus")
            {
                CIGameObject ctr = instance.GetComponent <CIGameObject>();
                ctr.SetDirection(objectDirection);

                instance.GetComponent <CIGameObject>().ResetGObject();
            }
            else
            {
                BonusCtr ctr = instance.GetComponent <BonusCtr>();
                ctr.ResetBonus();
            }
        }

        return(instance);
    }
コード例 #24
0
    /**********************************************************************************/
    // просчитываем конкретную точку построения пути
    // проверяем её стоимость и на оснеовании проверки вносим коррективы в карту маршрутов
    //
    /**********************************************************************************/
    void CalculatePoint(BlockDescriptor descriptor, WayNode[,] bluprintOfRoadMap, Point currentPoint, Point to, Base.DIREC prevPointDir, int sizeOfBlock, int currentWayCost, ref int nodeClosestDist,
                        LinkedList <Point> currentPontsToProcess, LinkedList <Point> nextIterationPontsToProcess)
    {
        // проверки параметров
        if (currentPoint == null || to == null || descriptor == null || bluprintOfRoadMap == null || bluprintOfRoadMap.Length == 0)
        {
            Debug.LogError("CalculatePoint: Wrong arguments! " + "descriptor is null? " + (descriptor == null).ToString()
                           + " currentPoint is null? " + (currentPoint == null).ToString()
                           + " prevPointDir " + prevPointDir.ToString()
                           + " to is null? " + (to == null).ToString()
                           + " bluprintOfRoadMap is null? " + (bluprintOfRoadMap == null).ToString()
                           + " bluprintOfRoadMap.Length " + bluprintOfRoadMap.Length);
            return;
        }


        int newX = currentPoint.x;
        int newY = currentPoint.y;

        // выбираем координаты новой точки в зависимости от положения предыдущей
        switch (prevPointDir)
        {
        case Base.DIREC.DOWN:
            newY++;
            break;

        case Base.DIREC.UP:
            newY--;
            break;

        case Base.DIREC.LEFT:
            newX++;
            break;

        case Base.DIREC.RIGHT:
            newX--;
            break;
        }

        // если координата удовлетворяет ...
        if (newX < 0 || newX >= sizeOfBlock || newY < 0 || newY >= sizeOfBlock)
        {
            return;
        }

        // ... и место свободно для дорог - процессим
        if (descriptor.FreeWaysMap[newX, newY] == false)
        {
            return;
        }


        WayNode wayNodeToCheck  = bluprintOfRoadMap[newX, newY];
        int     possibleWayCost = currentWayCost + wayNodeToCheck.cellCost;
        Point   pointToCheck    = null;

        if (wayNodeToCheck.wayCost > possibleWayCost)
        {
            wayNodeToCheck.wayCost = possibleWayCost;
            wayNodeToCheck.previusRoadDirection = prevPointDir;
            pointToCheck = new Point(newX, newY);
        }
        else if (wayNodeToCheck.wayCost == possibleWayCost)
        {
            // в случае, если стоимости равны - в половине случаев переключаемся на новый путь для разнообразия
            if (Random.Range(0, 100) >= 50)
            {
                wayNodeToCheck.wayCost = possibleWayCost;
                wayNodeToCheck.previusRoadDirection = prevPointDir;
            }
        }

        // если мы нашли точку для просчёта - определяемся когда будем её просчитывать
        // если "квадратное" растояние меньше или равно самого близкого к целевой точке, то будем просчитывать её в первую очередь
        if (pointToCheck != null)
        {
            int dist = Mathf.Abs(pointToCheck.x - to.x) + Mathf.Abs(pointToCheck.y - to.y);

            if (dist == 0)
            {
                nodeClosestDist = 0;
                return;
            }
            else if (dist <= nodeClosestDist)
            {
                currentPontsToProcess.AddLast(pointToCheck);
                nodeClosestDist = dist;
            }
            else
            {
                nextIterationPontsToProcess.AddLast(pointToCheck);
            }
        }
    }
コード例 #25
0
ファイル: Unit.cs プロジェクト: ExShini/Crazy-Invasion
 /**********************************************************************************/
 // данное переопределение передаёт контроллеру данные о направлении движении и сохраняет
 // информацию для дальнейшего использования
 //
 /**********************************************************************************/
 override public void MoveGObject(Base.DIREC direction)
 {
     SetMovementDirection(direction);
     base.MoveGObject(direction);
 }
コード例 #26
0
 /**********************************************************************************/
 // Создаём луч лазера
 //
 /**********************************************************************************/
 protected override void CreateBullet(Vector2 position, Base.DIREC direction)
 {
     m_ctr.Fire(position, direction);
 }
コード例 #27
0
    /**********************************************************************************/
    // функция брожения по округе, выбирает рандомный соседний блок и плюхает туда
    //
    /**********************************************************************************/
    protected void MoveToRandomeBlock()
    {
        Point currentPosition = m_unitToDrive.GetGlobalPosition();

        // проверяем - надо ли нам искать новую точку для движения
        bool haveToChouseNewPoint = false;

        if (m_pointToMove == null)
        {
            haveToChouseNewPoint = true;
        }
        else if (currentPosition.IsSamePoint(m_pointToMove))
        {
            haveToChouseNewPoint = true;
        }

        // выбираем рандомный соседний блок
        if (haveToChouseNewPoint)
        {
            // двигаемся в соседний блок
            bool  blockIsOk = false;
            Point randomPointInRandomClosestBlock = new Point();
            Point pointToCheck = new Point();


            // симулируем точку в соседнем блоке
            while (!blockIsOk)
            {
                randomPointInRandomClosestBlock.x = 0;
                randomPointInRandomClosestBlock.y = 0;
                Base.DIREC randomDir = Base.GetRandomDirection();

                randomPointInRandomClosestBlock.ShiftPoint(randomDir);
                int sizeOfBlock = MapGenerator.GetInstance().SizeOfBlocks;
                randomPointInRandomClosestBlock.x *= sizeOfBlock;
                randomPointInRandomClosestBlock.y *= sizeOfBlock;

                randomPointInRandomClosestBlock += currentPosition;
                blockIsOk = MapGenerator.GetInstance().CheckCoordinates(randomPointInRandomClosestBlock.x, randomPointInRandomClosestBlock.y);

                // если точка действительно существует (а значит и существует блок для этой точки), выбираем рандомную свободную точку в этом блоке
                if (blockIsOk)
                {
                    Point blockPosition = new Point(randomPointInRandomClosestBlock.x / sizeOfBlock, randomPointInRandomClosestBlock.y / sizeOfBlock);
                    bool  pointIsOk     = false;

                    while (!pointIsOk)
                    {
                        int xShift = Random.Range(0, sizeOfBlock);
                        int yShift = Random.Range(0, sizeOfBlock);

                        pointToCheck = new Point(blockPosition.x * sizeOfBlock + xShift, blockPosition.y * sizeOfBlock + yShift);
                        pointIsOk    = PathFinder.GetInstance().ValidatePathCell(pointToCheck);
                    }
                }
            }

            LinkedList <Point> path = PathFinder.GetInstance().GetWay(currentPosition, pointToCheck);

            // сохраняем первую в списке точку, как точку в соседнем блоке, до которой мы будем пытаться добраться
            m_pointToMove = path.First.Value;
        }

        // двигаемся к заданной точке
        MoveToPoint(m_pointToMove);
    }
コード例 #28
0
    /**********************************************************************************/
    // обновляем правила дорог для блока
    // если этого не сделать, то возможны колизии в соседних блоках, особенно это касается предопределённых блоков
    //
    /**********************************************************************************/
    public void UpdateRulesForBlock(int x, int y, ROAD_CONNECTION_STATUS[] roadConnections)
    {
        // проверки параметров
        if (x < 0 || y < 0 || roadConnections == null || roadConnections.Length != (int)Base.DIREC.NUM_OF_DIRECTIONS)
        {
            Debug.LogError("UpdateRulesForBlock: Wrong arguments! " + "x " + x + " y " + y + "roadConnections is null? " + (roadConnections == null).ToString() + " roadConnections.Length " + roadConnections.Length);
            return;
        }

        // обновляем правила для текущего и соседних блоков
        for (int i = 0; i < (int)Base.DIREC.NUM_OF_DIRECTIONS; i++)
        {
            if (roadConnections[i] != ROAD_CONNECTION_STATUS.BLOCKED)
            {
                m_blockRoadRulesDescriptor[x, y].RoadConnections[i] = ROAD_CONNECTION_STATUS.NEEDED;
                roadConnections[i] = ROAD_CONNECTION_STATUS.NEEDED;
            }
            else
            {
                m_blockRoadRulesDescriptor[x, y].RoadConnections[i] = ROAD_CONNECTION_STATUS.BLOCKED;
            }
        }

        // проходим по окрестным блокам и обновляем условия
        // правила должны быть синхронизированы в соседних блоках
        for (int direction = (int)Base.DIREC.DOWN; direction < (int)Base.DIREC.NUM_OF_DIRECTIONS; direction++)
        {
            Point blockToUpdateCor = new Point(x, y);
            switch (direction)
            {
            case (int)Base.DIREC.DOWN:
                blockToUpdateCor.y--;
                break;

            case (int)Base.DIREC.UP:
                blockToUpdateCor.y++;
                break;

            case (int)Base.DIREC.LEFT:
                blockToUpdateCor.x--;
                break;

            case (int)Base.DIREC.RIGHT:
                blockToUpdateCor.x++;
                break;

            default:
                Debug.LogError("PrepareBluprintOfRoads: wrong direction!");
                break;
            }

            // проверяем координыты
            if (blockToUpdateCor.x < 0 || blockToUpdateCor.x >= m_blockRoadRulesDescriptor.GetLength(0) || blockToUpdateCor.y < 0 || blockToUpdateCor.y >= m_blockRoadRulesDescriptor.GetLength(1))
            {
                continue;
            }

            BlockDescriptorImitation blockToUpdates = m_blockRoadRulesDescriptor[blockToUpdateCor.x, blockToUpdateCor.y];
            Base.DIREC connectionToUpdate           = Base.InvertDirection(direction);

            // синхронизируем
            blockToUpdates.RoadConnections[(int)connectionToUpdate] = m_blockRoadRulesDescriptor[x, y].RoadConnections[(int)direction];
        }
    }
コード例 #29
0
ファイル: PathFinder.cs プロジェクト: ExShini/Crazy-Invasion
    /**********************************************************************************/
    // просчитываем конкретную точку построения пути
    // проверяем её стоимость и на оснеовании проверки вносим коррективы в карту маршрутов
    //
    /**********************************************************************************/
    void CalculatePoint(WayNode[,] bluprintOfRoadMap, Point currentPoint, Point to, Base.DIREC prevPointDir, int currentWayCost, ref int nodeClosestDist,
                        LinkedList <Point> currentPontsToProcess, LinkedList <Point> nextIterationPontsToProcess)
    {
        int newX = currentPoint.x;
        int newY = currentPoint.y;

        // выбираем координаты новой точки в зависимости от положения предыдущей
        switch (prevPointDir)
        {
        case Base.DIREC.DOWN:
            newY++;
            break;

        case Base.DIREC.UP:
            newY--;
            break;

        case Base.DIREC.LEFT:
            newX++;
            break;

        case Base.DIREC.RIGHT:
            newX--;
            break;
        }

        // если координата удовлетворяет ...
        if (newX < 0 || newX >= bluprintOfRoadMap.GetLength(0) || newY < 0 || newY >= bluprintOfRoadMap.GetLength(1))
        {
            return;
        }

        WayNode wayNodeToCheck = bluprintOfRoadMap[newX, newY];

        // формирование цены прохода происходит из стоимости предыдущих клеток + стоимость прохода по клетке + загруженность пути
        int   possibleWayCost = currentWayCost + wayNodeToCheck.cellCost + m_trafficData[newX, newY];
        Point pointToCheck    = null;

        if (wayNodeToCheck.wayCost > possibleWayCost)
        {
            wayNodeToCheck.wayCost = possibleWayCost;
            wayNodeToCheck.previusRoadDirection = prevPointDir;
            pointToCheck = new Point(newX, newY);
        }
        else if (wayNodeToCheck.wayCost == possibleWayCost)
        {
            // в случае, если стоимости равны - в половине случаев переключаемся на новый путь для разнообразия
            if (Random.Range(0, 100) >= 50)
            {
                wayNodeToCheck.wayCost = possibleWayCost;
                wayNodeToCheck.previusRoadDirection = prevPointDir;
            }
        }

        // если мы нашли точку для просчёта - определяемся когда будем её просчитывать
        // если "квадратное" растояние меньше или равно самого близкого к целевой точке, то будем просчитывать её в первую очередь
        if (pointToCheck != null)
        {
            int dist = Mathf.Abs(pointToCheck.x - to.x) + Mathf.Abs(pointToCheck.y - to.y);

            if (dist == 0)
            {
                nodeClosestDist = 0;
                return;
            }
            else if (dist <= nodeClosestDist)
            {
                currentPontsToProcess.AddLast(pointToCheck);
                nodeClosestDist = dist;
            }
            else
            {
                nextIterationPontsToProcess.AddLast(pointToCheck);
            }
        }
    }
コード例 #30
0
ファイル: PathFinder.cs プロジェクト: ExShini/Crazy-Invasion
    /**********************************************************************************/
    // ГЛАВНАЯ ФУНКЦИЯ ПОИСКА ПУТИ ИЗ ОДНОЙ ТОЧКИ ПРОСТРАНСТВА В ДРУГУЮ
    // оценивает позиции объектов и выбирает оптимальные точки для достижения цели
    //
    // ВНИМАНИЕ: для оптимизации при построении пути между удалёнными точками функция будет возвращать путь
    // до промежуточной точки
    //
    /**********************************************************************************/
    public LinkedList <Point> GetWay(Point from, Point to)
    {
        // определяем в одном или в разных блоках находятся точки
        Point blockFromPosition = new Point(from.x / m_sizeOfBlock, from.y / m_sizeOfBlock);
        Point blockToPosition   = new Point(to.x / m_sizeOfBlock, to.y / m_sizeOfBlock);
        Point distanceVector    = blockToPosition - blockFromPosition;


        // если from и to находятся в рамках соседних блоков - строим прямой маршрут
        if (Mathf.Abs(distanceVector.x) < 2 && Mathf.Abs(distanceVector.y) < 2)
        {
            return(BuildSpecificWay(from, to));
        }
        // если в разных - смотрим в каком направлении необходимо осуществить движение и идём в сторону выхода
        else
        {
            MapGenerator mg = MapGenerator.GetInstance();
            if (!mg.CheckCoordinates(from) || !mg.CheckCoordinates(to))
            {
                Debug.LogError("Wrong coordinates");
            }

            // выбираем переходный блок для построения пути, но обрезаем длину пути ограничиваясь только
            // соседними блоками
            // укорачивание по Х
            if (distanceVector.x > 1)
            {
                distanceVector.x = 1;
            }
            else if (distanceVector.x < -1)
            {
                distanceVector.x = -1;
            }

            // укорачивание по Y
            if (distanceVector.y > 1)
            {
                distanceVector.y = 1;
            }
            else if (distanceVector.y < -1)
            {
                distanceVector.y = -1;
            }

            // определяемся с новой точкой выхода
            Point exitBlockShift = blockFromPosition + distanceVector;

            // определяем точку выхода из блока в блок, расположенный ближе к цели
            int fromKey = GetSingKey(exitBlockShift.x, exitBlockShift.y);
            int toKey   = GetSingKey(blockToPosition.x, blockToPosition.y);


            if (fromKey < 0 || fromKey >= m_singMap.GetLength(0) || toKey < 0 || toKey >= m_singMap.GetLength(1))
            {
                Debug.LogError("Wrong coordinates");
            }

            Base.DIREC directionToMove = m_singMap[fromKey, toKey];
            Point      exitPoint       = new Point(m_exitBlockPoints[(int)directionToMove]);
            Point      transferPoint   = new Point(m_transferBlockPoints[(int)directionToMove]);

            exitPoint.x += exitBlockShift.x * m_sizeOfBlock;
            exitPoint.y += exitBlockShift.y * m_sizeOfBlock;

            transferPoint.x += exitBlockShift.x * m_sizeOfBlock;
            transferPoint.y += exitBlockShift.y * m_sizeOfBlock;

            // строим путь до точки выхода
            LinkedList <Point> way = BuildSpecificWay(from, exitPoint);
            // добавляем трансферную точку (точка входа в блок, в который будет происходить переход) и возвращаем путь
            way.AddFirst(transferPoint);
            return(way);
        }
    }