📜 ⬆️ ⬇️

2D Platform Implementation Guide (start)

Since I was previously disappointed with the amount of information on this issue, I decided to fill this gap by collecting different types of implementation of 2D platformers, describing their strengths and weaknesses and reflecting on the implementation details.

My goal was to create a comprehensive and understandable guide to the implementation of 2D platformers.


')
Disclaimer : Some of the information in this article is obtained by reversing the design behavior of the game, and not from the source code or from programmers. It is possible that in fact the game is not implemented as described in the article, but simply behaves in a similar way. It is also worth noting that the size of the grid of tiles for game logic may differ from the size of graphic tiles.

Four solutions


Four basic solutions come to mind when creating a platformer. In the framework of this article, all four will be considered, but due to the large volume, the article is divided into 2 parts.

From the simple to the most complex it is:

Type 1: Tile (clean)


In it, character positioning is limited to a grid of tiles, so he can never get between two tiles. To create the illusion of smooth movement, various animations can be used, however, according to the game logic, the character is always directly on a particular tile. This is the easiest way to make a platformer, but it imposes large restrictions on the control of the character, making it unacceptable for traditional action-platform games. Nevertheless, it is very popular for puzzles and "cinematic" platformers.

Flashback, tile grid
Examples: Prince of Persia, Toki Tori, Lode Runner, Flashback

How does it work
A map is a grid of tiles, each of which contains information about the properties of a tile: whether it is an obstacle or not, which image to use, which ones to play the sounds of steps, and so on. And the player and other characters are represented by a set of one or several tiles moving together. For example, in Lode Runner, a player is one tile. In Toki Tori, the player is 2x2 tiles. And in the Flashback game, which is rather unusual due to the small size of the tile grid, the player has dimensions of two tiles in width and five in height (see the image above) when standing, but only three tiles in height when he bends down.
In games of this type, the character usually does not move diagonally, and if it moves, then the movement can be decomposed into two separate steps. Movement to several tiles can be done with multiple shifts of single tiles, if necessary (in Flashback the player always moves two tiles at a time). The following algorithm develops:
  1. Create a copy of the character where it should be (i.e. if you need to move 1 tile to the right, you need to make a copy, where each character tile is shifted to one tile to the right)
  2. Check this copy for intersection with background and other characters.
  3. If an intersection is found, the movement of the character is blocked. Need to respond accordingly.
  4. Otherwise, the path is clear. Move the character here, playing the animation, if necessary, to make the movement look smooth.


This type of movement is completely unsuitable for ordinary jumps “in an arc”, therefore games of this genre are completely devoid of jumps (Toki Tori, Lode Runner) or allow only horizontal or only vertical jumps of a fixed length (Prince of Persia, Flashback), which is nothing else as usual linear motion. The advantages of this system are simplicity and accuracy. Such games are more deterministic, which leads to less likelihood of glitches and more controlled gameplay, which does not require too often adjust the values ​​depending on the circumstances. Fixed distances for interaction provide an opportunity to make beautiful seamless animation. The implementation of some game mechanics (such as grabbing a ledge and one-sided platforms) is greatly simplified - all that needs to be done is to check whether the background tiles in the desired position satisfy the necessary conditions.
Of course, this system does not allow taking steps to less than one tile, but steps can be reduced in various ways. For example, tiles can be slightly smaller than the player (say, player 2x6 tiles), or you can allow “only visual” movement to move within the selected tile without changing the logic (I suppose this solution is applied in “Lode Runner - The Legend Returns ")

Type number 2: Tile (Smooth)


Collisions are still determined by the grid of tiles, but characters can move freely in the world (usually with a resolution of 1 pixel. See the remark at the end of the article regarding smoothness of movement). This is the most common form of implementation of platformers on 8-bit and 16-bit consoles, which remains popular today, as it is extremely easy to implement and allows you to edit the level much easier than using more complex techniques. It also allows you to make biases and smooth jumps in an arc.
If you are not sure what kind of platformer you want to do, but definitely an action, then I suggest to stay at this type. Not surprisingly, the vast majority of the best action-based platformers of all times are based on this method.

Mega Man X, with a grid and a rectangle of the character.

Examples: Super Mario World, Sonic the Hedgehog, Mega Man, Super Metroid, Contra, Metal Slug, and virtually any 16-bit platformer

How it works
Information about the map is stored as well as in the pure tile method. The only difference is how the character interacts with the background. Now the character has a collision calculation rectangle describing it (AABB, which cannot rotate), and, as a rule, the size is a multiple of the tile size. Standard sizes are like one tile wide and one (small Mario, crouched Samus), two (large Mario, Mega Man, crouched Samus) or three (standing Samus) tiles in height. In many cases, a character's sprite is visually more than a logical rectangle, as this makes the game look more enjoyable and the gameplay more honest (agree that it is better for the player to avoid hitting him when he should get it than to get it when he shouldn't).
In the image above, you can see that the sprite with the character “X” is square (two tiles wide), but the rectangle describing it is only one tile wide.
Provided that there are no biases and one-sided platforms, the algorithm is simple:
  1. Spread the motion on the X and Y axes, make one move at a time. If it is planned to add later slopes, then first by X, then by Y. Otherwise, the order is absolutely not important. Then for each axis:
    Get the coordinate of the face in the direction of motion. For example: if you move left, the X coordinate of the left side of the describing rectangle. If right, the X coordinate of the right side. If the top, the Y coordinate of the top, and so on.
  2. To determine which lines of the tiles intersect with the describing rectangle - this will give the minimum and maximum value of the tile on the OTHER axis. For example, if we move to the left, suppose a player intersects with horizontal lines 32, 33 and 34 (here it is, tiles with Y = 32 * TS, Y = 33 * TS and Y = 34 * TS, where TS = tile size).
  3. Examine these lines with tiles in the direction of motion until you find the nearest obstacle. Then in the cycle, look at each moving obstacle and determine which of the closest ones is on your way.
  4. The resulting movement of the player along this direction is the minimum between the distance to the nearest obstacle and the player’s range.
  5. Move the player to a new position. From this position, process another coordinate if you have not processed it yet.


