-
Notifications
You must be signed in to change notification settings - Fork 2
Design Discussion
This page contains information on various design decisions that were made in creating different aspects of the game engine.
Some spritesheets may contain individual sprites of different sizes. In such a scenario, we need to divide the overall spritesheet into unit sprites. The current implementation of the AssetLookup table enables such spritesheets, but requires the programmer to enter in the spritesheet's dimensions in terms of unit sprites, the target sprite's dimensions in terms of unit sprites, and the upper left vertex coordinate (first quadrant style) for the target sprite on the overall spritesheet. The Sprite class takes this information to create a ratio of the Sprite's size and position relative to the spritesheet for rendering.
![]()
In the above example, the overall spritesheet has been divided into unit sprites. Let's assume that the unit sprites are perfect squares. Note that the example contains 26 unit sprites in the x direction and 24 unit sprites in the y direction. If we were to add the smallest tree (center rightmost tree) to the AssetLookupTable, its entry data would look something along the lines of this (note that this isn't the exact recorded values since different unit sprites were used there):
- Sheet Index = Vector2D(24, 15)
- rows = 24
- cols = 26
- unitsWide = 2
- unitsHight = 4
Of course some spritesheets need to break the unit sprite dimensions further down if the sprites on the sheet bleed into a shared coordinate. As such it is important to consider how the spritesheet would be divided when designing the image. As long as the unit sprite dimensions are known in terms of pixels, it is merely a mathematical exercise to configure the AssetLookupTable entry.
Animation is all about illusions. Our eyes perceive motion when frames flash in front of us in rapid succession. The Sprite::Walk() function takes advantage of that illusion by iterating through the directional frames assigned to a given Sprite. For each animation, we assume that there are 4 directions that exist in a specific order: DOWN, LEFT, RIGHT, and UP.
![]()
The diagram above shows the rules that we follow for Character movement in the overworld. Here we assume that each map tile is 64p x 64p, and that the overworld Character Sprite is 64p x 96p. A full walk to an adjacent tile is divided into 8 steps (8 total Sprite::walk() calls), so the Sprite only travels 8 pixels per frame animation. If the Sprite is to move in a different direction, we change the Sprite's directional frame to the intended direction (idle frame) immediately, but do not change the Sprite's position. If the Sprite continues to move in the same direction, it will only change its frame on the third and seventh Sprite::walk() call.
Let's assume that each Sprite direction is configured to have 4 frames: Idle, Walk1, Walk2 (just another Idle), and Walk3. If the Sprite is facing left and is to move to the right, the Sprite frame changes from LEFT Idle to RIGHT Idle. If the Sprite is to continue moving, the Sprite keeps its RIGHT Idle frame until it reaches position 2 on the diagram. At that point, the Sprite enters its third Sprite::walk() call, so it changes its frame to RIGHT Walk1. When it reaches position 6 and begins its seventh Sprite::walk() call, it changes its frame again but to RIGHT Walk2 (looks just like an Idle/standing frame). If the Sprite were to walk to another tile to the right, its third and seventh Sprite::walk() calls would change the directional frames to RIGHT Walk3 and Right Idle, respectively, and the process repeats as necessary.
As long as the duration is set to an appropriate amount, the Sprite movement appears fluid. Don't believe me? Check out one of the Project's Demo videos and behold the power of animation illusion!
The engine currently presents a 1024p x 768p screen to the user. However, the generated maps for the game are not limited to the size of the screen. Since we want to have maps that are larger than the screen, we need to have a special way to convert screen to map coordinates.
For starters, let's assume that we have a map that is at least the same size of the screen, or larger. Let's also assume that each WorldMap contains the same amount of columns per row (see more information about WorldMap files in the Special Files wiki page).
We can think of the screen as a window into the game world (we don't call it a game window for nothing :) ). When we look out into a window, we can see a portion of the world outside. Of course parts of the world are cut off, so they aren't displayed to the user. Below is an example of this scenario:

In the diagram, we can see the dark green tiles represent the tiles that appear on the screen, and the light green tiles are those off screen. When we want to add a tile to the game, we may need to draw it off screen (negative positions are fine as they are just relative to the game window). For reference, the bottom left-hand corner of the game window designates the origin (0, 0). In order to record the positions of off screen tiles, we use the equation shown in the diagram.