/// <summary> /// Sets the x and y acceleration of an object or group of objects to move towards a given point. /// </summary> /// <param name="objectOrGroup">The object or group of objects to move.</param> /// <param name="point">The point to move towards.</param> /// <param name="speed">The acceleration to move the object at.</param> /// <param name="radius">The radius extending from the point. An object will need to be within this area to accelerate. A value of 0 will not use a radius.</param> /// <param name="axis">The allowed movement axis of the object.</param> /// <param name="allowImmovable">A flag used to determine if an object set to immovable will be affected.</param> public static void AccelerateToPoint(GenBasic objectOrGroup, Vector2 point, float speed, float radius = 0, Axis axis = Axis.Both, bool allowImmovable = false) { if (speed != 0) { if (objectOrGroup is GenObject) { if (allowImmovable || !(objectOrGroup as GenObject).Immovable) { // Get a normalized distance vector to calculate the horizontal and vertical speeds. Vector2 distanceNormal = GetDistanceNormal(objectOrGroup as GenObject, point, axis); if (radius <= 0) (objectOrGroup as GenObject).Velocity += distanceNormal * speed * GenG.TimeStep; else { // If the object is within the radius from the point, accelerate the object towards the point. // The closer the object is to the point, the higher its acceleration will be. float accelerationFactor = MathHelper.Clamp(radius - Vector2.Distance((objectOrGroup as GenObject).CenterPosition, point), 0, 1); (objectOrGroup as GenObject).Velocity += distanceNormal * speed * accelerationFactor * GenG.TimeStep; } } } else if (objectOrGroup is GenGroup) { foreach (GenBasic basic in (objectOrGroup as GenGroup).Members) AccelerateToPoint(basic, point, speed, radius, axis, allowImmovable); } } }
/// <summary> /// Adds an object to the group. /// If the group already contains the object, the object will not be added again. /// </summary> /// <param name="basic">The object to add.</param> /// <returns>The object that was added to the group.</returns> public GenBasic Add(GenBasic basic) { // Do not add the same object twice. if (Members.Contains(basic)) return basic; Members.Add(basic); _updateMembers = true; if (Quadtree != null) { Quadtree.Add(basic); } return basic; }
/// <summary> /// Sets the x and y acceleration of an object to move in a given angle direction. /// </summary> /// <param name="objectOrGroup">The object or group of objects to move.</param> /// <param name="angle">The angle direction, in degrees, to move the object in. A value of 0 would be up, and 90 would be to the right.</param> /// <param name="speed">The acceleration to move the object at.</param> /// <param name="allowImmovable">A flag used to determine if an object set to immovable will be affected.</param> public static void AccelerateAtAngle(GenBasic objectOrGroup, float angle, float speed, bool allowImmovable = false) { if (speed != 0) { if (objectOrGroup is GenObject) { if (allowImmovable || !(objectOrGroup as GenObject).Immovable) { // Convert the angle to a normal vector to calculate the horizontal and vertical speeds. Vector2 angleVector = AngleToVector(angle); (objectOrGroup as GenObject).Acceleration = angleVector * speed; } } else if (objectOrGroup is GenGroup) { foreach (GenBasic basic in (objectOrGroup as GenGroup).Members) AccelerateAtAngle(basic, angle, speed, allowImmovable); } } }
/// <summary> /// Applies collision detection and response between an object or group of objects and the tiles of the tilemap. /// Uses an object's position to efficiently find neighboring tiles to check for collision in the tiles two-dimensional array. /// </summary> /// <param name="objectOrGroup">The object or group to check for collisions.</param> /// <param name="callback">The delegate method that will be invoked if a collision occurs.</param> /// <returns>True is a collision occurs, false if not.</returns> public bool Collide(GenBasic objectOrGroup, CollideEvent callback) { if (objectOrGroup is GenObject) return CollideObject(objectOrGroup as GenObject, callback); if (objectOrGroup is GenGroup) { bool collided = false; foreach (GenBasic basic in (objectOrGroup as GenGroup).Members) { if (CollideObject(basic as GenObject, callback)) collided = true; } return collided; } return false; }
/// <summary> /// Removes an object or group of objects from the follow targets list. /// </summary> /// <param name="objectOrGroup">The object or group of objects to remove from the follow targets list.</param> public void RemoveTarget(GenBasic objectOrGroup) { if (objectOrGroup is GenObject) { _followTargets.Remove(objectOrGroup as GenObject); } else if (objectOrGroup is GenGroup) { foreach (GenBasic basic in (objectOrGroup as GenGroup).Members) RemoveTarget(basic); } }
/// <summary> /// Adds an object or group of objects as targets that the camera will follow. /// Adding multiple targets will cause the camera to follow a point within the center of all targets. /// Adding the same object twice is useful for zooming in on the target. /// </summary> /// <param name="objectOrGroup">The object or group of objects to set as a target.</param> public void AddTarget(GenBasic objectOrGroup = null) { if (objectOrGroup is GenObject) _followTargets.Add(objectOrGroup as GenObject); else if (objectOrGroup is GenGroup) { foreach (GenBasic basic in (objectOrGroup as GenGroup).Members) AddTarget(basic); } }
/// <summary> /// Replaces an existing object in the members list with a new object. /// </summary> /// <param name="oldMember">The existing object to replace.</param> /// <param name="newMember">The new object that will replace the existing object.</param> /// <returns>The new object that replaced the existing object. Null if the object was not found in the members list.</returns> public GenBasic Replace(GenBasic oldMember, GenBasic newMember) { // Attempt to replace the existing object in the members list. int index = Members.IndexOf(oldMember); if (index == -1) return null; Members[index] = newMember; _updateMembers = true; return newMember; }
/// <summary> /// Removes a specified object from the members list. /// </summary> /// <param name="basic">The object to remove.</param> /// <returns>The object removed from the members list. Null if the object was not found in the members list.</returns> public GenBasic Remove(GenBasic basic) { // Attempt to remove the object from the members list. if (Members.Contains(basic)) { Members.Remove(basic); _updateMembers = true; // TODO: Remove from the quadtree. return basic; } return null; }
/// <summary> /// Adds an object or group of objects to the quadtree. /// Added objects will be inserted into the quadtree nodes during the next update, and added to the active objects list. /// </summary> /// <param name="objectOrGroup">The object or group of objects to add.</param> public void Add(GenBasic objectOrGroup) { if (objectOrGroup is GenObject) { // If the object has already been added to the quadtree, do not add the same object twice. if (!Objects.Contains(objectOrGroup as GenObject)) { Objects.Add(objectOrGroup as GenObject); _updateObjects = true; } } else if (objectOrGroup is GenGroup) { foreach (GenBasic basic in (objectOrGroup as GenGroup).Members) Add(basic); } }
/// <summary> /// Sets the x and y velocities of an object or group of objects to move towards a given point. /// </summary> /// <param name="objectOrGroup">The object or group of objects to move.</param> /// <param name="point">The point to move towards.</param> /// <param name="speed">The velocity to move the object at.</param> /// <param name="axis">A bit field of flags to determine the allowed movement axis of the object.</param> /// <param name="allowImmovable">A flag used to determine if an object set to immovable will be affected.</param> public static void MoveToPoint(GenBasic objectOrGroup, Vector2 point, float speed, Axis axis = Axis.Both, bool allowImmovable = false) { if (speed != 0) { if (objectOrGroup is GenObject) { if (allowImmovable || !(objectOrGroup as GenObject).Immovable) { // Get a normalized distance vector to calculate the horizontal and vertical speeds. Vector2 distanceNormal = GetDistanceNormal(objectOrGroup as GenObject, point, axis); (objectOrGroup as GenObject).Velocity = distanceNormal * speed; } } else if (objectOrGroup is GenGroup) { foreach (GenBasic basic in (objectOrGroup as GenGroup).Members) MoveToPoint(basic, point, speed, axis, allowImmovable); } } }