Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The Clone method is a generic method which can be used to create new instances of objects which inherit from PositionedObjects. Since it is generic, the Clone method can be used on types that inherit from the PositionedObject class, like Entities.
The following creates a custom PositionedObject class called WeightedObject. It manually creates one WeightedObject, then creates a clone of it. The output Text shows that the WeightedObject has been properly cloned. Add the following using statement:
Define your WeightedObject class:
Add the following to Initialize after initializing FlatRedBall
The Clone method clones your PositionedObject, but there are a few details to keep in mind. First, the Clone method calls the MemberwiseClone method, which is a method that exists for all objects in .NET. This method performs a "shallow" copy. What that means is that if your object has a member that is a reference (for example, to another Sprite), then the newly-cloned object will share the exact same reference. It will not create a new Sprite instance for it to reference as a member. All value members (such as float or int) will be copied and each object will have its own value data. There are a few exceptions. The PositionedObject will create new instances for:
ListsBelongingTo
Children
Instructions
The new clone will have new lists for the properties mentioned above, and they will be empty.
If you are creating an object which includes other referenced objects (such as Sprites, Texts, or any collision Shapes), then you will need to manually clone the objects and re-attach these objects. We recommend encapsulating this logic in a Clone method as follow:
FlatRedBall objects like Sprites and collision Shapes provide Clone methods which can be used to simplify cloning. If your object contains other reference objects then you will either:
Need to add a Clone method to those objects if you have written them yourself.
Manually instantiate a new object for the new PositionedObject instance in the Clone method and set any variables that should be set.
The Drag property is a linear approximation of deceleration which is tied to the PositionedObject's absolute velocity. Internally drag is applied as follows (you do not need to write this code, it's just an explanation):
Drag is independently applied to each component of velocity.
Drag is typically used to slow objects down over time. A non-zero Drag value is often used on objects which are also affected by acceleration. Examples include Drag slowing down a boat that is moving through water and Drag slowing down an object so that it reaches terminal velocity.
Drag is a linear approximation of deceleration which is tied to absolute velocity. It can be used to create terminal velocities (maximum velocities) when objects are moved by acceleration. The following code shows the effect of Drag on three Sprites.
For objects which are controlled by the player such as a space ship or car, Drag is usually only used when the object is controlled by setting its acceleration value. If an object's velocity value is set every frame based off of input, then Drag will only slightly reduce the velocity for that frame. Next frame input will overwrite the velocity - effectively making Drag a dampening value.
When an object has a non-zero Drag value and is controlled through acceleration it will always reach a maximum velocity or "terminal velocity" - a term which defines the fastest that an object can fall through an atmosphere. To understand this, let's consider the amount by which the XVelocity of a PositionedObject is reduced when Drag is non-zero:
Equilibrium is reached when acceleration and drag apply equal forces. Keep in mind that the velocity over time when using drag and acceleration is an asymptote. Mathematically this means the actual terminal velocity is never reached. However, over time the velocity will get closer and closer to terminal velocity. In practical applications, a terminal velocity may be reached due to floating point inaccuracy, but it may not be exactly the same as the terminal velocity calculated mathematically. Mathematically, equilibrium can be calculated as follows:
This formula is easiest to calculate when Drag is 1. If Drag is 1, that means that terminal velocity will be reached when Velocity reaches Acceleration. If Drag is 2, then terminal velocity will be reached when Velocity is half of acceleration. This makes sense because higher Drag means that top speed will be reduced.
Drag applies a continual acceleration proportional (and in the opposite direction of) the current Velocity. Over time, an object with drag slows down to 0 (or near 0) velocity. The distance that an object travels given a starting Velocity and Drag can be calculated with the following formula:
For this example we will use the following values:
These values will make our computations simple. Velocity.X will be variable. Now, consider the effect of Drag with different Velocity.X values:
The "Effect of Drag" column displays the amount by which velocity will decrease each frame. Consider an object which has an XAcceleration of 50. This will add 50 * TimeManager.SecondDifference to the velocity each frame, or in our case where TimeManager.SecondDifference is fixed at .01, XAcceleration will increase velocity by .5 each frame. Consider the net change in Velocity.X at the different Velocity.X values:
Notice that although our XAcceleration is always .5, the increase of velocity is less and less as the velocity itself is greater when Drag is non-zero. In fact, once Velocity.X reaches 50 the object's velocity reaches an equilibrium - the Drag is reducing .5 from the velocity every frame while XAcceleration is adding .5 every frame. As a note, this technically not exact as FlatRedBall's order of operations results in an equilibrium slightly different. When Velocity.X reaches a value greater than 50 the result of Drag actually reduces the velocity. Regardless of the velocity, if XAcceleration is 50 and Drag is 1, Velocity.X will move towards an equilibrium value of 50.
Managed PositionedObjects such as Sprites automatically have their Drag applied every frame.