コード例 #1
0
        protected void UpdateMovement()
        {
            // check if there is no explicit move request
            if (!_moveRequested)
            {
                // obtain a move from active Navigators:
                if (_myNavigator != null)
                {
                    // Navigator found. Accelerate.
                    this.Accelerate();

                    Nullable <Vector> moveDir = _myNavigator.Navigate();
                    if (moveDir == null)
                    {
                        // we've hit an impediment. kill the navigator and stop the ship.
                        _myNavigator            = null;
                        _moveDir                = null;
                        _owner.MoveSpeedCurrent = 0;
                    }
                    else if (moveDir.Value.X == Double.PositiveInfinity)
                    {
                        // goal attained. stop the navigator.
                        _myNavigator = null;
                    }
                    else
                    {
                        // request move from self
                        this.MoveRequest(moveDir.Value, true, true);
                    }
                }
            }

            // Time to do the move. Check if there is an active vector:
            if (_moveDir != null)
            {
                // do move
                this.Move();

                // if there is no move request, we need to decelerate and normalize the dir-vector.
                if (!_moveRequested && _myNavigator == null)
                {
                    this.Decelerate();
                    // careful with the boxing
                    if (_owner.MoveSpeedCurrent > 0)
                    {
                        Vector normalized = _moveDir.Value;
                        normalized.ScaleToLength(_owner.MoveSpeedCurrent);
                        this._moveDir = normalized;
                    }
                    else
                    {
                        this._moveDir = null;
                    }
                }
            }

            // Flush flags.
            _moveRequested   = false;
            _moveClipChecked = false;
        }
コード例 #2
0
        /*
         * private UInt16 _sideStepTimer = 0;
         * private Vector _sideStepDir;
         */

        /// <summary>
        /// Requests a move from the agent.
        /// </summary>
        /// <param name="direction">Move direction.</param>
        /// <param name="clipChecked">Whether the move has been clip-checked.</param>
        /// <param name="normalizedToSpeed">Whether the vector is normalized.</param>
        public void MoveRequest(Vector direction, bool clipChecked, bool normalizedToSpeed)
        {
            if (!normalizedToSpeed)
            {
                // Accelerate and normalize the move.
                this.Accelerate();
                direction.ScaleToLength(_owner.MoveSpeedCurrent);
            }

            _moveDir         = direction;
            _moveClipChecked = clipChecked;
            _moveRequested   = true;
        }
コード例 #3
0
        /// <summary>
        /// Handles a collision between two agents.
        /// </summary>
        private void HandleCollisionBetweenTwoPlayers(Creature first, Creature second)
        {
            double distance          = first.PositionDouble.DistanceTo(second.PositionDouble);
            double preferredDistance = Math.Sqrt(Math.Pow(first.RadiusX + second.RadiusX, 2) + Math.Pow(first.RadiusY + second.RadiusY, 2));

            double deltaOver2 = 0.5 * (preferredDistance - distance);

            if (deltaOver2 < 0)
            {
                return;
            }

            // push both actors in opposite direction, by a vector of length delta/2.
            Vector mover = first.PositionDouble - second.PositionDouble;

            mover.ScaleToLength(deltaOver2);
            first.PositionDouble  += mover;
            second.PositionDouble -= mover;

            // this might have cause other collisions. the algo needs fixing.
        }
コード例 #4
0
        /// <summary>
        /// Performs a terrain passability check betwee two points by doing pixel validity checks at interval delta.
        /// </summary>
        public List <Creature> RayTracerPassabilityCheckRough(Creature client, Vector v1, Vector v2, double delta)
        {
            Vector difference = v2 - v1;
            Vector deltaV     = difference;

            deltaV.ScaleToLength(delta);

            Vector currentPosition = v1;

            for (int i = 0; i < difference.Length() / deltaV.Length(); ++i)
            {
                Coords          pixel     = new Coords(CoordsType.Pixel, currentPosition);
                List <Creature> collision = _myCollider.CreatureClippingCheck(client, pixel, false);
                if (collision == null || collision.Count > 0)
                {
                    return(collision);
                }
                currentPosition += deltaV;
            }

            return(new List <Creature>());
        }
コード例 #5
0
        /*
        private UInt16 _sideStepTimer = 0;
        private Vector _sideStepDir;
        */

        /// <summary>
        /// Requests a move from the agent.
        /// </summary>
        /// <param name="direction">Move direction.</param>
        /// <param name="clipChecked">Whether the move has been clip-checked.</param>
        /// <param name="normalizedToSpeed">Whether the vector is normalized.</param>
        public void MoveRequest(Vector direction, bool clipChecked, bool normalizedToSpeed)
        {
            if (!normalizedToSpeed)
            {
                // Accelerate and normalize the move.
                this.Accelerate();
                direction.ScaleToLength(_owner.MoveSpeedCurrent);
            }

            _moveDir = direction;
            _moveClipChecked = clipChecked;
            _moveRequested = true;
        }
