Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The CoordinateAdjustment variable is used to adjust the texture coordinate of tiles inward to prevent adjacent pixels from bleeding in to tiles. This value needs to be balanced between being too small (resulting in values bleeding in to tiles) and too large (resulting in pixels being excluded from tiles). This value is in texture coordinates as opposed to pixels, so ideally it should be adjusted according to the size texture size used on the tile map.
If CoordinateAdjustment is set to 0, then the texture coordinates are assigned according to the edges of the tiles. For example, a texture coordinate of 0 would use the area represented by the yellow are in the image below:
Increasing the CoordinateAdjustment value results in the yellow area shrinking.
CoordinateAdjustment is a static property no the MapDrawableBatch so it can be assigned prior to loading a TMX. Glue projects typically load TMX files when a Screen is first created, so the CoordinateAdjustment value must be assigned prior to loading the screen to take effect.
The PaintTile can be used to change the texture coordinate on an existing tile in the MapDrawableBatch according to its index. This method can be used if your game requires dynamically the graphics of a tile after it is created (either from a .TMX file or manually).
PaintTile has the following overrides:
PaintTile takes the orderedTileIndex and the texture ID.
The orderedTileIndex value is the index of the tile on the tilemap. Usually, an index of 0 is the top-left tile on the map. The subsequent tiles are ordered counting left-to-right if the map is taller than it is wide. The following image shows example orderedTileIndex values for a map which is ordered left-to-right.
If your map is wider than it is tall, then the ordering is performed top-to-bottom rather than left-to-right. The following image shows example orderedTileIndex values for a map which is ordered top-to-bottom.
The newTileId is the index of the texture of the tileset. This index uses a similar indexing pattern but it always begins at the top-left with a value of 0 and is ordered left-to-right. The following image shows example newTileId values in a tileset.
This example assumes the following:
You have a LayeredTileMap in your game called Map
You have a Layer added to the LayeredTileMap called LayerForPainting. This could be created through code, but the easiest way to do this is to add this layer in Tiled. For information on how to create a layer through code, see the MapDrawableBatch page.
This layer references a tileset that you intend to paint with. This can be done by painting tiles on the layer in Tiled which will result in the layer being associated with the tileset containing the painted tiles
The layer is already filled with tiles. This enables the painting to adjust texture coordinates without adding new tiles.
In this example, this map is the modified Level1Map.tmx which is created automatically in a platformer game. To paint on this tile, add the following code:
FlatRedBall does not support multiple tilesets per layer (MapDrawableBatch). In other words, each MapDrawableBatch can only paint tiles using its current layer. Therefore, the value of 0 (the top-left most tile in the tileset) depends on the layer's current TileSet. Games which require multiple tilesets should create multiple layers.
PaintTileTextureCoordinates can be used to change the texture coordinates on a tile by its ordered index. This method can specify all four coordiantes (left, top, right, bottom) or just the top and left. If only the top and left are specified, the bottom and right are automatically determined based on the tileset's tile dimensions.
Note that this requires the ordered tile index. This sample assumes that tiles have been added manually, and then painted later.
MergeOntoThis can be used to merge tiles from one or more source layers into a destination layer. Merging can be used for a number of reasons:
To simplify management of layers
To improve performance
This example uses a tmx file which includes a layer named Layer2 which contains ice blocks.
The other tiles (the red number 1 and the orange brick surrounding blocks) are part of the GameplayLayer - the standard layout for Level1 if using the wizard. The following code shows how to merge the layers:
The code above includes diagnostic variables to count quads and layers. These values can help verify that the layers have been merged at runtime as shown in the following screenshot:
Even though layer2 has been destroyed, the ice blocks still draw as shown in the following screenshot:
Note that LayeredTileMaps partition their tiles based on the X or Y axis, so merging is not simply an addition of quads at the end of the layer. Rather, merging inserts the quads to preserve the axis sorting so that efficient partitioning during drawing can be performed.
The NameTileOrderedIndexes property can be used to find tiles by a given name. It is a Dictionary<string, List<int>> , where the key is a name, and the value is the index of tiles which have the given name.
The MapDrawableBatch object stores a list of vertices (points) which are used to define the coordinates for each tile. These points are used by the rendering code in the MapDrawableBatch class to perform efficient rendering. Each tile is composed of a list of vertices, as opposed to a Sprite (as might be the case if the MapDrawableBatch were a FlatRedBall-drawn object). Therefore, to access and modify properties on a tile, its index must be known. The following image shows the indexes of a simple tile map:
The following code example shows how to create an Entity for every tile with the name "CreateEntity".
Tiles will only have properties at runtime if it uses a tile in a tileset with a Name property.
The MapDrawableBatch class is the heart of the Tile Graphics Plugin. It is ultimately the class responsible for rendering the tile map graphics when your game runs. Although the Tile Graphics Plugin provides ways to construct MapDrawableBatches from .scnx files, the MapDrawableBatch can also be constructed purely in code. While this does require some code, working with the MapDrawableBatch class is actually very easy.
The name MapDrawableBatch comes from the fact that it's usually used for tile maps, and it implements the FlatRedBall IDrawableBatch interface. The IDrawableBatch interface allows classes to implement completely custom rendering code using XNA, yet the result of the rendering will still be properly sorted with other FRB objects. The result is that the rendering code appears to be fully integrated into FRB despite being completely custom. If you are interested in more info on IDrawableBatch, see the IDrawableBatch page.
The MapDrawableBatch class works very well in Screens, but it can also be used in a non-Glue project. If you are not using Glue, make sure to follow the proper initialize/activity/destroy pattern explained here. For simplicity the rest of this article will be written assuming you are using Glue Screens. First you will need to download and install the Tile Graphics Plugin from GlueVault which can be found here. If you are not using Glue, but instead doing everything with pure code, you can download all of the .cs files from here: http://www.flatredball.com/FlatRedBallAddOns/Trunk/FlatRedBall.TileGraphics/FlatRedBall.TileGraphics/. Next you will need to create or open a Glue project. Doing so after the the Tile Graphics Plugin has been installed will automatically add the appropriate classes to your code. Once you have a project created, you can verify the Tile graphics Plugin is installed and that it has properly modified your project by checking the project in Visual Studio. You should have a TileGraphics folder in your project.
The next step is to add a Screen to your Glue project. This Screen will also need to contain a .png (any will do). We will be using this .png file in code. For more information on how to add files to your Screen, and how to access files in code, see this page.
Now that we have a project set up and we have a file that is available to be used, we can create our map. The first step is to create an instance in our GameScreen:
Open your project in Visual Studio
Navigate to your Screen class's .cs file (the custom code file)
Add the following code inside your GameScreen class but outside of any function:
Next we'll initialize our class. First I'll present the code, then break apart what each piece means. The full code is:
Let's look at each section and see what it means:
The UsePixelCoordinates code is responsible for putting our Camera in "2D mode". For more information, see this page.
This code creates an instance of the MapDrawableBatch. Here we specify the number of tiles we want in our map. We are specifying it as 32 x 32. Keep in mind that increasing the dimensions will increase the number of tiles much faster. For example if your map is 32 tall and 32 wide, then it will include 32x32 = 1024. However, increasing to 64x64 results in 4096 tiles. While a 4096 map will usually render without any performance slowdown, it is possible to get to very large numbers very quickly, so you will want to run performance tests on your target platforms for the size of map you are interested in creating. Next we specify the size in pixels of how big our cells on our sprite sheet (the texture used by our tile map) will be. For example, consider the following image to show how big the cells are in a sprite sheet:
In this example the size of the sprite sheet cell is 16 by 16 pixels. My image happens to be 16 by 16 pixels so there is only one cell in the sprite sheet.
This line of code creates each cell. Each cell needs to know 3 pieces of information:
The bottom-left corner of the tile in world coordinates.
The width and height of the tile. This will usually match the size of the cells.
The top, bottom, left, and right pixels of the cell to use. In this case we are rendering the entire sprite sheet, so we use 0 - 16.
The AddToManagers call adds the MapDrawableBatch to the engine. In other words, once this call is made the MapDrawableBatch will be rendered to the screen when your game runs:
MapDrawableBatches (map layers) support parallax by assigning the values in Tiled or in code. By default parallax has a value of 1, which means that the object will show no parallax. A value between 0 and 1 results in the layer behaving as if it is in the distance (not scrolling as quickly when the camera moves). A value greater than 1 results in the layer behaving as if it is in the foreground (scrolling more quickly when the camera moves).
To set parallax:
Open an existing map
Select a layer
Change its Parallax Factor property to the desired value
Tiled provides a preview of the parallax if you scroll the main view
Once the file is saved, the parallax will automatically be applied at runtime in the game.
RenderingScale can be used to draw a MapDrawableBatch at a larger size. By default this value is set to 1 which means the MapDrawableBatch draws at its original size. Note that increasing the RenderingScale is not recommended for "zooming" the game in or out - it's best to use the FlatRedBall Camera. Increasing the RenderingScale can be used to make layers in-game appear larger or smaller.
The following code finds a layer called CloudLayer and increases the RenderingScale gradually as the user holds either the up arrow or down arrow on the keyboard.
SortAxis controls how the MapDrawableBatch performs culling. This value controls how culling is performed when the MapDrawableBatch is drawn. If SortAxis is set to SortAxis.X, then the map will cull tiles from the left and right of the camera visible bounds. Otherwise, if SortAxis is set to Y, then the map will cull tiles from above and below the camera visible bounds. This value is automatically set when the map is created according to whether the map is wider (SortAxis.X) or taller (SortAxis.Y). Setting SortAxis to SortAxis.None results in the map not being culled at all when rendered.
This article shows how to use the MapDrawableBatch to render a large number of Sprites very efficiently. The MapDrawableBatch is less flexible than using individual Sprites; however, in exchange for giving up that flexibility the MapDrawableBatch can be extremely efficient. In fact regardless of optimizations the FlatRedBall Engine will likely never be able to render a large number of Sprites faster than MapDrawableBatch because of the flexibility it supports. Keep in mind that the MapDrawlableBatch is used for Sprites which do not move. Once they have been pasted, they will be there until MapDrawableBatch is either made invisible or removed completely from the engine. This makes the MapDrawableBatch ideal for tile maps and static environments; although it could be used for other static objects such as backgrounds and static UI/HUD components.
Internally MapDrawableBatches do not store references to Sprites. Instead they store a list of vertices which are used for rendering, much like model objects when dealing with 3D rendering. The Paste method will create a new set of vertices to match the argument Sprite; however, the Sprite itself is not held by the MapDrawableBatch. This means that the same Sprite can be used over and over to reduce allocation during the creation of a MapDrawableBatch.
The following code shows how to create a 4096 (that's 64x64) MapDrawableBatch using the Paste method. Despite the large number of Sprites, the MapDrawableBatch will render efficiently - even on mobile platforms such as the Windows Phone 7.
You will need to add the following using statement for MapDrawableBatch to be resolved:
The Paste method adds vertices to the MapDrawableBatch class. The Sprite which is passed in the map method is *not* stored by the MapDrawableBatch. This means a few things:
Changes to the Sprite after paste will not be reflected in the map. This means that if you move the Sprite around, it will not change on the map. The map is static.
Since the Sprite reference is not used internally in the MapDrawableBatch, the same Sprite can be used over and over. This reduces the amount of allocation needed when creating a MapDrawableBatch.
The MapDrawableBatch class represents a single layer in a .tmx file. It implements the IDrawableBatch class to perform custom rendering. It internally creates a single vertex buffer which is drawn all at once with no render state changes for maximum performance. Usually .tmx files are loaded into a LayeredTileMap, which contains one or more MapDrawableBatch instances.
When the MapDrawableBatch is created it will only create vertices for tiles which exist. Therefore tiles which are not painted or which have been erased in Tiled will not create vertices.
MapDrawableBatch supports a Modulate color operation through its Red, Green, and Blue values. By default these values are all set to 1.0f, but they can be modified at runtime to tint or darken the map.
MapDrawableBatch instances are typically created by adding a TMX file to your project. By default FlatRedBall top down and platformer projects contain TMX files for each level. MapDrawableBatch instances can also be created in code. The following code shows how to create a new MapDrawableBatch which is filled with a pattern from a texture called FRBeefcakeSpritesheet The following code assumes that an existing Map exists (although this is not necessary), that the code has access to a Texture called FRBeefcakeSpritesheet, and that this code exists in the CustomInitialize of a Screen such as Level1.
The code above includes some subtle considerations:
The CustomLayer MapDrawableBatch uses X axis sorting. Therefore, all tiles must be added in order of X, largest to small. Breaking this order will result in incorrect rendering and other unpredictable behavior.
The entire tile set is filled. This enables painting later without having to add tiles. If tiles are added on paint, this can make sorting far more difficult.
RemoveQuads can be used to remove quads from the MapDrawableBatch by index. This method is useful in situations where you want to remove tiles from the MapDrawableBatch at runtime, such as when creating Entities from the contents of a tile map.
The following shows how to remove the first three tiles from the MapDrawableBatch:
For more information on LayeredTileMap, see the LayeredTileMap page.
Often the internal quad ordering is unknown. Therefore, the MapDrawableBatch class provides a GetQuadIndex method to convert world X and Y to an index. If no tile is located at the index, a value of null is returned. The following code could be used to remove quads when the user clicks a mouse: