Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The AddCollisionFrom method can be used to add AxisAlignedRectangle instances to the TileShapeCollection from a tile map (MapDrawableBatch).
AddCollisionFrom provides lots of flexibility for adding collision. The simplest form is to add collision from a tile by the tile name. The following code adds collision for all tiles named "CollisionTile":
Using names is simple, but can also be restrictive. For example, we can check a tile to see if any of its properties are named "IsSpikes":
Note that if adding collision based on tile property names alone (not the value), see the AddCollisionFromTilesWithProperty method: http://flatredball.com/documentation/tools/tiled-plugin/glue-gluevault-component-pages-tile-graphics-plugin-tileshapecollection/addcollisionfromtileswithproperty/
The CollideAgainst function returns a bool value indicating whether the calling TileShapeCollection collides with the argument. CollideAgainst can be used to test collisions against:
ICollidable (usually Glue entities)
AxisAlignedRectangle
Circle
Line
Polygon
Note that in most cases CollideAgainst does not need to be called because collision relationships can be created between TileShapeCollections and Glue ICollidable entities.
The following code shows how to test if an entity is colliding with a TileShapeCollection whenever the space bar is pressed. The code assumes that the entity implements ICollidable.
GetRectangleAtPosition returns the AxisAlignedRectangle instance at the argument position. This method checks if the position is inside the bounds of the rectangle, so an exact position is not needed. This method also takes advantage of the axis-based partitioning in the TileShapeCollection so this method does not need to check every rectangle. In other words, this method is very fast, even for TileShapeCollections with a lot of rectangles.
The following code can be used to obtain a rectangle at the Cursor's position:
AddCollisionFromTilesWithProperty adds rectangles to the calling TileShapeCollection for all tiles which have the argument custom property. This is the most common way to create collisions from a TMX file in code.
Additional Information For more control over which tiles create collisions (for example checking a property and its value), see the AddCollisionFrom method: http://flatredball.com/documentation/tools/tiled-plugin/glue-gluevault-component-pages-tile-graphics-plugin-tileshapecollection/addcollisionfrom/
AddMergedCollisionFromLayer adds rectangles to the calling TileShapeCollection for all layers in the argument layer which have properties matching the predicate. Rather than creating individual rectangles for each tile, the created rectangles will be merged - all adjacent rectangles in either a row or column will be combined into one to reduce memory consumption and to speed up collision calls. AddMergedCollisionFromLayer is similar to AddMergedCollisionFromTilesWithProperty, but it provides more control over how collisions are created. Note that AddMergedCollisionFromTilesWithProperty is simpler and may provide enough flexibility for many games.
The following shows how to add collisions for any tile which has a property IsSpike with a value of true.
Note that in this case the Name is the name of the property and the Value is the value of the property. The code above could be modified to check any property or desired value.
RemoveFromManagers removes all contained tiles from any managers and other PositionedObjectLists that hold the tiles. Specifically calling RemoveFromManagers will:
Remove all shapes from the ShapeManager for every-frame management
Remove all shapes from the ShapeManager for rendering
Clear the TileShapeCollection
Remove shapes in the TileShapeCollection from any other PositionedObjectList containing these shapes, including parent/child relationships
The following code will remove the calling TileShapeCollection from all managers and will clear it
AddCollisionAtWorld creates attempts to create a new rectangle at the location specified. If the TileShapeCollection already has an AxisAlignedRectangle at the argument location, then it will not create another. If there is no rectangle at the argument location, then a new one will be created. Newly-created rectangles will automatically be sized and positioned according to the rectangle size and seed of the TileShapeCollection.
AddCollisionAtWorld adds a collision rectangle at the argument X and Y values. Rather than using the exact X and Y values, the rectangle will be placed at the center of the tile, extending to the edges using the TileShapeCollection.GridSize value. For example, consider a TileShapeCollection with a GridSize of 16. Calling the AddCollisionAtWorld method with any value between 0 and 16 will result in a rectangle being placed at (8,8). Furthermore, calling AddCollisionAtWorld inserts a rectangle in the proper index to keep the shape collection ordered along its SortAxis . Therefore, AddCollisionAtWorld can be called in any order and all rectangles will still be sorted and collision methods will use partitioning.
The following code shows how to create AxisAlignedRectangles with the cursor. The following code assumes that SolidCollision is a valid TileShapeCollection and that it is visible.
TileShapeCollection is a class created specifically for tile based collision. Its features include:
Very fast collision - it has partitioning built-in.
Eliminates snagging - Internally the TileShapeCollection modifies contained AxisAlignedRectangles' RepositionDirections to eliminate snagging.
Full support in the FlatRedBall Editor for initial definition and collision relationships.
Simplified syntax - Adding collisions to TileShapeCollection is very easy to do in code, whether doing so manually in code or from a loaded TMX file.
If you have created your project using the FlatRedBall Editor Wizard (either platformer or top-down), then your game already has TileShapeCollections. For example, the GameScreen should have a SolidCollision TileShapeCollection.
To add a TileShapeCollection:
Expand your GameScreen or Screen which should contain the TileShapeCollection. Typically collision is added to GameScreen.
Right-click on Objects and select Add Object
Verify FlatRedBall or Custom Type is selected
Select the TileShapeCollection option
Click OK
Now that you have created a TileShapeCollection, you can fill it using a variety of methods as shown before.
The most common usage of TileShapeCollections is to add collision from a particular tile Type. Usually this is done through a Map object in the GameScreen. If your project has been set up using the wizard, then you should have a Map object in GameScreen. If so, you can:
Select the TileShapeCollection that you would like to fill from the map
Check the TileShapeCollection properties
Select the From Type option
Use the dropdown to select the type. These types will match the types defined in your map's Tileset (tsx) file
When creating a game, you may want to add some placeholder collisions to test your logic and collision relationships. To create placeholder collisions:
Select your TileShapeCollection in Glue
Click the TileShapeCollection Properties
Select the Fill Completely option
Set the Tiles Wide and Tiles High to define the size of collision block you want
Click the Variables tab
Check the Visible checkbox
Now the TileShapeCollection will appear in your game and can be used for testing.
Open Tiled
Click the wrench icon to edit the tileset
Select one (or more) tiles which should have collision
Add a Custom Property called SolidCollision. The type of the variable doesn't matter.
Save your tileset (tsx)
Place some tiles in your map
Save your TMX
Now in Glue we can associate the SolidCollision with the TileShapeCollection:
Select the TileShapeCollection in your GameScreen
Click the TileShapeCollection Properties tab
Select the From Property option
Use the dropdown to select your TMX file
Enter the property SolidCollision
Now if you run your game you will see collision wherever you placed your tiles.
Collision can be added to a TileShapeCollection from a loaded TMX file (which loads into a LayeredTileMap). The following code shows how to add collision from all tiles with the custom property HasCollision.
The following example shows how to create an AxisAlignedRectangle that moves around with the keyboard and collides against a TileShapeCollection. This project assumes a Glue project with:
A Screen called GameScreen
An AxisAlignedRectangle object named Rectangle in GameScreen
To add the TileShapeCollection:
Open the project in Visual Studio
Open GameScreen.cs
Add the following using statement:
Add the following at class scope:
Add the following to CustomInitialize:
To add movement and collision to your rectangle, add the following code to CustomActivity:
Finally you'll need to remove the TileShapeCollection. To do this, add the following to CustomDestroy:
By default each rectangle in a TileShapeCollection occupies the entire tile (16x16). Custom shapes can be defined in Tiled to create rectangles which occupy less than the entire tile, or even polygons for sloped collision. Partial tile collisions are defined in the TSX file, typically in the StandardTileset.tsx. To add collision on tiles:
Open the TSX file in Tiled
Select the tile which should have partial collision
Select View -> View and Toolbars -> Tile Collision Editor
Draw a rectangle or polygon on the tile
Set the type on the tile which has the collision. Note that the same type can be given to multiple tiles. Be sure to select the tile and not the shape. You may need to deselect and re-select the tile to force its properties to display rather than the newly-drawn polygon.
Repeat this process for any other tile which should have custom shapes.
Once you have added shapes to all of the tiles, and once you have set the types on the tiles, save the TSX file.
Paint the tiles in their desired locations. Note that tile collision can be previewed in Tiled by selecting the View -> Show Tile Collision Shapes option
Save the Tiled (TMX) file.
To use these shapes:
Select an existing TileShapeCollection or create a new TileShapeCollection. Typically this TileShapeCollection would be in the GameScreen.
Select the TileShapeCollection Properties tab
Select the From TMX Collision (use tileset shapes) option
Set Source TMX File/Object to Map
The TileShapeCollection will now include custom shapes as defined in Tiled.
PlatformerCharacterBase and TileShapeCollection - discusses how to use the PlatfromerCharacterBase with TileShapeCollection.
AdjustRepositionDirectionsOnAddAndRemove determines whether a TileShapeCollection adjusts the RepositionDirections property on contained AxisAlignedRectangles when a new rectangle is added. This value defaults to true, and in most cases it should be left unchanged. For more information on the RepositionDirections, including how it pertains to TileShapeCollections, see the AxisAlignedRectangle.RepositionDirections page.
By default, TileShapeCollections adjust the contained rectangle RepositionDirections to prevent snagging. For example, the following image shows how RepositionDirections are adjusted to prevent snagging on a flat surface.
The image above displays the RepositionDirections of four rectangles, all of which belong to the same TileShapeCollection. However, consider a situation where two TileShapeCollections are needed. For example, a game may have two TileShapeCollections:
SolidCollision (white, regular ground collision)
IceCollision (blue, slippery collision)
In this case, each TileShapeCollection would adjust the RepositionDirections of each of its contained rectangles, but areas where the TileShapeCollections touch would not be properly handled, as shown in the following image.
In this case if a player were to walk across the transition between SolidCollision and IceCollision, the player's may snag on the seam (horizontal velocity may stop). The RepositionDirections for the rectangles in the middle of the strip should consider adjacent rectangles in different TileShapeCollections, rather than only rectangles in their own TileShapeCollection. To solve this problem, we can use another TileShapeCollection which contains all rectangles from both the SolidCollision and IceCollision. Keep in mind, a rectangle can exist as multiple TileShapeCollections, so we can take advantage of this to properly adjust RepositionDirections. Once we solve this problem (as shown below), the center rectangles where the two TileShapeCollections meet will no longer have inward reposition directions.
For this example, consider two TileShapeCollections defined in a GameScreen in Glue: SolidCollision and IceCollision.
We can uncheck the Adjust Reposition Directions On Add And Remove option in the Variables tab for both TileShapeCollections.
Next we can create a combined TileShapeCollection in Glue.
We'll mark this new TileShapeCollection as Empty so that we can fill it in code.
Finally, we can insert the TileShapeCollections which we'd like to adjust the RepositionDirections of, in context of each other, in code. To do this, we can modify the CustomInitialize of our GameScreen:
It's important to note that the purpose of inserting the collisions into CombinedTileShapeCollection is to adjust the RepositionDirections of each of the contained rectangles. Each individual TileShapeCollection (SolidCollision and IceCollision in this case) are still fully-functional TileShapeCollections, and CollisionRelationships can still be created between entities and these TileShapeCollections.
AddMergedCollisionFromTilesWithProperty adds rectangles to the calling TileShapeCollection for all tiles in the first argument (LayeredTileMap). Rather than creating individual rectangles for each tile, the rectangles will be merged - all adjacent rectangles in either a row or column will be combined into one to reduce memory consumption and to speed up collision calls. Merging will happen either along rows or columns depending on the SortAxis property.
The following code creates adds collision to a LayeredTileMap called SolidCollision from a LayeredTileMap called Level1 . It adds collision for all tiles with the property HasCollision .
Consider the following image (from Tiled). In this map all painted tiles have the HasCollision property, so all tiles will create collision. At runtime this will produce the following collision if not using merged collision (if calling AddCollisionFromTilesWithProperty ) : If we change the call to use AddMergedCollisionFromTilesWithProperty then the number of rectangles is significantly reduced, as shown in the following image:
Merging will work even for more complex maps, such as maps with gaps and concave areas, as shown in the following image:
As mentioned above, merging will be performed according to the SortAxis property. By default the SortAxis value is set to X, so collision will be merged along columns, so that the rectangles can be sorted along the X axis.
If we change the SortAxis to Y prior to adding collision, then merging will happen along rows.
In general the SortAxis should be X if the map is wider than it is tall, and it should be Y if the map is taller than it is wide. Adjusting the SortAxis according to the map's width or height will allow collision partitioning to operate efficiently.
The LastCollisionAxisAlignedRectangles property stores a list of AxisAlignedRectangles which collided with the last object to perform collision against a TileShapeCollection. This can change multiple times per frame since multiple objects may collide with a TileShapeCollection. Therefore, this property should be used immediately after a collision occurs. Typically this is accessed in a CollisionRelationship event. This list may contain multiple rectangles if the last collision check resulted in multiple rectangles overlapping.
For this example, consider a platformer entity which is performing solid collision. We can print information about the collision to the screen in an event for the collision relationship, as shown in the following code:
The CollideAgainstClosest method can be used to perform collision between a Line and a TileShapeCollection. The method returns whether a collision has occurred. Also, it marks the closest collision point. Line vs TileShapeCollection closest collision can be used for a variety of gameplay purposes such as:
Laser vs. level
Grappling hook vs. level
Fast-traveling bullet vs level
Other types of shapes usually are checked over the course of multiple frames as a collidable object moves, and these shapes have a fixed size. However, lines can be of infinite size, and often times are checked just once, such as when a bullet is fired.
The following code can be added to a GameScreen to draw a line from the camera's position to the cursor's position. CollideAgainstClosest is used to find the last collision point which is used to draw a circle. This code assumes that your screen (such as GameScreen or Level1) contains a TileShapeCollection named SolidCollision.
InsertCollidables allows the adding of a list of ICollidable rectangles to a ShapeCollection. This is usually done for collidables which align with a grid and which are used for solid or platformer collision.
Often when creating solid collisions, a game uses the TileShapeCollection type. However, at times each collision rectangle should be an entity. This is necessary if the collision has additional behavior beyond collision. For example blocks may play animations, may trigger game actions (such as unlocking a door), or may HP and break (such as when being shot). In situations like these, each block should be an entity to keep track of its state and to provide additional functionality through custom code. TileShapeCollections automatically adjust their contained rectangle RepositionDirections, but collidable lists do not have this functionality built-in. Prior to adjusting reposition directions, a row of blocks may have the following RepositionDirections:
The purple reposition directions are considered undesirable because they can cause snagging. After fixing this problem using InsertCollidables, the RepositionDirections will only point outward, allowing other entities to collide without snagging.
This example uses a collidable entity named Block which has a list called BlockList in GameScreen.
We will use an empty TileShapeCollection to fix the RepositionDirections:
In code, call InsertCollidables on the CombinedTileShapeCollection to add the BlockList
Now all blocks in the BlockList will have their RepositionDirections adjusted for every Block that is already created when the method is called.
RemoveSurroundedCollision removes all rectangles which are surrounded by other collisions on all four sides. Calling this method removes the "inside" of solid collision areas, resulting in only the outline tiles being preserved.
This method can be used to reduce the number of collision objects to improve runtime performance and reduce memory usage. This method should only be used when the collision is solid because solid collisions only need their outline to function properly. However, non-solid collision (such as a collision area representing water that the user can swim through) should not use this method. RemoveSurroundedCollision can provide performance improvements similar to merged collisions (such as AddMergedCollisionFromTilesWithProperty ), but this method does not introduce snagging so it is suitable to be used in platformers.
The following code shows how to remove all surrounding collisions using the RemoveSurroundedCollision method.
Note that this method can be called after multiple AddCollision methods.
The Rectangles property provides access to the list of AxisAlignedRectangles stored in a TileShapeCollection. This list will be ordered based on the TileShapeCollection's SortAxis property.
The following code shows how to loop through all rectangles in a TileShapeCollection and perform custom logic:
Testing your collision using Fill or Border Outline is a handy way to make sure your game is working as you expect it, but eventually you will want to have collision defined in a map. For this tutorial we'll work with a simple game with a single TMX file already added to the GameScreen which also contains a TileShapeCollection. First we'll specify which tiles should have collision:
Add a new TileShapeCollection to the GameScreen called CombinedTileShapeCollection. The name CombinedTileShapeCollection is a recommended name for TileShapeCollections used specifically for fixing RepositionDirections.
Leave the newly-created TileShapeCollection as empty.