コード例 #6
0
        /// <summary>
        /// Obtains step towards goal. Returns null if path is blocked.
        /// Returns (infinity, infinity) if goal is reached.
        /// </summary>
        /// <returns></returns>
        public Nullable<Vector> Navigate()
        {
            ++_timeTraveled;

            // Check to see if we've arrived. In that case the navigator has finished its job.
            if (_traveler.MyCollider.CollisionCheckPixelInEllipse(_goalPixel, _traveler.PositionPixel, _traveler.RadiusX, _traveler.RadiusY))
            {
                // goal attained.
                ++Constants._navigationSuccesses;
                return new Vector(Double.PositiveInfinity, Double.PositiveInfinity);
            }

            // Check to see if we have a visible goal or if we're taking too long to get to it
            if (_visiblePixelGoal == null || _timeTraveled >= _timeTraveledUpperBound)
            {
                // no goal set. check to see if a exists and whether we're on it:
                if (_routeCoarse == null || !this._putativeCurrentPosition.Equals(_traveler.PositionTile))
                {
                    // no route or we need a recalc
                    AcquireRoute();
                }
            }

            // Check to see if we've arrived to the current visible goal. If so, get new one.
            if (_traveler.MyCollider.CollisionCheckPixelInEllipse(_visiblePixelGoal.Value, _traveler.PositionPixel, _traveler.RadiusX, _traveler.RadiusY))
            {
                AcquireVisiblePixelGoal();
            }

            // We move towards current visible pixel goal.

            // Declare movement vector
            Vector principleMoveDir = new Vector(_visiblePixelGoal.Value) - _traveler.PositionDouble;
            principleMoveDir.ScaleToLength(_traveler.MoveSpeedCurrent);
            Vector startPoint = _traveler.PositionDouble;

            // Try to move in given direction. If the move fails, offset the direction angle and try again.
            // The offsets are under a full PI in either direction (so the agent doesn't get stuck in a loop).
            // Avoidance is first attempted in one direction. If it fails, the agent tries to other direction.
            // If both directions fail, the agent gives up.
            Int32 numberOfOffsetAttempts = (Int32)(Math.PI / Constants.CollisionAvoidanceRotation);

            // flags whether avoidance direction was flipped.
            bool directionFlipped = false;

            // list of creatures the agent has asked to step aside.
            List<Creature> askedToStepAside = new List<Creature>();

            while (true)
            {
                for (sbyte i = 0; i < numberOfOffsetAttempts; ++i)
                {
                    double offsetAngle = Math.Pow(-1, (sbyte)_avoidanceDirection) * i * Constants.CollisionAvoidanceRotation;
                    Vector moveDir = principleMoveDir.Rotate(offsetAngle);

                    List<Creature> checkForCollisions = _traveler.MyCollider.RayTracerPassabilityCheckPrecise(_traveler, startPoint, startPoint + moveDir);

                    if (checkForCollisions != null)
                    {
                        if (checkForCollisions.Count > 0)
                        {
                            // ask agents in the way to move
                            foreach (Creature impediment in checkForCollisions)
                            {
                                if (!askedToStepAside.Contains(impediment))
                                {
                                    Vector vectorToImpediment = impediment.PositionDouble - _traveler.PositionDouble;
                                    vectorToImpediment.ScaleToLength(1);

                                    Vector moveDirPerpendicular = directionFlipped ? moveDir.PerpendiculatRight() : moveDir.PerpendiculatLeft();
                                    moveDirPerpendicular.ScaleToLength(1);

                                    impediment.CreatureBrain.StepAsideRequest(vectorToImpediment + moveDirPerpendicular);
                                    askedToStepAside.Add(impediment);
                                }

                            }
                        }
                        else
                        {
                            // success. update creature position.
                            //_traveler.PositionDouble = startPoint + moveDir;
                            _timeWaited = 0;
                            return moveDir;
                        }
                    }
                }

                // we failed to move anywhere. the agent tries avoidance in the other direction.
                if (!directionFlipped)
                {
                    _avoidanceDirection = (AvoidanceDir)(((sbyte)_avoidanceDirection + 1) % 2);
                    directionFlipped = true;
                }
                else
                {
                    // avoidance in either direction failed. the agent gives up.
                    // NOTE: perhaps add a brief (1 second?) waiting time for the agent before giving up.
                    ++_timeWaited;

                    if (_timeWaited >= Constants.FailedCollisionAvoidanceWaitTime)
                    {
                        // give up
                        _timeWaited = 0;
                        break;
                    }
                    else
                    {
                        // pass back static moveVector
                        return new Vector(0, 0);
                    }
                }
            }

            ++Constants._navigationFailures;
            return null;

        }
