コード例 #1
0
        /// <summary>
        /// Find a valid spawn point in the world.
        /// </summary>
        /// <param name="radius">The radius of the object to be spawned.</param>
        /// <param name="random">A persistent Random object.</param>
        /// <returns>The spawn point.</returns>
        public static Vector2 FindSpawnPoint(GameplayObject spawnedObject, float radius)
        {
            // safety-check the singleton
            if (collisionManager == null)
            {
                throw new InvalidOperationException(
                          "The collision manager has not yet been initialized.");
            }

            // safety-check the parameters
            if ((radius < 0f) || (radius > Dimensions.Width / 2))
            {
                throw new ArgumentOutOfRangeException("radius");
            }

            // keep trying to find a valid point
            Vector2 spawnPoint = new Vector2(
                radius + Dimensions.X +
                RandomMath.Random.Next((int)Math.Floor(Dimensions.Width - radius)),
                radius + Dimensions.Y +
                RandomMath.Random.Next((int)Math.Floor(Dimensions.Height - radius)));

            for (int i = 0; i < findSpawnPointAttempts; i++)
            {
                bool valid = true;

                // check the barriers
                if (Barriers != null)
                {
                    CollisionMath.CircleLineCollisionResult result =
                        new CollisionMath.CircleLineCollisionResult();
                    foreach (Rectangle rectangle in Barriers)
                    {
                        if (CollisionMath.CircleRectangleCollide(spawnPoint, radius,
                                                                 rectangle, ref result))
                        {
                            valid = false;
                            break;
                        }
                    }
                }

                // check the other objects
                if (valid)
                {
                    foreach (GameplayObject gameplayObject in collisionManager)
                    {
                        if (!gameplayObject.Active || (gameplayObject == spawnedObject))
                        {
                            continue;
                        }
                        if (CollisionMath.CircleCircleIntersect(spawnPoint, radius,
                                                                gameplayObject.Position, gameplayObject.Radius))
                        {
                            valid = false;
                            break;
                        }
                    }
                }
                if (valid)
                {
                    break;
                }
                spawnPoint = new Vector2(
                    radius + Dimensions.X + RandomMath.Random.Next(
                        (int)Math.Floor(Dimensions.Width - radius)),
                    radius + Dimensions.Y + RandomMath.Random.Next(
                        (int)Math.Floor(Dimensions.Height - radius)));
            }

            return(spawnPoint);
        }
コード例 #2
0
        /// <summary>
        /// Update the collision system.
        /// </summary>
        /// <param name="elapsedTime">The amount of elapsed time, in seconds.</param>
        public static void Update(float elapsedTime)
        {
            // safety-check the singleton
            if (collisionManager == null)
            {
                throw new InvalidOperationException(
                          "The collision manager has not yet been initialized.");
            }


            // move each object
            for (int i = 0; i < collisionManager.Count; ++i)
            {
                if (collisionManager[i].Active)
                {
                    // determine how far they are going to move
                    Vector2 movement = collisionManager[i].Velocity * elapsedTime;
                    // only allow collisionManager that have not collided yet
                    // collisionManager frame to collide
                    // -- otherwise, objects can "double-hit" and trade their momentum
                    if (collisionManager[i].CollidedThisFrame == false)
                    {
                        movement = MoveAndCollide(collisionManager[i], movement);
                    }
                    // determine the new position
                    collisionManager[i].Position += movement;

                    // collide with the barriers
                    for (int b = 0; b < collisionManager.barriers.Count; ++b)
                    {
                        CollisionMath.CircleLineCollisionResult result =
                            new CollisionMath.CircleLineCollisionResult();
                        if (collisionManager[i] is Projectile)
                        {
                            CollisionMath.CircleRectangleCollide(
                                collisionManager[i].Position - movement,
                                collisionManager[i].Radius,
                                collisionManager.barriers[b], ref result);
                            if (result.Collision)
                            {
                                collisionManager[i].Position -= movement;
                                collisionManager[i].Die(null, false);
                            }
                        }
                        else
                        {
                            CollisionMath.CircleRectangleCollide(
                                collisionManager[i].Position,
                                collisionManager[i].Radius,
                                collisionManager.barriers[b], ref result);
                            if (result.Collision)
                            {
                                // if a non-projectile hits a barrier, bounce slightly
                                float vn = Vector2.Dot(collisionManager[i].Velocity,
                                                       result.Normal);
                                collisionManager[i].Velocity -= (2.0f * vn) *
                                                                result.Normal;
                                collisionManager[i].Position += result.Normal *
                                                                result.Distance;
                            }
                        }
                    }
                }
            }

            CollisionManager.Collection.ApplyPendingRemovals();
        }