Slopes



Mega Man X, with comments to slopes

Biases (tiles, which are indicated by green arrows) are a little tricky thing, since they and obstacles and at the same time allow the character to enter their tile. They also cause a change in the Y coordinate with a simple movement along the X axis. A simple way to do this is to allow the tile to store information about the "floor height" on each side. Suppose a coordinate system with zero in the upper left corner, then the tile to the left of X (the hero), the first slope tile, will contain heights {0, 3}. The one on which he stands will contain {4, 7}, then {8, 11}, then {12, 15}. After that, everything will be repeated again with {0, 3} and so on. After we see a slope with a large angle, assembled from two tiles {0, 7} and {8, 15}.

Detailed view of the {4, 7} tile

The method that I am going to describe allows making arbitrary biases, despite the obvious reasons, these two deviations are most common and are obtained from 12 tiles (6 described earlier and their mirror copies). The collision algorithm changes for horizontal movement:


And for vertical movement:


One-way platforms



Super Mario World, where Mario falls down (left) and stands on (right) the same one-way platform

One-sided platforms are the usual platforms for which you can stand, but you can jump through them from below. In other words, they are considered an obstacle if you stand on them, and are not considered if you jump from below. This fully describes their behavior. The algorithm changes slightly:

It is rather tempting to tie the behavior to a positive value of the player’s vertical speed (if the player falls), but this will not be true: the player can, while jumping, cross the platform, but then start falling down again, without having to put his feet on the platform. In this case, he must still fall through it.
Some games allow the player to jump down from such platforms. There are several solutions, but they are all relatively simple. For example, you can disable one-sided platforms by one frame and make sure that the vertical speed is at least one pixel (so that the character will be lower than the platform on the next frame), or you can check whether it is worth it on a one-sided platform, and if it is, then move the character one pixel down.

Stairs



Mega Man 7, with a grid of tiles, illuminated tiles of a ladder, and a player’s rectangle.

Ladders can seem like a tricky thing, but they are implemented quite simply - when a character is on a ladder, he just ignores most of the collisions and redefines them with a new set of rules. Stairs are usually one tile wide.
The staircase can be reached in two ways:

This immediately causes the effect of attaching the player’s X coordinate to the ladder tiles, and if you move down on the ladder, you just need to change the Y coordinate, since the player is already inside the real ladder. From this point on, some games begin to use another descriptive box to determine whether the player is still on the ladder. Mega Man, for example, apparently uses a single tile (the equivalent of the top tile of an ordinary character, circled in red in the picture above).
To leave the stairs there are several options:

While the player is on the ladder, the character's behavior changes so that he can usually move up and down and sometimes attack.

Steps



Castlevania: Dracula X, with a grid of tiles

Stairs are a type of ladder, as seen in some games, but especially in the Castlevania series. The implementation is very similar to the stairs with some reservations:

Other games may implement ladders as biases. In this case, the stairs are more decorative in nature.

Moving platforms



Super mario world

Moving platforms may seem tricky, but they are actually extremely simple. Unlike normal platforms, they cannot be represented by fixed tiles (for obvious reasons), but it is necessary to describe them with a AABB rectangle. This is a common obstacle for all types of collisions. If you stop at this, it will be very slippery platforms (they will work, but as intended, except that the character will not move with them).
There are several solutions. Let's analyze one algorithm:


Other features



Sonic the hedgehog 2

There are games that have complex and exclusive features. For example, the Sonic the Hedgehog series. These features are beyond the scope of this article (and my knowledge, which is very important!), But may be the subject of a future article.

Continuation (end)

Source: https://habr.com/ru/post/265911/


All Articles