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.
Velocity.X
Effect of Drag
0
0
1
-.01
5
-.05
50
-.5
200
-2
Velocity.X
Effect of Drag
Net Velocity Change with XAcceleration = 50
0
0
.5
1
-.01
.49
5
-.05
.45
50
-.5
0
200
-2
-1.5
The Initialize method can be used to reset the PositionedObject variables back to their default state. Specifically, the Initialize method resets:
Position (absolute and relative)
Velocity (absolute and relative)
Acceleration (absolute and relative)
All "real" values
Rotation (absolute and relative)
Rotation Velocity (absolute and relative)
Attachments (detach from parents)
Attachment properties (ParentRotationChangesPosition and ParentRotationChangesRotation)
Instructions
Name
List membership (see below for more information)
The signature for Initialize is as follows:
Arguments:
bool clearListsBelongingTo - Whether the object should clear its ListsBelongingTo property. If this property is not specified, then the default value is true.
The FlatRedBall Engine depends on the two-way relationship that exists between IAttachables (an interface of the PositionedObject) and two-way lists that the IAttachable belongs to. Calling the no-argument version of Initialize, or passing true as the argument will result in the the PositionedObject breaking its two-way relationships with other objects, but it will not be removed from those lists. Let's look at a simple example where this can cause errors. The following code creates a PositionedObject, adds it to the SpriteManager for management, initializes, then attempts to remove it:
To avoid the bug shown above, you should either:
Initialize before adding to the SpriteManager
Pass false as the argument to Initialize
The RelativeRotationZ property controls the rotation of a PositionedObject relative to its parent. If an object does not have a parent (is not attached), RelativeRotationZ will not impact the final rotation of an object. If an object is attached, then RotationZ becomes read-only, and RelativeRotationZ controls the rotation of the object relative to its parent.
The acceleration property can be used to apply force to your objects in a physically realistic way. A force is anything which continually makes your object move faster and faster (or slower and slower if the force is in the opposite direction of the object's current Velocity). Examples of forces include:
Gravity
Car accelerator pedal
Car brake pedal
Space ship rockets
Magnetism (varies according to distance)
Acceleration can also be used to create smooth speed-up and slow-down movement for platformers and top down games.
If acceleration is constant (such as gravity in a platformer), it only needs to be assigned once. Acceleration should only be assigned in Custom Activity if it changes every frame, such as the gravity on an orbiting body.
The following piece of code uses a Circle, sets the acceleration, then applies velocity for jumping and resting. It assumes a screen which contains a Circle called CircleInstance.
Screen's CustomInitialize:
Screen's CustomActivity:
By itself, Acceleration has no impact on an object. Acceleration is applied to the Velocity of managed objects. This velocity is then used to modify the Position, which results in an object moving.
By default, objects (such as entities) are managed, so Acceleration is applied automatically.
GetPositionAfterTime - This function can be used to predict the position of objects given an object's starting position, velocity, and acceleration.
The ForceUpdateDependencies forces the calling PositionedObject and all of its parents to update absolute values according to relative values. This method can be called if an update is needed immediately (instead of waiting for the next Draw call). For more information on attachments, check the IAttachable page.
In many cases, if you have a parent object and a child object, you will not need to manually manage this attachment by calling ForceUpdateDependencies. However, calling ForceUpdateDependencies may be necessary in certain cases. As explained in this article, setting the relative value of a child object does not immediately change its absolute value. Similarly, changing the absolute value of a parent also does not immediately update the absolute value of a child. These updates occur right before drawing occurs. Therefore, if you have created a new attachment or modified the values involved in an attachment and would like to see these updates immediately impact the absolute value of all children, then you need to call ForceUpdateDependencies.
The following created two Text objects. Both are attached to a PositionedObject, but only one calls ForceUpdateDependencies. Then the DisplayText is set to show each Text's absolute Y value. Notice only the one which called ForceUpdateDependencies has a non-zero Y value. Add the following using statements:
Add the following to Initialize after initializing FlatRedBall:
The example above showed a situation where a child's relative values were read out immediately after an attachment was created. This example shows a similar situation - where the parent object is moved. You can comment and uncomment out the ForceUpdateDependencies call to see the difference. Add the following using statements:
Add the following to Initialize after initializing FlatRedBall:
The PositionedObject's Velocity and Acceleration values often dictate the position and movement of a PositionedObject, but sometimes these properties are also used in game code to control other objects. For example, in a physically realistic game if an airplane is flying at a certain speed and fires a bullet, the bullet's world velocity should equal the velocity relative to the barrel where it was fired plus the velocity of the airplane (at least initially if drag is being considered). In these situations it's important to use the accurate velocity or acceleration; but sometimes the value reported in the Velocity and Acceleration properties do not reflect the actual on-screen velocity of an object. For example, if we made a game where our character was standing on a boat, we may simply the character to the boat and work with relative positions. If the boat moves, the character moves, but we never explicitly set the character's Velocity property, nor has the engine touched it. If we want to base behavior off of the character's actual world velocity then we can use "real" values. To use real values, the KeepTrackOfReal property must be set to true. After this is done, any PositionedObject which is being managed will report its real velocity and acceleration through its RealVelocity and RealAcceleration properties.
The following code creates two and uses the RealVelocity property of the attached Sprite to apply a velocity to newly-created . In Initialize after initializing FlatRedBall:
Later define CreateNewSpriteEachFrame:
The LastPosition property is a protected property which marks the position of the PositionedObject last frame. This property is only updated if the PositionedObject's .
The PositionedObject class has a number of mirrored properties. These are properties which completely reflect similarly-named fields or other properties. The following graph shows mirrored property relationships:
The AttachTo method can be used to attach a child PositionedObject to a parent. Since the Parent property is read-only, the AttachTo method must be used to set up parent/child relationships. Most FlatRedBall objects (Text, Sprite, and all shapes) inherit from PositionedObject. Also, all Glue entities inherit from PositionedObject.
The following code assumes that GunInstance is a valid Glue component, and ShipInstance is also a valid Glue component:
The changeRelative property controls whether the relative values are changed on the caller (the child) when the method is called. Setting this value to true will result in the child being located in the same absolute position before and after the attachment. If false is passed, then the relative values on the child will be applied and the caller may move according to its relative values and its new parent's absolute values.
The Children property contains a list of PositionedObjects which are attached to this. Initially the list is empty, but it is automatically populated when one PositionedObject is attached to another using the method.
Add the following using statement:
Add the following to Initialize after initializing FlatRedBall:
RelativePosition (which mirrors the RelativeX, RelativeY, and RelativeZ properties) represents the position of a given PositionedObject relative to its parent. If a PositionedObject does not have a parent, then changing RelativePosition does not modify the PositionedObject. If a PositionedObject does have a parent, changing the RelativePositions will change the absolute Position of the PositionedObject, but not immediately. Dependencies must be updated before absolute positions are changed.
Relative position is used in almost every Glue project, but Glue simplifies the process. If an Entity contains an object which is a PositionedObject (such as a Sprite, Circle, or other Entity), then the object will be attached to its containing Entity. Changing the object's X, Y, or Z value will result in Glue ultimately changing the RelativePosition of the object.
The following code changes the relative position of a PositionedObject (such as an Entity, Sprite, or Circle). For RelativePosition to have an impact on an object's actual position, it must be attached to something. RelativePosition can be changed as follows:
The individual component properties can also be accesed as follows:
These two approaches are identical and result in the same outcome. The two approaches are provided for convenience.
Relative values must be used if you would like to move a PositionedObject which is attached to another PositionedObject. For example, if you are using Glue, you may have a Tank Entity with two Sprites:
Body
Turret
By default both the Body and the Turret Sprite will be attacked to the Tank. If you want to rotate the turret independently, then you must control the Turret. In this particular case you may want to control the RelativeRotationZ or RelativeRotationZVelocity value; however, the general idea is the same: You must use relative values to control an attached PositionedObject.
The following properties mirror each other
In most cases if you modify RelativePosition, you never have to worry about updating dependencies - dependencies are updated right before the engine performs the draw for a given frame - so everything will always appear up-to-date. However, if you are modifying RelativePosition values and you need to have those result in changes to absolute position, you will want to force the dependency update:
Position is a variable which controls a PositionedObject's absolute position. The PositionedObject is a Vector3, meaning PositionedObjects can be controlled on the X, Y, and Z axes. Position is a value which controls and returns the absolute position of a PositionedObject.
The Position variable is a "mirror" variable for the X, Y, and Z properties on a PositionedObject. In other words the following two lines are equivalent:
As the title implies, if a PositionedObject is attached to another PositionedObject, then the Position values (along with the X, Y, and Z values) are all read-only. The "relative" counterparts must be used. By default every PositionedObject (Sprite, Circle, AxisAlignedRectangle, Text) in an Entity is attached to that Entity. Therefore, the relative values must be used when assigning position in code.
RotationZ is the counterclockwise rotation value of the positioned object along the Z axis. For most games this value is used to rotate an object such as a car in a top-down game, or a spinning particle. RotationZ is represented in radians.
Although RotationZ is a property on all PositionedObjects, the Circle and AxisAlignedRectangle objects will not visually respond to rotation values.
The following code shows how to apply RotationZ to a Sprite in code. This assumes that SpriteInstance is a valid Sprite with a valid Texture. Typically this would be set in Glue.
Note: The previous code section uses the event. This event exists in the class, not in the PositionedObject class. For more information, see the .
For more information, see .
Property | Associated Field/Property |
X | Position.X |
Y | Position.Y |
Z | Position.Z |
XVelocity | Velocity.X |
YVelocity | Velocity.Z |
ZVelocity | Velocity.Z |
XAcceleration | Acceleration.X |
YAcceleration | Acceleration.Y |
ZAcceleration | Acceleration.Z |
RelativeX | RelativePosition.X |
RelativeY | RelativePosition.Y |
RelativeZ | RelativePosition.Z |
RelativeXVelocity | RelativeVelocity.X |
RelativeYVelocity | RelativeVelocity.Y |
RelativeZVelocity | RelativeVelocity.Z |
RelativeXAcceleration | RelativeAcceleration.X |
RelativeYAcceleration | RelativeAcceleration.Y |
RelativeZAcceleration | RelativeAcceleration.Z |
Float property | Vector3 Property |
instance.RelativeX | instance.RelativePosition.X |
instance.RelativeY | instance.RelativePosition.Y |
instance.RelativeZ | instance.RelativePosition.Z |
The ParentRotationChangesPosition property controls whether a child IAttachable's absolute Position is modified by its Parent's rotation. By default this value is true, meaning that when an IAttachable's parent rotates, its absolute position will be calculated using its relative position as well as the parent's RelativeRotationMatrix.
To understand when ParentRotationChangesPosition is a useful property, consider the following situation. A top-down tank game uses tanks which can rotate freely. Each tank should have a health bar shown above the tank. The health bar is attached to the tank for convenience; however when the tank rotates, the health bar moves around the tank. To keep the health bar above the tank regardless of the tank's orientation, the health bar's ParentRotationChangesPosition can be set to false. Also, setting the health bar's ParentRotationChangesRotation is also probably needed in this situation.
RelativeVelocity is the rate of change of an object's RelativePosition value. Since RelativePosition will only apply when an object has a parent, RelativeVelocity is typically only used for objects which are attached to other objects (such as a Sprite in an Entity).
The ParentRotationChangesRotation property tells an object whether its rotation should be relative to its parent rotation. This is true by default but it can be set to false.
This code could be used to tell a health bar to not rotate when whatever it is attached to rotates:
Attachments create a relationship in which the child is both positioned and rotated relative to the parent. In some cases it is useful to suppress some of this behavior. The ParentRotationChangesRotation property controls whether the rotation of a child is modified by the parents' rotation. In the following example the ship Sprite (represented by the red ball) rotates and moves according to input from the keyboard. The Camera is attached to the Sprite but does not rotate with it. Declare the ship at class scope:
In Initialize:
In Update:
This method can be used to "update" relative values (rotation and position) of a child PositionedObject after modifying its absolute rotation or position values.
Although child absolute values are considered read-only (see this page), this does not necessarily mean that the actual variable itself is read-only. Rather, before drawing occurs, the absolute values of all children are overwritten by their attachment logic. However, prior to drawing occurring, absolute values can be set and reset and used *within that same frame*. We can take advantage of this behavior by modifying the absolute values, then using those values to update the child's relative values so that the overwriting that occurs later will not end up changing the absolute values. In other words, we can use the SetRelativeFromAbsolute to reposition a child object in absolute space, then make those changes "stick".
This example creates two Sprites and attaches one to the other. The child will then be repositioned in absolute coordinates, then SetRelativeFromAbsolute will be called to modify its relative values so that the child remains in the position that it was placed: Add the following using statements:
Add the following to Initialize after initializing FlatRedBall:
This code essentially makes the absolute values temporarily writable. The end result is the same as:
Detaching a child
Repositioning the child
Reattaching the child and passing true as the second (changeRelative) value
The TimedActivity method is a method used by PositionedObjects (and objects which inherit from PositionedObject such as ) to perform common every-frame logic. The TimedActivity method performs the following:
Adjusts position by velocity and acceleration
Adjusts velocity by acceleration
Adjusts rotation by rotation velocity
Adjusts velocity by drag (linear representation)
Calls .
Adjusts RealVelocity and RealAcceleration if is set to true.
TimedActivity is automatically called for you on any PositionedObject that is part of a manager, so you will normally not need to call this method manually.
The TimedActivity signature is as follows:
The arguments are used as follows:
secondDifference - this is the amount of time that has passed since last frame. Internally FlatRedBall uses
secondDifferenceSquaredDividedByTwo - this is a value used to apply acceleration. Internally FlatRedBall uses:
secondsPassedLastFrame - this is the amount of time that passed between two frames ago and last frame. This is used to calculate . Internally FlatRedBall uses
TimedActivity is called automatically by the engine so you will not need to call it in most cases. However, there are some cases where you may need to:
If you have a PositionedObject which has either been removed from the engine or made manually updated, you may need to call this method manually if you would logic mentioned above to be applied (like Velocity).
If you would like to simulate more time passing in a single frame. The first argument indicates the amount of time that you would like applied in TimedActivity.
If you are performing unit tests and need to perform logic that would normally be performed by the engine on PositionedObjects.
TimedActivity may need to be manually called if you would like to simulate more time being passed in your frame. For example, you may be working on a game and you want to "fast-forward" time by 5 seconds to see where an object will end up. The TimedActivity method can accomplish this. The following code will move a PositionedObject forward in time by 5 seconds:
Call TimedActivity in a loop rather than all at once, as shown below.
Of course calling this method multiple times (150 in the example above) takes much more processing time than simply calling the method once with a larger secondDifference.
If you have a class which is inheriting from PositionedObject, then you may want to override the TimedActivity method. Doing this will allow you to write custom code which will be run automatically every frame if your object is added to the SpriteManager. In a Glue environment, code added to TimedActivity will be called prior to the custom code for a given frame.
Since this code is called by the SpriteManager during the FlatRedBall.Update call, your code may execute before or after TimedActivity for other engine-managed objects. In other words, if you require that other FlatRedBall types have finished applying properties such as velocity and acceleration for a given frame before your code is applied, you should not use TimedActivity for custom logic.
The following code is an example of what TimedActivity might look like in a class that inherits from PositionedObject:
The Z property controls the absolute Z position of an object. On 3D cameras (Orthogonal=false) , the smaller the Z is, the further away from the camera an object will appear. For information on setting Z in the FlatRedBall Editor, see .
The following code assumes an empty Screen, and the code is written in CustomInitialize.
The Z value controls the distance of an object from the Camera. When using a 2D Camera (Orthogonal=true), changing the Z will not make objects get bigger or smaller as they move closer to/away from the Camera. Despite that, the Z value still impacts a few things:
Objects with a Z value smaller than the Camera's near clip plane (by default 39) will not be drawn
Objects with a Z value larger than the Camera's far clip plane (by default -960) will not be drawn
Objects will sort with each other according to their Z values (excluding shapes like Circle and AxisAlignedRectangle)
SpriteManager.Camera.Z = 40
New PositionedObject.Z = 0
Notice that although the Camera is attached to the ship Sprite, it does not rotate. Try setting the Camera's ParentRotationChangesRotation property to true and observe the behavior.
The example shown above will result in perfectly accurate positioning if is 0. The reason for this is because is a linear approximation. Normally this linear approximation is sufficiently accurate; however, large values for secondDifference can result in inaccurate and even confusing behavior. It is even possible, given a large enough secondDifference, for to reverse the velocity of an object.
If you are using and want to manually call TimedActivity, you should either:
Manually apply (see the page for information on how to do this)
Calling TimedActivity in a loop simulates the way that FlatRedBall calls TimedActivity once per frame. This can make behave properly. The following code shows how to call TimedActivity, simulating a game that runs at 30 frames per second:
For information about how Z affects sorting, see the documents.
UpdateDependencies is a method which updates absolute values (specifically position and rotation) according to the caller's relative values and Parent absolute values. The UpdateDependencies method is a method which is automatically called by the Engine on any PositionedObject or PositionedObject-inheriting object which is part of a FlatRedBall manager. In most cases you will never need to worry about dependencies being updated - this will be called automatically.
UpdateDependencies is responsible for positioning an object according to its parents' position and rotation. Since attached objects must move together, then absolute positions must be set after all custom code is executed, but before the draw is called. Therefore, FlatRedBall managers call UpdateDepencies on contained PositionedObjects in the FlatRedBallServices.Draw method.
ForceUpdateDependenciesDeep is a method which calls ForceUpdateDisependencies on all contained children. This method recursively calls itself on all contained Children, so it will update all children, grandchildren, etc. This method is not typically called in games and is only needed in rare cases.
Just like FlatRedBall.PositionedObject.ForceUpdateDependencies this method does not check if dependencies have already been updated already. Therefore this method can result in unnecessary calls to ForceUpdateDependencies.
Velocity is a value that controls how fast an object moves. Setting Velocity on an unattached, managed PositionedObject (including Entities in Glue) will result in that object moving automatically. Velocity is measured in units per second. In other words, setting your object's Velocity.X value to 100 will result in its X value increasing by 100 unit per second - of course, the increase will happen smoothly as opposed to jumping by one unit every second.
Velocity is a Vector3 meaning it has three components:
Velocity.X
Velocity.Y
Velocity.Z
PositionedObjects also provide individual float values for each of the velocity components:
XVelocity
YVelocity
ZVelocity
Setting the values directly on the float properties or on the Velocity values does the same thing, so which you use is a matter of preference. You can also set and get each component individually, or work with the entire vector in mathematical operations. To set the X velocity you can access the X component as follows:
You can also get individual values. For example:
All entities can have their Velocity value assigned. This example shows how to create a bullet and assign its velocity so that it moves to the right whenever the space bar is pressed. This code uses an entity named Bullet.
The code could also be modified to shoot the bullets at angles. For example, the following code shows how to shoot 5 bullets in a spread angle:
If the Velocity of an object is set, it will remain until changed. For example, consider the following code:
If you add this code (assuming you have a myCharacter object which is a PositionedObject), you will notice that your character keeps moving even after you release the Right arrow key. The reason is because the Velocity value will not change back to 0 every frame automatically. You will have to change it back yourself, as follows:
You can make a PositionedObject move from one object to another by using the Velocity and Position code. For example, you may have a bullet which is being fired toward the player. For this example we will use two PositionedObjects: Bullet and Player.
If an object has a non-null Parent, then you must use RelativeVelocity instead of Velocity.
The PositionedObject is an object which contains properties and functionality for position, rotation, attachment, velocity, acceleration, and instructions. It serves as the base object for common FlatRedBall classes such as the Camera, Sprite, and Text objects. The PositionedObject is also the base class of Entities.
Absolute position can be directly controlled through the X, Y, and Z properties as well as the exposed Position field. The following code creates three Sprites with various positions. Note that the default position of a PositionedObject is (0,0,0). Also, note that in the screenshot below, the Z value impacts the size of sprite3 , implying that the game is using a 3D Camera.
Since the Position and X/Y/Z properties are all part of the PositionedObject class, any class that inherits from the PositionedObject class (list can be viewed above in the table) has these properties. In other words, the code above uses Sprites, but it could have used any PositionedObject-inheriting object to achieve the same results.
The default view in FlatRedBall is down the Z axis using a perspective view. Therefore modifying the Z value of PositionedObjects can result in apparent changes in size. FlatRedBall MDX uses a left-handed coordinate system while FlatRedBall XNA uses a right-handed coordinate system. This means that the Z axes point the opposite direction on each version, so keep this in mind if switching from one to the other. By default, positive Z moves objects further away from the camera in FlatRedBall MDX. Positive Z moves objects closer to the camera in FlatRedBall XNA.
Velocity represents the speed at which an object is moving. Mathematically, it represents the change in position measured in units per second. While the PositionedObject itself does not apply velocity automatically, any PositionedObject-inheriting instance which is created through or added to FlatRedBall managers will have its velocity automatically applied to its position. This is the case for Sprites, Cameras, and Text objects. Similarly, Acceleration modifies velocity on all objects which belong to FlatRedBall managers. It represents the rate of change of velocity in units per second. Acceleration is often used to simulate forces applied to an object such as gravity or a rocket's thrust. The following code creates two Polygons. One moves to the left while the other begins moving up and to the right, but falls downward as if affected by gravity. Although the section covering position used Sprites, this section uses Polygons to show that the same code works on many FlatRedBall types.
For more information on Velocity, see the Velocity page. For more information on Acceleration, see the Acceleration page.
See the IRotatable wiki entry.
PositionedObjects implement the IAttachable interface. For more information on attachments and the IAttachable interface, see the IAttachable entry.
PositionedObjects implement the IInstructable interface allowing them to store and execute instructions. Most PositionedObjects such as Sprites and Text objects have their instructions executed automatically by their corresponding managers. For more information, see the IInstructable page.
Most PositionedObjects like Text objects and Sprites are managed by managers as listed above. However, it is common practice to create objects which inherit from PositionedObjects. When one of these objects is instantiated it is not automatically managed, therefore fields like Velocity and Acceleration are not applied. In other words, the following code will NOT result in an object that moves across the screen:
The SpriteManager can also perform common management on PositionedObjects. Therefore, adding the following line will result in the object being managed by the SpriteManager and exhibiting all expected behavior:
To remove an object that has been added this way from management, call:
One of the most useful yet least understood features of PositionedObjects is their two-way relationship with . The RemoveSelfFromListsBelongingTo method does essentially what the name says - it removes the calling PositionedObject from any that it belongs to. This can include:
Internal lists in the engine, like the AutomaticallyUpdatedSprites list in the .
Any lists that you might create, such as lists of Entities in a GameScreen.
Parent lists. Keep in mind that calling this method will NOT set the calling object's Parent property to null. This usually doesn't matter because the most common practice is to throw this object away (lose its reference) after the method is called. But just in case, remember that this will create a "lost child" relationship.
The answer is "almost never". RemoveSelfFromListsBelongingTo is ultimately called very frequently, but it is done so through one of the following calls:
Entities which are Destroyed automatically call their own RemoveSelfFromListsBelongingTo
Objects inside Entities and Screens have their RemoveSelfFromListsBelongingTo when the Entity or Screen is destroyed. Note that RemoveSelfFromListsBelongingTo is not directly called, but rather the objects inside are removed from their respective managers, which in turn calls RemoveSelfFromListsBelongingTo.
If you have manually created an object that is not an Entity, such as a Sprite for particles, then you would manually call the Remove method from the SpriteManager. Therefore, if you call the manager's remove method, also calling RemoveSelfFromListsBelongingTo is redundant. The only time that this method is really needed is if you have a PositionedObject-inheriting object which is not being managed by a manager. In that case you may want to call RemoveSelfFromListsBelongingTo to clear it out of any lists that it may belong to; however, this case is extremely rare.
The provides a method to create particle . Particle behave slightly differently from other managed objects. When Remove is called on them they are not removed from all lists. The stores a list of particle internally which it cycles to reduce memory allocation and garbage. If RemoveSelfFromListsBelongingTo is called on a particle , then that will be removed from all lists including the internal particle list. This can cause difficult to track bugs because this reduces the size of the particle list which can ultimately cause crash bugs if you run out of particles. In short, just as mentioned above, use the appropriate manager's remove method whenever possible instead of calling RemoveSelfFromListsBelongingTo.
PositionedObject-Inheriting Class
Associated Manager
FlatRedBall.PositionedObject