Пример #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 int GetNearEdge(Vector2 aPosition)
        {
            float   dist;
            float   minValue = float.MaxValue;
            int     minIndex = -1;
            Vector2 edgePos = Vector2.zero;
            Vector2 a, b;

            for (int i = 0, n = edges.Count; i < n; i++)
            {
                if (!edges[i].HasNeigbors)
                {
                    a         = vertices[edges[i].a];
                    b         = vertices[edges[i].b];
                    edgePos.x = (a.x + b.x) * 0.5f;
                    edgePos.y = (a.y + b.y) * 0.5f;
                    dist      = AntMath.Distance(aPosition, edgePos);
                    if (dist < minValue)
                    {
                        minValue = dist;
                        minIndex = i;
                    }
                }
            }
            return(minIndex);
        }
Пример #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 Execute(float aDeltaTime, float aTimeScale)
    {
        // Move to the cargo.
        var pos = _t.position;

        pos.x      += SPEED * aDeltaTime * Mathf.Cos(_targetAngle);
        pos.y      += SPEED * aDeltaTime * Mathf.Sin(_targetAngle);
        _t.position = pos;

        // Check distance to the cargo.
        if (AntMath.Distance(pos, _targetPos) <= 0.2f)
        {
            // We arrived!
            // Current action is finished.
            Finish();
        }
    }
Пример #5
0
        public int FindNearNode(Vector2 aPoint)
        {
            float dist        = 0.0f;
            float minDistance = float.MaxValue;
            int   minIndex    = -1;

            for (int i = 0, n = nodes.Count; i < n; i++)
            {
                dist = AntMath.Distance(aPoint, nodes[i].position);
                if (dist < minDistance)
                {
                    minDistance = dist;
                    minIndex    = i;
                }
            }
            return(minIndex);
        }
        private int FindNearVertex(int aVertexIndex, float aRadius)
        {
            float dist;

            for (int i = 0, n = _self.vertices.Count; i < n; i++)
            {
                if (aVertexIndex != i)
                {
                    dist = AntMath.Distance(_self.vertices[aVertexIndex], _self.vertices[i]);
                    if (dist < aRadius)
                    {
                        return(i);
                    }
                }
            }
            return(-1);
        }
Пример #7
0
        private void DrawLinks()
        {
            Vector2 current;

            AntDrawer.BeginHandles(Handles.matrix);
            for (int i = 0, n = _self.wayPoints.Count; i < n; i++)
            {
                current = _self.wayPoints[i];
                for (int j = 0; j < n; j++)
                {
                    if (i != j && AntMath.Distance(current, _self.wayPoints[j]) <= _self.linkRadius)
                    {
                        AntDrawer.DrawLine(current, _self.wayPoints[j], Color.yellow);
                    }
                }
            }
            AntDrawer.EndHandles();
        }
Пример #8
0
        private void LinkMap()
        {
            WayPoint current;
            WayPoint other;

            for (int i = 0, n = points.Count; i < n; i++)
            {
                current = points[i];
                for (int j = 0; j < n; j++)
                {
                    other = points[j];
                    if (AntMath.Distance(current.position, other.position) <= linkRadius)
                    {
                        current.AddNeighbor(other);
                    }
                }
            }
        }
        /// <summary>
        /// This function finds some info about specified item in tank memory,
        /// and if we found info, then moving to the founded position.
        /// </summary>
        /// <param name="aKind">Kind of the item that we want to find.</param>
        public void SearchItem(ItemKind aKind)
        {
            var targetPoint = Vector2.zero;

            if (_blackboard.GetSpawner(aKind, out targetPoint))
            {
                // If we found in our memory where is item spawner,
                // then move to this point.
                if (AntMath.Distance(_control.Position, targetPoint) > 0.8f)
                {
                    MoveTo(targetPoint);
                    return;
                }
            }

            // Otherwise just move to the random point and
            // hoping for the success!
            MoveTo(GetRandomPoint());
        }
