Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Although AxisAlignedRectangles inherit from the PositionedObject class, which inherits from the IRotatable interface, AxisAlignedRectangles cannot be visibly rotated. This article discusses how rotation values are applied to AxisAlignedRectangles.
As far as the visible representation and collision behavior of an AxisAlignedRectangle, rotation will have no impact on an AxisAlignedRectangle. For more information, see this section.
All positions in FlatRedBall are defined by a combination of X, Y, and Z values. These values, when measuring absolute space, represent the distance from the origin along each axis by the same name as the component (X axis, Y axis, and Z axis). In FlatRedBall, when using an unrotated Camera, positive X points to the right and positive Y points up. The "axis aligned" part of AxisAlignedRectangles simply means that the edges of the rectangle are parallel (line up with) the X and Y axes. This is always true for AxisAlignedRectangles - even if they are rotated. However, that doesn't mean that the underling rotation values are always 0. In other words, if another PositionedObject is attached to an AxisAlignedRectangle, and the (parent) AxisAlignedRectangle is rotated, then the child PositionedObject will react to the rotation.
The KeepThisInsideOf method repositions the calling AxisAlignedRectangle (or its TopParent if it is attached to another PositionedObject) so that it is not outside of the argument AxisAlignedRectangle. This method will do a one-time re-position of the calling instance, so it must be called every frame if the moving AxisAlignedRectangle.
This method can only be used to keep AxisAlignedRectangles inside of other AxisAlignedRectangles - other shapes are not supported.
The LastMoveCollisionReposition is a property that exists for all Shapes. If using CollisionRelationships, this property is set on any type of collision relationship that moves an object. This includes:
Move Collision
Bounce Collision
Platformer Solid Collision
Platformer Cloud Collision
If using manual collision calls, this property is set whenever a shape calls CollideAgainstBounce or CollideAgainstMove and the method test results in an actual collision. The LastMoveCollisionReposition property can then be tested to obtain information about collision.
When two AxisAlignedRectangles collide the collision side can be determined rather easily. The following code determines the side that two rectangles collided on: Add the following using statements:
Assuming rectangle1 and rectangle2 are valid AxisAlignedRectangles:
The following code can be used in a platformer to detect if a character is on the ground.
This code uses the CollideAgainstBounce method. For more information on this method, see this page. Let's look at the individual pieces of code above to see what is happening. The first line is:
This line of code tests to see if the character's collision (which we assume is a circle) collides against the "LevelCollision" which can be any shape or an entire ShapeCollection. This method does the following:
It adjusts the velocity of the calling object (the character in this case) so that it is no longer falling. This prevents gravity accumulation errors.
It adjusts the calling shape's (the character.Collision in this case) LastMoveCollisionReposition.
It returns whether a collision has occurred.
So, as we can see, this first if-statement does *a lot*. Well, the most important thing initially is knowing *if* a collision has occurred. If it does, then we proceed to the body of the if-statement to find out if the player is actually on the ground. The next line of code is:
In this code we assume that character is an Entity that you've created that has an IsOnGround property. IsOnGround is a property that you must create in your Entity - either in custom code or as a new variable in Glue. Of course, you can store this information however you'd like; we've just presented the most common way if using Entities.
The LastMoveCollisionReposition property gives you the reposition of the last shape that a given shape has collided against. This information may not be very useful if you are colliding against a collection of shapes. In this case, you may want to manually keep track of your collision reposition:
CollideAgainstMoveSoft performs the following logic:
It checks to see if two AxisAlignedRectangles are overlapping
If so, it adjusts the velocity of the caller and the argument AxisAlignedRectangles according to how much the two shapes overlap each other and according to the separation velocity.
Since this function adjusts the velocity of the caller and the argument, then your code must not explicitly set Velocity on either of the two objects or else your code will overwrite the Velocity values set by this function.
CollideAgainstMoveSoft adjusts the velocities of the two involved objects according to the strength of the separation (the last parameter in the function) as well as how far the two overlap.
A physical example of this would be to have magnets with the same charge (so they repel) on ice. If they are sufficiently far away then the repulsion is essentially 0, but as they get closer the amount increases. The math behind how this works is not physically identical to magnetic attraction and repulsion, but the concepts are similar.
The following code assumes 2 AxisAlignedRectangles are created:
AxisAlignedRectangleInstance1
AxisAlignedRectangleInstance2
It assumes you are using Glue so the code has been written in CustomActivity in a Screen, but it could be used outside of Glue as well.
The RepositionDirections member controls which direction colliding objects will be repositioned. Specifically,RepositionDirections is relevant when calling and . RepositionDirections is also used by CollisionRelationships when using platformer collision. By default standalone AxisAlignedRectangles have all directions active, meaning the rectangle will reposition objects in all directions (up, down, left, right). AxisAlignedRectangles which are part of TileShapeCollections automatically have their RepositionDirections adjusted to prevent snagging.
The default value is All, which means that any objects colliding with the AxisAlignedRectangle can be moved in any of the four directions (Up, Down, Left, and Right) as shown in the following diagram:
RepositionDirections can be changed to any of the four cardinal directions, as shown in the following code:
The code above results in all objects being moved upward:
RepositionDirections can be combined with the | (or) operator, as shown in the following code:
This example shows how RepositionDirections modifies the CollideAgainstMove method. It uses two rectangles:
RedRectangle
BlueRectangle
These are created in Glue so the screen starts as shown in the following image:
RepositionDirections value can be adjusted in code or in Glue. Typically this property is adjusted in code, so this example uses the following code:
Notice that when the first rectangle is moved (with the keyboard), it will only be repositioned to the left.
If two AxisAlignedRectangle instances are colliding against each other, then the RepositionDirection of both rectangles are considered. For example, consider the following situation:
For this example the red rectangle on the left will be called RedRectangle and the blue rectangle on the right will be called BlueRectangle. We'll assume that the BlueRectangle's RepositionDirection value is set to RepositionDirection.All. We'll also use the following collision code between the two:
By default, the red rectangle will be pushed to the left so it no longer overlaps the blue rectangle. Of course, this depends on the following two conditions:
That BlueRectangle has a RepositionDirection including RepositionDirection.Left
That RedRectangle has a RepositionDirection including RepositionDirection.Right
For the default separation to occur, the blue must be able to reposition to its left and the red must be able to reposition to its right. In other words, both rectangles must have opposing RepositionDirection values for a reposition to occur. If either is missing, then other directions will be checked. For example, consider the following code:
This code would result in BlueRectangle only being able to reposition to the right when a collision occurred, resulting in RedRectangle being moved all the way to the right side of BlueRectangle.
Setting a RepositionDirection of Up can help with cloud collisions. Assuming MyPlatform is a valid AxisAlignedRectangle:
RepositionDirections defines which direction objects will move in when either CollideAgainstMove or CollideAgainstBounce are called. If a value of None is set, then CollideAgainstMove and CollideAgainstBounce will not change the position or velocity of either of the colliding objects.
The use of RepositionDirections is critical for proper collision when using TileShapeCollections. For simple situations, a developer does not need to understand the RepositionDirections behavior that is happening when creating TileShapeCollections. This section discusses the behavior of RepositionDirections in TileShapeCollections. To begin, consider a TileShapeCollection which contains a single AxisAlignedRectangle. In this case, the rectangle will have all four RepositionDirections as shown by red arrows.
If a second rectangle is added to the first, then both of them remove their inward reposition directions. This is important to prevent collision snagging - the stopping of a moving object when moving across a smooth surface created by multiple rectangles.
As more rectangles are added, the TileShapeCollection adjusts the RepositionDirections of each to prevent snagging. Usually this happens automatically and no custom code is needed.
The RepositionDirections property on AxisAlignedRectangles in a TileShapeCollection can tell you if a rectangle is a corner or part of a flat surface. As shown above, corners have at least two adjacent reposition directions. Since RepositionDirections is a bitfield, then the logical or can be used to test if an AxisAlignedRectangle is a corner, as shown in the following code.
The AxisAlignedRectangle object supports changing its Color property by assigning a value.
The following example requires that LeftRectangle and RightRectangle are valid Rectangles. For this example the rectangles were created in Glue. The following code can be used to modify the colors of the Rectangles:
GetRandomPositionInThis returns a representing a random position in the calling AxisAlignedRectangle. This value can be used for any logic, such as randomly positioning an object within an AxisAlignedRectangle.
The following example can be used to create 50 inside an AxisAlignedRectangle.
The code assumes that the rectangle is called AxisAlignedRectangleInstance and that you have a CircleList to store all the created Circles:
This line of code tells us whether the collision that occurred should be treated as a ground collision. The reason this works is because "move" and "bounce" collision methods move the calling objects so they no longer overlap. For more information on how this works, check this page. If the player is standing on the ground, then gravity will move the player "into the ground", but the CollideAgainstBounce method will separate the two - repositioning the Circle. If the player is on the ground, then this position is vertical; in other words, it has a Y value of greater than 0. By contrast, if the character is jumping and hits the ceiling with his head, then he will be repositioned downward; the Y value will have a value less than 0. Finally we assign this value to our character's IsOnGround property:
The Left, Right, Top, and Bottom properties on AxisAlignedRectangle return the absolute position of the respective side.
The following code shows how to get the four values (Left, Right, Top, and Bottom):
Setting Left, Right, Top, and Bottom results in the X or Y values of the AxisAlignedRectangle changing. These values will not change the Width or Height of the AxisAlignedRectangle. To change dimensions use the Width and Height.
The following code makes an AxisAlignedRectangle named RectangleInstance position its bottom-left corner at the origin (0,0):
The AxisAlignedRectangle is a PositionedObject which is used for unrotated bounding box collision. This is preferred over Polygon collision if Sprites are not rotated due to speed and memory usage considerations. AxisAlignedRectangles share many similarities with the other shape classes (Circle, Line, and Polygon). For general information about shapes, see the ShapeManager wiki entry. For information on using AxisAlignedRectangles in Glue, see this page. AxisAlignedRectangles do not support being filled-in. They can only render as an outline. To render a solid rectangle, look at using Sprites with the Color ColorOperation
The "AxisAligned" part of AxisAlignedRectangle indicates that the sides of the rectangle are "axis aligned". In other words, the top, bottom, left, and right are all parallel to either the X or Y axes. AxisAlignedRectangles are always axis aligned for performance reasons. Therefore, if you rotate an AxisAlignedRectangle (set its RotationZ), this will have no impact on the collision behavior or its visible representation. If your game requires rotation, you should use the Polygon class. Of course, performance will suffer slightly if collision performance is a consideration for your game. For more information on axis alignment and a discussion of axis aligned object rotation and children positions, see this page.
The AxisAlignedRectangle class inherits from PositionedObject. This means that all properties which are available to PositionedObjects (excluding rotation) are available to AxisAlignedRectangles. For more information, see the PositionedObject page.
AxisAlignedRectangles are created through the ShapeManager. The following code creates an AxisAlignedRectangle through the ShapeManager and resizes it: Add the following using statement
Create the instance:
Solid or moving collision can be performed with AxisAlignedRectangles as well as Polygons and Circles. The following code creates three AxisAlignedRectangles - one controlled by the player, one which can be pushed, and one which is is immovable. Add the following using statements:
Add the following at class scope:
Add the following in Initialize after Initializing FlatRedBall:
Add the following in Update:
For information on determining which side an object has collided on, see this page on LastMoveCollisionReposition.
Did this article leave any questions unanswered? Post any question in our forums for a rapid response.