Skip to content

7. Creating a New Collision Tileset

Triangly edited this page Sep 22, 2024 · 8 revisions

Tile Types and Format

As described in the first chapter, collision tiles are divided into three types:

  • Full Solid
  • Top Solid
  • LBR Solid

Collision is represented by a tileset made up of 16x16 tiles, and it must follow a specific format. Below is a screenshot showing collision tiles from Sonic the Hedgehog 3:

chapter7_image1

As you can see, all three types of tiles are shown in the same order as listed above. By default, the framework supports 256 unique tiles in a single tileset (1 empty tile - the first one - and 255 customisable tiles). This limitation is defined by the ENGINE_TILE_COUNT macro, along with the tile size via the ENGINE_TILE_SIZE macro. These constraints apply to the entire project: if you change these macros (which is not recommended), all tilesets must adhere to the new values.

Creating a Custom Tileset

To create your own tileset, duplicate the sprite spr_ts_collision_template in the project. The framework only requires data from Full Solid tiles. You duplicate these tiles into the corresponding cells of other groups so that they can be used when placing collision tiles in levels.

chapter7_image2

However, simply adding the tileset to the game is not enough. The collision system does not rely on built-in collision functions but on a set of custom width, height, and angle data.

More information about tile arrangement and usage can be found in this discussion.

The colour of the tiles does not matter.

Generating Collision Data

In the scr_fw_collision_setup() script, call the collision_generate() function for your tileset sprite, and the game will generate the width and height data at runtime. Afterward, you can load this data using the collision_load() function in a Create Event of your room controller (or c_stage).

If using the template grid above, the arguments for the collision_generate() function will be:

collision_generate(your_tileset_sprite_here, your_angle_array_here, 0, 0, 2, 2);

Angle Data

To properly generate collision data, you need to pass an array of angles. Each value in the array represents the angle of the corresponding tile. These angles are represented by integer values ranging from 0 to 255, covering a full 360-degree circle.

The angles progress clockwise, starting from 0 at the downward direction:

  • 0 is downward (0 degrees)
  • 64 is leftward (270 degrees)
  • 128 is upward (180 degrees)
  • 192 is rightward (90 degrees)

Each integer represents a single step in the 360-degree circle. With 256 possible values in the array, each step corresponds to 1.40625 degrees (360° / 256 = 1.40625°).

The array must have one value for each tile, starting from the second tile (the first tile is empty and is practically non-existent). If the array is shorter than the total number of tiles defined by ENGINE_TILE_COUNT, any missing tiles past the angle array data will default to an angle of 0.

You can also pass an empty array if you want to quickly test collision functionality, in which case all tiles will default to an angle of 0. Additionally, you may use this tool to visualise the angle format, assisting you with generating angles.

As an example, here the data you'd use to assign angles to the Sonic 3 collision tileset:

        var _s3_data =
	[
		     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
		252, 252, 252, 252, 252, 252, 252, 252, 248, 248, 248, 0,   240, 240, 226, 208, 
		208, 200, 200, 200, 200, 200, 212, 214, 214, 0,   222, 0,   250, 238, 232, 242, 
		242, 240, 252, 252, 250, 248, 246, 246, 248, 250, 252, 252, 242, 244, 244, 226, 
		228, 240, 238, 254, 252, 248, 244, 244, 240, 244, 248, 252, 252, 236, 236, 224,
		228, 220, 242, 246, 250, 252, 232, 236, 224, 212, 208, 202, 198, 194, 236, 244,
		252, 214, 224, 204, 196, 212, 216, 224, 212, 240, 236, 236, 110, 114, 120, 0, 
		96,  100, 0,   92,  236, 244, 252, 132, 140, 146, 160, 168, 10,  32,  178, 56, 
		188, 70,  194, 84,  202, 112, 106, 96,  210, 108, 112, 224, 190, 180, 168, 160, 
		152, 140, 132, 216, 226, 232, 242, 246, 250, 0,   254, 250, 248, 242, 224, 238, 
		246, 252, 224, 224, 252, 246, 238, 196, 202, 210, 210, 202, 196, 62,  56,  52, 
		48,  48,  52,  58,  62,  0,   40,  40,  40,  40,  40,  168, 168, 168, 168, 168, 
		104, 112, 120, 124, 126, 96,  96,  80,  72,  72,  68,  66,  40,  40,  40,  32, 
		24,  24,  16,  12,  8,   4,   244, 244, 250, 252, 238, 238, 242, 224, 232, 224, 
		232, 254, 238, 236, 254, 252, 248, 52,  224, 224, 196, 204, 224, 212, 252, 244, 
		236, 0,   0,   0,   250, 250, 244, 240, 224, 0
	]

Optimising with Binary Data

If you want to optimise collision data, set the flag global.tools_binary_collision to true. This will tell the collision_generate() function not to load the generated data into the game's memory but instead save it in binary format in your project’s save directory. You can then move this data to the datafiles/collision/ folder in your project and load it using collision_load_binary(). This method reduces memory usage and improves loading times.

Do not forget to remove the collision_generate() function call for this tileset as it will no longer be needed.