Пример #10
0
        public override void Enter()
        {
            // Explode all tanks around.
            var   G    = Game.Instance;
            var   pos  = _control.Position;
            float dist = 0.0f;

            for (int i = G.tanks.Count - 1; i >= 0; i--)
            {
                dist = AntMath.Distance(pos, G.tanks[i].Position);
                if (dist <= 1.0f)
                {
                    // Kill all tanks around.
                    G.tanks[i].Health = 0.0f;
                }
            }

            // TODO: Make explosion effect.
        }
Пример #11
0
        public override void Update(float aDeltaTime)
        {
            DropperNode    dropper;
            MagnetableNode item;
            float          dist;

            for (int i = 0, n = _dropperNodes.Count; i < n; i++)
            {
                dropper = _dropperNodes[i];
                dropper.Dropper.IsEmpty = true;

                // Проверяем все вещи на предмет их попадания в область дроппера.
                for (int j = 0, jn = _magnetableNodes.Count; j < jn; j++)
                {
                    item = _magnetableNodes[j];
                    dist = AntMath.Distance(dropper.entity.Position, item.entity.Position);
                    if (dist <= dropper.Dropper.observeRadius)
                    {
                        dropper.Dropper.IsEmpty = false;
                        break;
                    }
                }

                // Если дроппер пустой.
                if (dropper.Dropper.IsEmpty)
                {
                    dropper.Dropper.Delay -= aDeltaTime;
                    if (dropper.Dropper.Delay < 0.0f)
                    {
                        dropper.Dropper.DropItem();
                        dropper.Dropper.Delay = dropper.Dropper.rechargeTime;
                    }
                }

                if (Config.Instance.showDropperRecharge && dropper.Dropper.IsEmpty)
                {
                    AntDrawer.DrawPie(dropper.entity.Position, 0.3f, 90.0f, 0.0f,
                                      (1 - (dropper.Dropper.Delay / dropper.Dropper.rechargeTime)) * 360.0f, Color.grey);
                }
            }
        }
Пример #12
0
        private void Fire(MovementNode aNode)
        {
            if (aNode.TankControl.Tower.HasGun &&
                aNode.TankControl.Tower.HasAmmo)
            {
                Transform go  = GameObject.Instantiate((GameObject)aNode.TankControl.Tower.bulletPrefab).GetComponent <Transform>();
                float     ang = AntMath.DegToRad(aNode.TankControl.Tower.Angle);
                Vector3   p   = aNode.entity.Position3D;
                p.x        += aNode.TankControl.Tower.bulletPosition * Mathf.Cos(ang);
                p.y        += aNode.TankControl.Tower.bulletPosition * Mathf.Sin(ang);
                go.position = p;

                Vector2 force = new Vector2();
                force.x = aNode.TankControl.Tower.bulletSpeed * Mathf.Cos(ang);
                force.y = aNode.TankControl.Tower.bulletSpeed * Mathf.Sin(ang);
                go.GetComponent <Rigidbody2D>().AddForce(force, ForceMode2D.Impulse);

                Quaternion q = Quaternion.AngleAxis(aNode.TankControl.Tower.Angle, Vector3.forward);
                go.rotation = q;

                aNode.TankControl.Tower.AmmoCount--;
            }
            else if (aNode.TankControl.Tower.HasBomb)
            {
                float      dist;
                HealthNode hpNode;
                for (int i = _healthNodes.Count - 1; i >= 0; i--)
                {
                    hpNode = _healthNodes[i];
                    dist   = AntMath.Distance(aNode.entity.Position, hpNode.entity.Position);
                    if (dist < 2.5f)
                    {
                        hpNode.Health.HP = 0.0f;
                    }
                }
            }
        }
Пример #13
0
        public WayPoint FindNearestPoint(Vector2 aPosition)
        {
            AntSorter <WayPoint> sorter = new AntSorter <WayPoint>();
            WayPoint             point;
            float dist;

            for (int i = 0, n = points.Count; i < n; i++)
            {
                point = points[i];
                dist  = AntMath.Distance(aPosition, point.position);
                if (dist <= linkRadius)
                {
                    sorter.Add(point, dist);
                }
            }

            if (sorter.Count > 0)
            {
                sorter.Sort(AntSorterOrder.ASC);
                return(sorter[0]);
            }

            return(null);
        }
