Demo Animation:
(best viewed in 1080 quality and 60 FPS)
Loading IntroJust Console Screen for this part. The Console Screen is the light blue section. The "screen border" is the colour of the window and is just cleared to a solid colour (the flashing "loading" border is just clearing to a randomly chosen colour from the Console Screen's palette). The content is then "typed" one character at a time. The cursor is shows/hidden based on the current time in the animation (so that it flashes):
cs.setShowCursor(anim.csCursorVisibility.get(currentTime) && (currentTime % sf::seconds(1.5f) < sf::seconds(0.9f)));
anim.csCursorVisibility is an animation track that allows the cursor to be switched on and off depending on the current time in the animation. This line, then, flashes the cursor only when the cursor should be visible.
Actually, the Console Screen is technically drawn onto a render texture and then that texture is drawn to the window using a sprite; we use a Sprite 3D to achieve this.
CubeThe Console screen persists from the loading intro but the palette colours are changed. The Sprite 3D is animated to rotate to look like a cube. There are two Sprite 3Ds here, both using the same texture (from the render texture of the Console Screen) so both (seemingly all) faces of the "cube" are identical. As one face becomes completely obscured by the other, it effectively rotates 180° to continue as the next face. The Sprites are darkened based on their angle away from the "camera" to give some impression of 3D lighting.
There are also 7 Splines that have their vertices and (Bezier) handles animated based sinusoidally (a recurring technique in this animation). The vertices are equally spaced horizontally; only the y position of the vertices and handles are animated.
The Starfield, which is drawn behind everything else, is constantly moved left to give the impression of travelling to the right.
The "flashes" that match the music are only the window's background colour.
When the "yellow flashes" occur, the colour of the Splines transition from yellow/red-based to blue-based while the palette colour of the Console Screen that fills most of the screen changes from blue to red.
The phrase "Check in to check it out" shown on the Console Screen is output to the screen's stack cells. These particular cells are "on top" of the standard cells so are always displayed above them.
The entire screen is scrolled so that the title is at the top, scrolling the URL off the top. Note that stack cells don't scroll.
At the beginning of the animation, a buffer is prepared from a bit pattern for the block logo. This is made up of quarter cell blocks to display a mosaic logo. This is pasted at different positions on the screen so it can scroll onto the screen.
The title is scrolled left (just the top section is scrolled now, not the entire screen), wrapping from one side to the other. This gives the impression that the logo moves from one face to the next.
The "police line" row is flashed by animating the inverse attribute of that row (in a similar way to animating the flashing cursor):
cs << Cs::Begin;
if (currentTime % sf::seconds(1.2f) < sf::seconds(0.5f))
cs << Cs::CellAttributes(Cs::Affect::Inverse) << Cs::Affect::Inverse;
else
cs << Cs::CellAttributes(Cs::Affect::None) << Cs::Affect::Inverse;
cs << csFlashLineLocation << Cs::Wipe(textFlashLine.size());
cs << Cs::End;
ScrollerThe Console Screen (and its Sprite 3D, although only one is used now) persists through this section as well. The palette is manipulated so that the colours that were shown are now all transparent except the title's text.
The Starfield persists too but is now moved in the opposite direction (but slows down toward the end).
The VU meters are three Progress Bars. The one on the left represents the left channel, the one on the right represents the right channel and the central one represents both. This is why the centre bar is always higher than both. The progress bar is "rounded" to one of the blocks so that it doesn't "light up" only half of a single light block.
The meters themselves use the actual music as input and the result is based on the music's current decibel level, not just its peak or even its RMS. To allow simpler access to the music's samples for this, the music is loaded as a sound buffer and played as a sound, rather than opened and streamed using sf::Music.
The scrolling text is a single Bitmap Text object that is just moved to scroll. The Bitmap Font used is customised to allow features like hanging letters (e.g. g, j, y) without increasing the entire cell for each character/glyph, different widths (e.g. l, i, j are thinner) and kerning (e.g. capital t followed by lower-case e "Te" are closer together).
SnakeThe Starfield is now moved upwards (quite quickly) to the impression of moving downwards (quickly, similar to falling).
The "snake" here is a group of Rings that use the same motion paths. They differ their position on the path but the path used is the same. The path and the positions for each ring are sinusoid-based.
The texture used for the Rings is multi-coloured but not very saturated so that all of the colours still exist. For the first half of the snake section, the rings are coloured (multiplied by a colour) by a rainbow of colours. This gives each Ring a different base colour.
The Rings are drawn in the same order each time. The "back" ones (the ones drawn first) are slighly smaller to give the impression of depth. The "front" Ring has the entire ring segment and each ring behind it has a little less segment. Each ring is also rotated clockwise a little more than the one in front of it to give it a "corkscrew" look, although all rings are also being rotated constantly together as well.
The "hole" of all of the Rings are animated together to match the music in the first half of the snake section.
In the second half of the snake section, however, things are different...
The holes are no longer animated but the scale of the Rings are now animated to follow the beat of the music.
The segments of all of the rings are now animated similarly to the scale to follow the beat of the music. At their largest scale, the segments are as they were in the first half but at their smallest scale, the segments have a further 90° of the ring removed.
The colours of the Rings are now all set to white so that the original "pastel rainbow" texture can be seen on each ring. This gives each ring multiple colours. Note that because of the "corkscrew rotation", the colours also follow that look.
The asteroid that is introduced in this section is drawn using a Gallery Sprite, which just has its y position moved until it "collides" in the next section while it is just rotated.
The "snake" is moved off the top of the screen before the next section.
RocketA 2D side-scroller-style map using Tile Map then moves onto the screen quickly until the asteroid collides with it. At which point, the map, the asteroid, the stars, the rocket (a Gallery Sprite) and the rocket stand/astronaut animation (also a Gallery Sprite) all cease motion.
The asteroid's explosion is a Gallery Sprite that plays through its "exhibits" (or animation frames). The asteroid is removed when the explosion is large.
After the explosion has happened, the astronaut animation shows a door opening in a wall and a character jumping from it to the rocket's ladder. The ladder is then closed into the rocket and the door on the wall is closed. This is a frame animation and uses a Gallery Sprite. The frame durations are not equal; Plinth allows each frame of a Frame Animation to have its own duration. This allows delays on a single frame and some animation sections to have differing frame rates - as this animation does.
Following the astronaut's boarding the rocket, the rocket takes off. The rocket is a Gallery Sprite with 4 exhibits: 1 that is just the rocket and 3 of the rocket with propulsion flames that can be cycled for an animated flame. Note that the rocket is clearly drawn behind the Tile Map so that the flames don't appear over the map.
The rocket is then rotated to fly to the right and the Tile Map's camera is moved to the right (along with the stars being moved to the left) so that the level is scrolled to the left.
Note that there is, in fact, two Tile Maps here: the main "grey" one and a secondary, slightly smaller, bluer one behind it. The idea behind that was to create some depth but it ended up not being very noticeable.
The UI of the "side-scroller" is then scrolled into view. The texts are Bitmap Texts (using the same Bitmap Font as the scroller) and Progress Bars. Fuel and Power are simple coloured bars on coloured backgrounds but the Life bar is a texture bar. The texture is the width of a single "heart" image and contains only a full heart and an empty heart below it. The texture is repeated so that multiple heart can be seen by using a texture rectangle that passes the boundaries of the texture.
As the rocket moves up and down, the Tile Map camera is also moved up and down and the stars are moved accordingly.
The rocket's "laser" is just a Line. That is, it is a thick, textured Line. Whenever the laser is fired, "Power" is reduced by a small amount.
The level's "defence guns" are static level tiles and the level data is manipulated when they change to "damaged" (by changing the value of that tile). Similarly, the "barrier" that is shot away is a static level tile that is changed to a blank tile.
Since there is never more than one explosion on the screen at any one time, the same explosion Gallery Sprite is re-used for each explosion.
When the rocket "escapes the confines of the side-scroller to become a top-down scroller, the rocket is scaled up to show that it is now above the map. After leaving the map, however, it "drops" back down (scales down) to begin the vertical shooter-style section. The Starfield is moved downwards for this section.
The enemy ships are all Gallery Sprites. The enemies have animations for each gun firing. The actual enemy shot, though, is a thick, solid colour, Line.
For the "hyperspace" animation, multiple Lines are used. All lines are actually really long and just scrolled onto the screen together. The Starfield is removed too at this point.
WalkFollowing the "clear white" of the hyperspace, the white is removed to reveal a walk animation on a coloured background. The character walking is a Gallery Sprite cycling through an 8-exhibit animation (in time with the music). The animation is "zoomed in" quite extremely and then zoomed back out to reveal lots of similar walking animations.
The "spiky" animation in the centre here is a Pie Chart. Each slice is "exploded" (pushed out from the centre) by a different amount based on - you guessed it - a sinusoid.
The floor here is made up of two separate things: a Ring and a Line.
The thick Line is the straight floor and the Ring segment is the curved part of the floor. As the floor moves, the Ring segment increases and the Line is reduced. The texture rectangle are adjusted to match their positions.
The characters walk along the straight floor and then up the curved (actually circular) floor. The floor moves to be a full Ring. At this point, the Line is no longer used.
Next, the Pie Chart's explosions are stopped as the characters have their heights scaled in a sinusoidal pattern. This scaling is to how the characters are clearly anchored to the floor. Technically, the "origin" of the Gallery Sprite is still at (0, 0). This is because each exhibit can have its own anchor point, which, in this case, is where the floor would be.
After some rotations of everything, the Pie Chart explosions return and the characters' heights are restored to normal just before "rolling" the entire thing off the screen.
CreditsThe credits section uses the Nine Patch to display a strechable rectangle. Note that the corners are always the same size; it's the rest of the image that is stretched.
The Console Screen returns for this section. Its size and position is determined by the rectangle returned by the Nine Patch's "content area".
The screenshots gallery shown on the right use a Gallery Sprite. All of the screenshots are contained on one texture and the Gallery Sprite moves through those exhibits. It fades in and out and scales in and out for each screenshot.
The shadow on the Console Screen is created by copying the screen into a buffer, changing all of the colours in the buffer to be "shadow black" (black with some transparency) for the foreground and completely transparent for the background. The buffer is then pasted onto the stack (the "under" stack) so that it is shown below all of the standard cells. Stack cells can also have their position offsets so that allows the shadow's offset.
Note that this animation does not do this effect particularly efficiently. These shadows are created on every frame; that is, the entire screen is copied, manipulated, pasted and the buffer and all of the stack are both removed constantly. It would have been better to have done this only when the screen actually changes or, better still, use either a texture that contains the shadow or use a shader. However, this was done to make use of the "under stack" and its ability to be shown under the standard cells as well as having positional offsets (which is why the bespoke texture and shader techniques weren't used).
Console Screen's crash method was used for the crash screens. During those "crashes", the Nine Patch is faded out.
The final display on the Console Screen is the block/mosaic logo that was used earlier on the "cube" section. This time, however, the shadow is still being created so the logo has a bit more detail.
FinallyIn this post, I have attempted to explain which Selba Ward object was used for which task and how it was used to achieve that particular effect. There was not much actual code shown here as most of the things done are controlled by
Plinth's animation tracks and the actual main code is not organised well. However, there should be the information you need to understand what it going on and if you use the objects, you should be able to perform these tasks.
If there is anything you would like me explain in more detail, something you don't understand or just any questions about Selba Ward or the demo animation or its resources, feel free ask on this thread.
For more information, you can read the
Selba Ward wiki.