コード例 #1
0
        protected bool OnMove()
        {
            if (Config.Instance.showCurrentWay)
            {
                DrawWay();
            }

            // Достигли текущей точки!
            if (AntMath.Distance((Vector2)_control.Position, _nextPoint) < WayMap.Current.approachRadius)
            {
                NextPoint();
            }

            // Рулежка.
            UpdateAngle();
            if (!AntMath.Equal(AntMath.Angle(_control.Angle), AntMath.Angle(_targetAngle), 1.0f))
            {
                float curAng = AntMath.Angle(_control.Angle);
                float tarAng = AntMath.Angle(_targetAngle);
                if (Mathf.Abs(curAng - tarAng) > 180.0f)
                {
                    if (curAng > tarAng)
                    {
                        tarAng += 360.0f;
                    }
                    else
                    {
                        tarAng -= 360.0f;
                    }
                }

                if (curAng < tarAng)
                {
                    _control.isLeft  = true;
                    _control.isRight = false;
                }
                else if (curAng > tarAng)
                {
                    _control.isLeft  = false;
                    _control.isRight = true;
                }
            }
            else
            {
                _control.isLeft  = false;
                _control.isRight = false;

                // Газ.
                if (!_isWayFinished)
                {
                    _control.isForward = true;
                }
                else
                {
                    _control.isForward = false;
                }
            }

            return(_isWayFinished);
        }
コード例 #2
0
        public override void Execute(float aDeltaTime, float aTimeScale)
        {
            // Aim on the target.
            if (!AntMath.Equal(AntMath.Angle(_control.towerRef.Angle), AntMath.Angle(_targetAngle), 1.0f))
            {
                float curAng = AntMath.Angle(_control.towerRef.Angle);
                float tarAng = AntMath.Angle(_targetAngle);
                if (Mathf.Abs(curAng - tarAng) > 180.0f)
                {
                    if (curAng > tarAng)
                    {
                        tarAng += 360.0f;
                    }
                    else
                    {
                        tarAng -= 360.0f;
                    }
                }

                if (curAng < tarAng)
                {
                    _control.RotateTower(1.0f, aDeltaTime);
                }
                else if (curAng > tarAng)
                {
                    _control.RotateTower(-1.0f, aDeltaTime);
                }
            }
            else
            {
                Finish();
            }
        }
コード例 #3
0
 public bool IsSee(Vector2 aPoint)
 {
     if (AntMath.Distance(_t.position.x, _t.position.y, aPoint.x, aPoint.y) < radius)
     {
         float angle = AntMath.Angle(AntMath.AngleDeg(_t.position.x, _t.position.y, aPoint.x, aPoint.y));
         float diff  = AntMath.AngleDifferenceDeg(angle, Angle);
         if (AntMath.InRange(diff, lowerLimit, upperLimit))
         {
             if (Config.Instance.showVision)
             {
                 AntDrawer.DrawLine(_t.position.x, _t.position.y, aPoint.x, aPoint.y, Color.yellow);
             }
             return(true);
         }
     }
     return(false);
 }
コード例 #4
0
        public override void Update(float aDeltaTime)
        {
            // Процесс наведения на цель.
            if (!AntMath.Equal(AntMath.Angle(_control.Tower.Angle), AntMath.Angle(_targetAngle), 1.0f))
            {
                float curAng = AntMath.Angle(_control.Tower.Angle);
                float tarAng = AntMath.Angle(_targetAngle);
                if (Mathf.Abs(curAng - tarAng) > 180.0f)
                {
                    if (curAng > tarAng)
                    {
                        tarAng += 360.0f;
                    }
                    else
                    {
                        tarAng -= 360.0f;
                    }
                }

                if (curAng < tarAng)
                {
                    _control.isTowerLeft  = true;
                    _control.isTowerRight = false;
                }
                else if (curAng > tarAng)
                {
                    _control.isTowerLeft  = false;
                    _control.isTowerRight = true;
                }
            }
            else
            {
                _control.isTowerLeft  = false;
                _control.isTowerRight = false;
            }
        }
