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); }
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); }
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); }
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(); } }
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); }
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(); }
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()); }
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. }
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); } } }
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; } } } }
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); }
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); } } } } }
/// <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; } }
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(); } }
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); } } } }
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)); }
private bool IsNearBase() { return(AntMath.Distance(_t.position, _base.position) < 0.1f); }
private bool IsSeeBase() { return(AntMath.Distance(_t.position, _base.position) < 1.5f); }
private bool IsSeeCargo() { return(AntMath.Distance(_t.position, _cargo.position) < 1.0f); }
public float Heuristic(WayPoint aGoal) { return(AntMath.Distance(position, aGoal.position)); }
/// <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); } } } } } }