Пример #1
0
        /// <summary>
        /// Move all of the actors in the world.
        /// </summary>
        /// <param name="elapsedTime">The amount of elapsed time, in seconds.</param>
        private void MoveWorld(float elapsedTime)
        {
            Vector2 point = Vector2.Zero;

            // move each actor
            for (int i = 0; i < actors.Count; ++i)
            {
                if (actors[i].Dead)
                {
                    continue;
                }
                // determine how far they are going to move
                Vector2 movement = actors[i].Velocity * elapsedTime;
                // only allow actors that have not collided yet this frame to collide
                // -- otherwise, objects can "double-hit" and trade their momentum fast
                if (actors[i].CollidedThisFrame == false)
                {
                    movement = MoveAndCollide(actors[i], movement);
                }
                // determine the new position
                actors[i].Position += movement;
                // determine if their new position taks them through a wall
                for (int w = 0; w < walls.Length / 2; ++w)
                {
                    if (actors[i] is Projectile)
                    {
                        if (Collision.LineLineIntersect(actors[i].Position,
                                                        actors[i].Position - movement, walls[w * 2],
                                                        walls[w * 2 + 1], out point))
                        {
                            actors[i].Touch(actors[0]);
                        }
                    }
                    else
                    {
                        Collision.CircleLineCollisionResult result =
                            new Collision.CircleLineCollisionResult();
                        if (Collision.CircleLineCollide(actors[i].Position,
                                                        actors[i].Radius, walls[w * 2], walls[w * 2 + 1],
                                                        ref result))
                        {
                            // if a non-projectile hits a wall, bounce slightly
                            float vn = Vector2.Dot(actors[i].Velocity, result.Normal);
                            actors[i].Velocity -= (2.0f * vn) * result.Normal;
                            actors[i].Position += result.Normal * result.Distance;
                        }
                    }
                }
            }
        }
Пример #2
0
 /// <summary>
 /// Move all of the actors in the world.
 /// </summary>
 /// <param name="elapsedTime">The amount of elapsed time, in seconds.</param>
 private void MoveWorld(float elapsedTime)
 {
     Vector2 point = Vector2.Zero;
     // move each actor
     for (int i = 0; i < actors.Count; ++i)
     {
         if (actors[i].Dead)
         {
             continue;
         }
         // determine how far they are going to move
         Vector2 movement = actors[i].Velocity * elapsedTime;
         // only allow actors that have not collided yet this frame to collide
         // -- otherwise, objects can "double-hit" and trade their momentum fast
         if (actors[i].CollidedThisFrame == false)
         {
             movement = MoveAndCollide(actors[i], movement);
         }
         // determine the new position
         actors[i].Position += movement;
         // determine if their new position taks them through a wall
         for (int w = 0; w < walls.Length / 2; ++w)
         {
             if (actors[i] is Projectile)
             {
                 if (Collision.LineLineIntersect(actors[i].Position,
                     actors[i].Position - movement, walls[w * 2],
                     walls[w * 2 + 1], out point))
                 {
                     actors[i].Touch(actors[0]);
                 }
             }
             else
             {
                 Collision.CircleLineCollisionResult result =
                     new Collision.CircleLineCollisionResult();
                 if (Collision.CircleLineCollide(actors[i].Position,
                     actors[i].Radius, walls[w * 2], walls[w * 2 + 1],
                     ref result))
                 {
                     // if a non-projectile hits a wall, bounce slightly
                     float vn = Vector2.Dot(actors[i].Velocity, result.Normal);
                     actors[i].Velocity -= (2.0f * vn) * result.Normal;
                     actors[i].Position += result.Normal * result.Distance;
                 }
             }
         }
     }
 }