コード例 #5
0
        public void GetConditions(AntAIAgent aAgent, AntAICondition aWorldState)
        {
            // Получаем список всех объектов которые необходимо отслеживать.
            if (_visualNodes == null)
            {
                _visualNodes = AntEngine.Current.GetNodes <VisualNode>();
            }

            // 1. Обновляем информацию о себе.
            // -------------------------------
            aWorldState.Set(aAgent.planner, "ArmedWithGun", control.Tower.HasGun);
            aWorldState.Set(aAgent.planner, "ArmedWithBomb", control.Tower.HasBomb);
            aWorldState.Set(aAgent.planner, "HasAmmo", control.Tower.HasAmmo);
            aWorldState.Set(aAgent.planner, "Injured", (health.HP != health.maxHP));
            aWorldState.Set(aAgent.planner, "EnemyAlive", true);             // Наш враг всегда жив, потому что респавнится.
            aWorldState.Set(aAgent.planner, "Alive", (health.HP > 0.0f));
            aWorldState.Set(aAgent.planner, "HasObstacle", sensor.HasObstacle);

            if (sensor.HasObstacle)
            {
                sensor.HasObstacle = false;
            }

            // 2. Обрабатываем зрение.
            // -----------------------
            // Сбрасываем состояние всех возможных значений зрения.
            aWorldState.Set(aAgent.planner, "NearEnemy", false);
            aWorldState.Set(aAgent.planner, "EnemyVisible", false);
            aWorldState.Set(aAgent.planner, "GunInlineOfSight", false);
            aWorldState.Set(aAgent.planner, "AmmoInlineOfSight", false);
            aWorldState.Set(aAgent.planner, "BombInlineOfSight", false);
            aWorldState.Set(aAgent.planner, "HealInlineOfSight", false);

            VisualNode visual;

            // Перебираем все объекты которые можно просматривать.
            for (int i = 0, n = _visualNodes.Count; i < n; i++)
            {
                visual = _visualNodes[i];
                // Если объект из другой группы.
                if (vision.group != visual.Visual.group)
                {
                    // Если объект попадает в область зрения.
                    if (vision.IsSee(visual.entity.Position))
                    {
                        blackboard[visual.Visual.conditionName].AsBool = true;
                        blackboard[string.Concat(visual.Visual.conditionName, "_Pos")].AsVector2 = visual.entity.Position;

                        // Отмечаем что видим.
                        aWorldState.Set(aAgent.planner, visual.Visual.conditionName, true);

                        if (vision.enemyGroup == visual.Visual.group &&
                            AntMath.Distance(control.Position, visual.entity.Position) < 1.5f)
                        {
                            aWorldState.Set(aAgent.planner, "NearEnemy", true);
                        }
                    }
                }
            }

            // 3. Обрабатываем наведение пушки на врага.
            // -----------------------------------------
            aWorldState.Set(aAgent.planner, "EnemyLinedUp", false);
            if (aWorldState.Has(aAgent.planner, "EnemyVisible") && control.Tower.HasGun)
            {
                if (blackboard["EnemyVisible"].AsBool)
                {
                    float angle = AntMath.AngleDeg((Vector2)control.Position, blackboard["EnemyVisible_Pos"].AsVector2);
                    if (AntMath.Equal(AntMath.Angle(control.Tower.Angle), AntMath.Angle(angle), 10.0f))
                    {
                        aWorldState.Set(aAgent.planner, "EnemyLinedUp", true);
                    }
                }
            }
        }
コード例 #6
0
        private void UpdateMovement()
        {
            if (AntMath.Distance(_currentPoint, (Vector2)_t.position) < 0.5f)
            {
                // Arrived to the current way point.
                _pointIndex++;
                if (_pointIndex < _route.Count)
                {
                    // Move to next one.
                    _currentPoint = _route[_pointIndex];
                }
                else
                {
                    // This is end of the way.
                    float dist = AntMath.Distance(_currentPoint, (Vector2)_t.position);
                    if (dist < 0.5f)
                    {
                        // Enable break.
                        _speed   = AntMath.Lerp(_speed, 0.0f, 1.0f - breakCurve.Evaluate(dist / 0.5f));
                        _isBrake = true;
                    }

                    if (AntMath.Equal(_speed, 0.0f, 0.1f))
                    {
                        // Absolutely arrived.
                        StopMove();
                        if (EventArrived != null)
                        {
                            EventArrived(this);
                        }
                    }
                }

                _steeringTime = 0.0f;
                _isSteering   = false;
            }

            float targetAngle = AntMath.Angle(AntMath.AngleDeg(_t.position, _currentPoint));

            _debugTargetAngle = targetAngle * AntMath.RADIANS;
            float angleDiff = AntMath.AngleDifference(Angle, targetAngle) * AntMath.DEGREES;

            // If our direction incorrect.
            if (!AntMath.Equal(angleDiff, 0.0f, 0.01f) && !_isSteering)
            {
                // Correct our angle to the current way point.
                _isSteering        = true;
                _steeringTime      = 0.0f;
                _totalSteeringTime = totalSteeringTime * (1.0f - Mathf.Abs(angleDiff / 360.0f));
            }

            // Acceleration!
            if (!_isBrake && _accelerationTime < totalAccelTime)
            {
                _accelerationTime += Time.deltaTime;
                _speed             = AntMath.Lerp(_speed, moveSpeed, accelCurve.Evaluate(_accelerationTime / totalAccelTime));
            }

            // Correction of the angle.
            if (_isSteering)
            {
                _steeringTime += Time.deltaTime;
                Angle          = AntMath.LerpAngleDeg(Angle, targetAngle, steeringCurve.Evaluate(_steeringTime / _totalSteeringTime));
                if (AntMath.Equal(angleDiff, 0.0f, 0.01f))
                {
                    _isSteering   = false;
                    _steeringTime = 0.0f;
                }
            }

            // Movement.
            float ang = Angle * AntMath.RADIANS;

            Velocity = new Vector2(_speed * Mathf.Cos(ang), _speed * Mathf.Sin(ang));
        }