コード例 #7
0
        /// <summary>
        /// Obtains step towards goal. Returns null if path is blocked.
        /// Returns (infinity, infinity) if goal is reached.
        /// </summary>
        /// <returns></returns>
        public Nullable <Vector> Navigate()
        {
            ++_timeTraveled;

            // Check to see if we've arrived. In that case the navigator has finished its job.
            if (_traveler.MyCollider.CollisionCheckPixelInEllipse(_goalPixel, _traveler.PositionPixel, _traveler.RadiusX, _traveler.RadiusY))
            {
                // goal attained.
                ++Constants._navigationSuccesses;
                return(new Vector(Double.PositiveInfinity, Double.PositiveInfinity));
            }

            // Check to see if we have a visible goal or if we're taking too long to get to it
            if (_visiblePixelGoal == null || _timeTraveled >= _timeTraveledUpperBound)
            {
                // no goal set. check to see if a exists and whether we're on it:
                if (_routeCoarse == null || !this._putativeCurrentPosition.Equals(_traveler.PositionTile))
                {
                    // no route or we need a recalc
                    AcquireRoute();
                }
            }

            // Check to see if we've arrived to the current visible goal. If so, get new one.
            if (_traveler.MyCollider.CollisionCheckPixelInEllipse(_visiblePixelGoal.Value, _traveler.PositionPixel, _traveler.RadiusX, _traveler.RadiusY))
            {
                AcquireVisiblePixelGoal();
            }

            // We move towards current visible pixel goal.

            // Declare movement vector
            Vector principleMoveDir = new Vector(_visiblePixelGoal.Value) - _traveler.PositionDouble;

            principleMoveDir.ScaleToLength(_traveler.MoveSpeedCurrent);
            Vector startPoint = _traveler.PositionDouble;

            // Try to move in given direction. If the move fails, offset the direction angle and try again.
            // The offsets are under a full PI in either direction (so the agent doesn't get stuck in a loop).
            // Avoidance is first attempted in one direction. If it fails, the agent tries to other direction.
            // If both directions fail, the agent gives up.
            Int32 numberOfOffsetAttempts = (Int32)(Math.PI / Constants.CollisionAvoidanceRotation);

            // flags whether avoidance direction was flipped.
            bool directionFlipped = false;

            // list of creatures the agent has asked to step aside.
            List <Creature> askedToStepAside = new List <Creature>();

            while (true)
            {
                for (sbyte i = 0; i < numberOfOffsetAttempts; ++i)
                {
                    double offsetAngle = Math.Pow(-1, (sbyte)_avoidanceDirection) * i * Constants.CollisionAvoidanceRotation;
                    Vector moveDir     = principleMoveDir.Rotate(offsetAngle);

                    List <Creature> checkForCollisions = _traveler.MyCollider.RayTracerPassabilityCheckPrecise(_traveler, startPoint, startPoint + moveDir);

                    if (checkForCollisions != null)
                    {
                        if (checkForCollisions.Count > 0)
                        {
                            // ask agents in the way to move
                            foreach (Creature impediment in checkForCollisions)
                            {
                                if (!askedToStepAside.Contains(impediment))
                                {
                                    Vector vectorToImpediment = impediment.PositionDouble - _traveler.PositionDouble;
                                    vectorToImpediment.ScaleToLength(1);

                                    Vector moveDirPerpendicular = directionFlipped ? moveDir.PerpendiculatRight() : moveDir.PerpendiculatLeft();
                                    moveDirPerpendicular.ScaleToLength(1);

                                    impediment.CreatureBrain.StepAsideRequest(vectorToImpediment + moveDirPerpendicular);
                                    askedToStepAside.Add(impediment);
                                }
                            }
                        }
                        else
                        {
                            // success. update creature position.
                            //_traveler.PositionDouble = startPoint + moveDir;
                            _timeWaited = 0;
                            return(moveDir);
                        }
                    }
                }

                // we failed to move anywhere. the agent tries avoidance in the other direction.
                if (!directionFlipped)
                {
                    _avoidanceDirection = (AvoidanceDir)(((sbyte)_avoidanceDirection + 1) % 2);
                    directionFlipped    = true;
                }
                else
                {
                    // avoidance in either direction failed. the agent gives up.
                    // NOTE: perhaps add a brief (1 second?) waiting time for the agent before giving up.
                    ++_timeWaited;

                    if (_timeWaited >= Constants.FailedCollisionAvoidanceWaitTime)
                    {
                        // give up
                        _timeWaited = 0;
                        break;
                    }
                    else
                    {
                        // pass back static moveVector
                        return(new Vector(0, 0));
                    }
                }
            }

            ++Constants._navigationFailures;
            return(null);
        }