/// <summary> /// Luo FollowComparer-vertailijan, jolla aivot seuraavat aina lähintä oliota. /// </summary> /// <param name="changeTargetDistance"> /// Ero kahden olion etäisyyden välillä ennen kuin vaihdetaan seurattavaa kohdetta. /// Mitä pienempi arvo, sitä helpommin kohdetta vaihdetaan. /// </param> /// <returns></returns> public Comparison <IGameObject> CreateDistanceComparer(double changeTargetDistance) { return(delegate(IGameObject obj1, IGameObject obj2) { if (Owner == null) { return 0; } if (obj1 == null) { return 1; } if (obj2 == null) { return -1; } double d1 = Vector.Distance(Owner.AbsolutePosition, obj1.AbsolutePosition); double d2 = Vector.Distance(Owner.AbsolutePosition, obj2.AbsolutePosition); double diff = Math.Abs(d1 - d2); if (CurrentTarget == obj1 && diff < changeTargetDistance) { return -1; } if (CurrentTarget == obj2 && diff < changeTargetDistance) { return 1; } return d1.CompareTo(d2); }); }
private void SelectTarget() { CurrentTarget = null; foreach (var layer in Game.Instance.Layers) { foreach (var obj in layer.Objects) { if (obj == Owner || obj.IsDestroyed) { continue; } if (!ObjectsToFollow.Contains(obj) && !TagsToFollow.Contains(obj.Tag as string)) { continue; } if (CurrentTarget == null || FollowComparer(CurrentTarget, obj) > 0) { CurrentTarget = obj; } } } if (Owner != null && CurrentTarget != null) { DistanceToTarget.Value = Vector.Distance(Owner.AbsolutePosition, CurrentTarget.AbsolutePosition); } else { DistanceToTarget.Value = double.PositiveInfinity; } }
private void CalculateMomentOfInertia() { Vector center = this.Position; _calcMomentOfInertia = 0; foreach (var part in objects) { double r = Vector.Distance(center, part.Position); _calcMomentOfInertia += part.Mass * r * r; } }
/// <summary> /// Kutsutaan, kun tilaa päivitetään. /// Suurin osa päätöksenteosta tapahtuu täällä. /// </summary> protected override void Update(Time time) { double dt = Game.Time.SinceLastUpdate.TotalSeconds; if (dt <= 0) { return; } remainingDelay -= dt; if (remainingDelay <= 0 || CurrentTarget == null || !CurrentTarget.IsAddedToGame) { SelectTarget(); if (CurrentTarget == null) { return; } SetTargetPosition(dt); remainingDelay = Delay; } else { DistanceToTarget.Value = Vector.Distance(Owner.AbsolutePosition, CurrentTarget.AbsolutePosition); if (TurnWhileMoving) { Vector realDist = CurrentTarget.AbsolutePosition - Owner.AbsolutePosition; if (!double.IsNaN(realDist.Magnitude) && !double.IsInfinity(realDist.Magnitude)) { Turn(realDist.Angle); } } } double distance = DistanceToTarget.Value; bool targetClose = Math.Abs(distance) < DistanceClose; bool targetFar = Math.Abs(distance) > DistanceFar; if (targetClose && TargetClose != null) { TargetClose(); } if (targetClose) { if (CloseBrain != null) { CloseBrain.Owner = this.Owner; CloseBrain.DoUpdate(time); } if (StopWhenTargetClose) { if (Owner is PhysicsObject) { ((PhysicsObject)Owner).Stop(); } return; } } if (targetFar) { FarBrain.Owner = this.Owner; FarBrain.DoUpdate(time); return; } Vector d = targetPosition - Owner.AbsolutePosition; if (d.Magnitude > float.Epsilon) { Move(d / dt); } else if (Owner is PhysicsObject) { ((PhysicsObject)Owner).Stop(); } base.Update(time); }