コード例 #7
0
        public void CollectConditions(AntAIAgent aAgent, AntAICondition aWorldState)
        {
            // 1. Remove all stored data from previous ticks.
            // ----------------------------------------------
            ClearSensors();

            // 2. Get fresh Vision and Touch data.
            // -----------------------------
            UpdateVision();
            UpdateTouch();

            // 3. Update World State.
            // ----------------------
            aWorldState.Set(TankScenario.Alive, true);
            aWorldState.Set(TankScenario.Injured, (_control.Health < _control.maxHealth));
            aWorldState.Set(TankScenario.EnemyAlive, true);             // All time is true ;)

            aWorldState.Set(TankScenario.HasGun, _control.Tower.IsHasGun);
            aWorldState.Set(TankScenario.HasAmmo, _control.Tower.IsHasAmmo);
            aWorldState.Set(TankScenario.HasBomb, _control.Tower.IsHasBomb);

            // Reset items visibility.
            aWorldState.Set(TankScenario.SeeGun, false);
            aWorldState.Set(TankScenario.SeeAmmo, false);
            aWorldState.Set(TankScenario.SeeBomb, false);
            aWorldState.Set(TankScenario.SeeRepair, false);

            // Update vision for items.
            for (int i = 0; i < SEE_ITEMS_COUNT; i++)
            {
                if (_seeItems[i] != null)
                {
                    // Adds founded spawner and item to the our memory.
                    // This data maybe will be required by bot in the near future.
                    _blackboard.TrackSpawner(_seeItems[i].Position, _seeItems[i].kind);
                    _blackboard.TrackItem(_seeItems[i], _seeItems[i].kind);

                    // Update the world state.
                    switch (_seeItems[i].kind)
                    {
                    case ItemKind.Gun:
                        aWorldState.Set(TankScenario.SeeGun, true);
                        break;

                    case ItemKind.Ammo:
                        aWorldState.Set(TankScenario.SeeAmmo, true);
                        break;

                    case ItemKind.Bomb:
                        aWorldState.Set(TankScenario.SeeBomb, true);
                        break;

                    case ItemKind.Repair:
                        aWorldState.Set(TankScenario.SeeRepair, true);
                        break;
                    }
                }
            }

            // Update vision for enemies.
            aWorldState.Set(TankScenario.SeeEnemy, false);

            for (int i = 0; i < TANKS_COUNT; i++)
            {
                if (_seeTanks[i] != null)
                {
                    _blackboard.TrackTank(_seeTanks[i]);
                    aWorldState.Set(TankScenario.SeeEnemy, true);
                }
            }

            // Check the enemy on line of the fire.
            aWorldState.Set(TankScenario.OnLineofFire, false);

            if (_blackboard.HasEnemy)
            {
                float angle = AntMath.AngleDeg(_control.Position, _blackboard.EnemyTank.Position);
                if (AntMath.Equal(AntMath.Angle(angle), AntMath.Angle(_control.Tower.Angle), 10.0f))
                {
                    aWorldState.Set(TankScenario.OnLineofFire, true);
                }
            }

            // Check the touching of enemy tanks.
            aWorldState.Set(TankScenario.NearEnemy, false);

            for (int i = 0; i < TANKS_COUNT; i++)
            {
                if (_touchTanks[i] != null)
                {
                    aWorldState.Set(TankScenario.NearEnemy, true);
                    break;
                }
            }
        }