SUPER MARIO DIAGONALIZED

For my final project I attempted to recreate the first level of the original Super Mario Bros. from a 2.5-D perspective.
(please switch to high quality video for best results)

Movement

My movement is almost identical to that of the original game.

Before starting work I found a resource from a developer that also attempted recreated the movement. Using an emulator and screenshots
this person measured the exact distance of each possible movement in 'pixel' increments. The infographic with this information can be
found in the infographic here.

These values are defined verbatim in my code, and then assigned as acceleration values depending on the state of the game. Position is
then calculated using simple distance/velocity formulas. I also compared the movement by hand running both my program and the original
game side-by-side, and comparing the results of performing different movements.

Collisions

I use simple AABB collisions for the game. Because every object in the world is aligned to the origin, and because the source material
is pixel based, I was able to use a static square bounding box for every single object. Each frame I check for collisions between the
player character and the other objects in view. The actual collisions checks are simply depth comparisons between the bounding boxes of
the two objects: if the sides of the boxes overlap, I calculate the distance of the overlap in both the x and y direction. The greater
overlap determines the axis of the collision, and it's value (negative or positive) determines it's direction.

To improve the accuracy of my collision checks I perform them in the following order:

1. Move the player along the X axis.
2. Check for colliding blocks.
3. Resolve X collision.
4. Move the player along the Y axis.
5. Check for colliding blocks.
6. Resolve Y collision.

I referenced this forum post and its top response to improve my collision detection.

Texture for brick blocks Texture for brick blocks

Mario's bounding box is the exact dimensions of his original hitbox. For blocks the dimension is standardized to 1.0^3, the only
exception being pipes which are composed of invisible blocks over which the pipe object is drawn.

Objects

There are two different types of objects in the game: blocks, which make up the core geometry of the world, and entities such as the
player character.

Blocks are drawn from an object file. The file has pre-defined texture coordinates allowing unique textures to be mapped to each side
of the cube. Using the original 16x16 sprites as a reference, I first redrew the images in a higher resolution (128x128), and then
altered and arranged the images in texture maps to be assigned to each type of block.

Texture for brick blocks Texture for question blocks Texture for stone blocks Texture for pipe facade

The models for entities are automatically composed from images. The program reads in an image and draws a cube for each colored pixel.
Instead of textures the color of each cube is assigned based on the color of the pixel.

Using this method I was able to quickly create 3D-models for the player character from pixel-based sprites. However I did not have time
to do any sort of optimization. As a result having multiple entities drawn at any time results in significant lag spikes. Originally
I planned to add a number of entities for different enemies, coins, scenery, etc, but due to this issue I decided to focus my limited
time on other areas.

It's like a Mario museum display Reference material

Level Creation

The level represented in the game has the exact layout of the original 1-1 level in Super Mario Bros. I did not however place arrange the
blocks by hand. Instead levels are created automatically from an image file:

yay horrible upscaling

In a similar way to the automatic model creation mentioned above, the program reads in a image and for each non-black pixel in the
creates a block object. The type of block created is determined by the color of the pixel, the exact mappings for which are found in
code specific to the level.

Animations

In order to emulate the pixel-based animation style of the original game, animations are tied to frames. In place of sprites I store
models of the character in different poses. Depending on the movement state of the player, a different model is drawn in the game.
The poses themselves are created from the original sprites using the method for entities described above.

Camera

By default the camera is fixed on the player. If the player character reaches the center of the screen, the camera pans to match
its movement. In similar fashion to the original game, the camera does not move to match vertical movement, and the player is restricted
from moving backwards past the view of the camera. There is a single light source in the game positioned the height of a block above the
camera and moves exactly with it.

2000 hours in MS Paint Where's Mario?

The player can press 'p' to pause the game. In this state the player has free control of the camera. Movement is controlling using the standard
'wasd', and players can also control the vertical movement of the camera by pressing 'spacebar' and 'e'. In this freecam mode the player
character cannot be controlled, and the game is essentially frozen until the player chooses to resume it. Also every object is drawn
at once (for demonstration purposes), allowing players to view the entire level at once.