Пример #3
0
        /// <summary>
        /// Find a valid point for the actor to spawn.
        /// </summary>
        /// <param name="actor">The actor to find a location for.</param>
        /// <remarks>This query is not bounded, which would be needed in a more complex
        /// game with a likelihood of no valid spawn locations.</remarks>
        /// <returns>A valid location for the user to spawn.</returns>
        public Vector2 FindSpawnPoint(Actor actor)
        {
            if (actor == null)
            {
                throw new ArgumentNullException("actor");
            }

            Vector2 spawnPoint;
            float radius = actor.Radius;

            // fudge the radius slightly so we're not right on top of another actor
            if (actor is Ship)
            {
                radius *= 2f;
            }
            else
            {
                radius *= 1.1f;
            }
            radius = (float)Math.Ceiling(radius);

            Vector2 spawnMinimum = new Vector2(
                safeDimensions.X + radius,
                safeDimensions.Y + radius);
            Vector2 spawnDimensions = new Vector2(
                (float)Math.Floor(safeDimensions.Width - 2f * radius),
                (float)Math.Floor(safeDimensions.Height - 2f * radius));
            Vector2 spawnMaximum = spawnMinimum + spawnDimensions;

            Collision.CircleLineCollisionResult result =
                new Collision.CircleLineCollisionResult();
            bool valid = true;
            while (true)
            {
                valid = true;
                // generate a new spawn point
                spawnPoint = new Vector2(
                    spawnMinimum.X + spawnDimensions.X * (float)random.NextDouble(),
                    spawnMinimum.Y + spawnDimensions.Y * (float)random.NextDouble());
                if ((spawnPoint.X < spawnMinimum.X) ||
                    (spawnPoint.Y < spawnMinimum.Y) ||
                    (spawnPoint.X > spawnMaximum.X) ||
                    (spawnPoint.Y > spawnMaximum.Y))
                {
                    continue;
                }
                // if we don't collide, then one is good enough
                if (actor.Collidable == false)
                {
                    break;
                }
                // check against the walls
                if (valid == true)
                {
                    for (int wall = 0; wall < walls.Length / 2; wall++)
                    {
                        if (Collision.CircleLineCollide(spawnPoint, radius,
                            walls[wall * 2], walls[wall * 2 + 1], ref result))
                        {
                            valid = false;
                            break;
                        }
                    }
                }
                // check against all other actors
                if (valid == true)
                {
                    foreach (Actor checkActor in actors)
                    {
                        if ((actor == checkActor) || checkActor.Dead)
                        {
                            continue;
                        }
                        if (Collision.CircleCircleIntersect(checkActor.Position,
                            checkActor.Radius, spawnPoint, radius))
                        {
                            valid = false;
                            break;
                        }
                    }
                }
                // if we have gotten this far, then the spawn point is good
                if (valid == true)
                {
                    break;
                }
            }
            return spawnPoint;
        }
Пример #4
0
        /// <summary>
        /// Find a valid point for the actor to spawn.
        /// </summary>
        /// <param name="actor">The actor to find a location for.</param>
        /// <remarks>This query is not bounded, which would be needed in a more complex
        /// game with a likelihood of no valid spawn locations.</remarks>
        /// <returns>A valid location for the user to spawn.</returns>
        public Vector2 FindSpawnPoint(Actor actor)
        {
            if (actor == null)
            {
                throw new ArgumentNullException("actor");
            }

            Vector2 spawnPoint;
            float   radius = actor.Radius;

            // fudge the radius slightly so we're not right on top of another actor
            if (actor is Ship)
            {
                radius *= 2f;
            }
            else
            {
                radius *= 1.1f;
            }
            radius = (float)Math.Ceiling(radius);

            Vector2 spawnMinimum = new Vector2(
                safeDimensions.X + radius,
                safeDimensions.Y + radius);
            Vector2 spawnDimensions = new Vector2(
                (float)Math.Floor(safeDimensions.Width - 2f * radius),
                (float)Math.Floor(safeDimensions.Height - 2f * radius));
            Vector2 spawnMaximum = spawnMinimum + spawnDimensions;

            Collision.CircleLineCollisionResult result =
                new Collision.CircleLineCollisionResult();
            bool valid = true;

            while (true)
            {
                valid = true;
                // generate a new spawn point
                spawnPoint = new Vector2(
                    spawnMinimum.X + spawnDimensions.X * (float)random.NextDouble(),
                    spawnMinimum.Y + spawnDimensions.Y * (float)random.NextDouble());
                if ((spawnPoint.X < spawnMinimum.X) ||
                    (spawnPoint.Y < spawnMinimum.Y) ||
                    (spawnPoint.X > spawnMaximum.X) ||
                    (spawnPoint.Y > spawnMaximum.Y))
                {
                    continue;
                }
                // if we don't collide, then one is good enough
                if (actor.Collidable == false)
                {
                    break;
                }
                // check against the walls
                if (valid == true)
                {
                    for (int wall = 0; wall < walls.Length / 2; wall++)
                    {
                        if (Collision.CircleLineCollide(spawnPoint, radius,
                                                        walls[wall * 2], walls[wall * 2 + 1], ref result))
                        {
                            valid = false;
                            break;
                        }
                    }
                }
                // check against all other actors
                if (valid == true)
                {
                    foreach (Actor checkActor in actors)
                    {
                        if ((actor == checkActor) || checkActor.Dead)
                        {
                            continue;
                        }
                        if (Collision.CircleCircleIntersect(checkActor.Position,
                                                            checkActor.Radius, spawnPoint, radius))
                        {
                            valid = false;
                            break;
                        }
                    }
                }
                // if we have gotten this far, then the spawn point is good
                if (valid == true)
                {
                    break;
                }
            }

            return(spawnPoint);
        }