Пример #14
0
        public override void Update(float aDeltaTime)
        {
            float          dist  = 0.0f;
            float          ang   = 0.0f;
            Vector2        force = new Vector2();
            MagnetNode     magnet;
            MagnetableNode item;

            for (int i = 0, n = _magnetNodes.Count; i < n; i++)
            {
                magnet = _magnetNodes[i];
                for (int j = _magnetableNodes.Count - 1; j >= 0; j--)
                {
                    item = _magnetableNodes[j];
                    item.Magnetable.lifeTime += aDeltaTime;
                    dist = AntMath.Distance(magnet.entity.Position, item.entity.Position);
                    if ((magnet.Magnet.magnetKind == item.Magnetable.kind ||
                         magnet.Magnet.magnetKind == ItemKind.All) &&
                        dist < magnet.Magnet.distance &&
                        item.Magnetable.lifeTime > 2.0f)
                    {
                        ang     = AntMath.AngleRad(item.entity.Position, magnet.entity.Position);
                        force.x = magnet.Magnet.force * Mathf.Cos(ang);
                        force.y = magnet.Magnet.force * Mathf.Sin(ang);
                        item.Magnetable.body.AddForce(force, ForceMode2D.Impulse);

                        if (dist <= magnet.Magnet.collectDistance)
                        {
                            CollectItem(magnet, item);
                            Engine.RemoveEntity(item.entity);
                            GameObject.Destroy(item.entity.gameObject);
                        }
                    }
                }
            }
        }
Пример #15
0
		/// <summary>
		/// Sets enemy tank as current target.
		/// </summary>
		/// <param name="aEnemyTank">Reference to the enemy tank.</param>
		public void TrackTank(TankControl aEnemyTank)
		{
			if (_enemyTank != null && !System.Object.ReferenceEquals(_enemyTank, aEnemyTank))
			{
				// If we already tracked other tank, then check what of them is close to us?
				float dist = AntMath.Distance(_t.position, aEnemyTank.Position);
				if (dist < _enemyTankDist)
				{
					// If new enemy closer, then replace old on the new one.
					_enemyTankDist = dist;
					_enemyTank.EventDestroyed -= TankDestroyedHandler;
					_enemyTank = aEnemyTank;
					_enemyTank.EventDestroyed += TankDestroyedHandler;
				}
			}
			else
			{
				// Just track the enemy.
				_enemyTankDist = AntMath.Distance(_t.position, aEnemyTank.Position);
				_enemyTank = aEnemyTank;
				_enemyTank.EventDestroyed += TankDestroyedHandler;
				_hasEnemy = true;
			}
		}
Пример #16
0
        public override void Execute(float aDeltaTime, float aTimeScale)
        {
            if (_targetItem != null)
            {
                float dist = AntMath.Distance(_control.Position, _targetItem.Position);
                if (dist <= _control.magnetRadius)
                {
                    // Magneting our loot!
                    float angle = AntMath.AngleRad(_targetItem.Position, _control.Position);
                    var   force = new Vector2(
                        0.1f * Mathf.Cos(angle),
                        0.1f * Mathf.Sin(angle)
                        );

                    _targetItem.AddForce(force);
                    if (dist < _control.collectRadius)
                    {
                        // Yay! We got the item!
                        _targetItem.Collect();

                        switch (_itemKind)
                        {
                        case ItemKind.Gun:
                            if (_control.Tower.IsHasBomb)
                            {
                                // Drop bomb on the map.
                                Game.Instance.SpawnItem(
                                    _control.Position,
                                    ItemKind.Bomb,
                                    _control.transform.parent.transform
                                    );
                            }
                            _control.Tower.IsHasGun = true;
                            break;

                        case ItemKind.Ammo:
                            _control.Tower.GiveAmmo(3);
                            break;

                        case ItemKind.Bomb:
                            if (_control.Tower.IsHasGun)
                            {
                                // Drop gun on the map.
                                Game.Instance.SpawnItem(
                                    _control.Position,
                                    ItemKind.Gun,
                                    _control.transform.parent.transform
                                    );
                            }
                            _control.Tower.IsHasBomb = true;
                            break;

                        case ItemKind.Repair:
                            _control.Health = _control.maxHealth;
                            break;
                        }

                        Finish();
                    }
                }
            }
            else
            {
                // Item is lost :(
                // Finish the action.
                Finish();
            }
        }
Пример #17
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);
                    }
                }
            }
        }
Пример #18
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));
        }
Пример #19
0
 private bool IsNearBase()
 {
     return(AntMath.Distance(_t.position, _base.position) < 0.1f);
 }
Пример #20
0
 private bool IsSeeBase()
 {
     return(AntMath.Distance(_t.position, _base.position) < 1.5f);
 }
Пример #21
0
 private bool IsSeeCargo()
 {
     return(AntMath.Distance(_t.position, _cargo.position) < 1.0f);
 }
Пример #22
0
 public float Heuristic(WayPoint aGoal)
 {
     return(AntMath.Distance(position, aGoal.position));
 }
Пример #23
0
        /// <summary>
        /// Updates vision sensor.
        /// </summary>
        private void UpdateVision()
        {
            var G = Game.Instance;

            // 1. See on the items.
            // --------------------
            float   dist;
            float   angle;
            Vector2 seeTo;
            Vector2 seeFrom;

            for (int i = G.collectableItems.Count - 1; i >= 0; i--)
            {
                // Calc distance to the item.
                dist = AntMath.Distance(_t.position, G.collectableItems[i].Position);
                if (dist < _control.visionRadius)
                {
                    // If distance in our vision field.
                    // Try to make raycast to it.
                    angle   = AntMath.AngleRad(_t.position, G.collectableItems[i].Position);
                    seeFrom = new Vector2(
                        _t.position.x + 0.4f * Mathf.Cos(angle),
                        _t.position.y + 0.4f * Mathf.Sin(angle)
                        );

                    seeTo = new Vector2(
                        dist * Mathf.Cos(angle),
                        dist * Mathf.Sin(angle)
                        );

                    var hit = Physics2D.Raycast(seeFrom, seeTo);
                    if (hit.collider != null)
                    {
                        var ci = hit.collider.GetComponent <CollectableItem>();
                        if (ci != null)
                        {
                            // Yay! We actually can see some item.
                            // Just add it to our see list.
                            AddItem(ci);

                            // Save vision points for debug drawing.
                            if (showVision)
                            {
                                seeTo += (Vector2)G.collectableItems[i].Position;
                                _seeFrom.Add(seeFrom);
                                _seeTo.Add(G.collectableItems[i].Position);
                            }
                        }
                    }
                }
            }

            // 2. See on the enemies.
            // ----------------------
            for (int i = G.tanks.Count - 1; i >= 0; i--)
            {
                if (G.tanks[i].team == _control.team)
                {
                    // Friendly tank. Skip...
                    continue;
                }

                // Calc distance to the enemy tank.
                dist = AntMath.Distance(_t.position, G.tanks[i].Position);
                if (dist < _control.visionRadius)
                {
                    // If distance in our vision field.
                    // Try to make raycast to it.
                    angle   = AntMath.AngleRad(_t.position, G.tanks[i].Position);
                    seeFrom = new Vector2(
                        _t.position.x + 0.4f * Mathf.Cos(angle),
                        _t.position.y + 0.4f * Mathf.Sin(angle)
                        );

                    seeTo = new Vector2(
                        dist * Mathf.Cos(angle),
                        dist * Mathf.Sin(angle)
                        );

                    var hit = Physics2D.Raycast(seeFrom, seeTo);
                    if (hit.collider != null)
                    {
                        var tc = hit.collider.GetComponent <TankControl>();
                        if (tc != null && tc.team != _control.team)
                        {
                            // We actually can see enemy tank.
                            // Add it to our see list.
                            AddTank(tc);

                            // Save vision points for debug drawing.
                            if (showVision)
                            {
                                seeTo += (Vector2)G.tanks[i].Position;
                                _seeFrom.Add(seeFrom);
                                _seeTo.Add(G.tanks[i].Position);
                            }
                        }
                    }
                }
            }
        }