• Docs
  • Install
  • Follow @cosplayengine
  • v.0.8.8
  • GitHub
  • Watch
  • Examples
  1. Home
  2. Sprite Animation

Sprite Animation

  • Introduction
  • Install
  • ASCII Games
  • Demos
  • Examples
  • Macarena
  • Pong
  • Snake
  • Bird
  • Developer Guide
  • Quick Game 🏃
  • Key Concepts
  • Game Structure
  • Scenes & Objects
  • Log & Debugging
  • Pixels & Colors
  • Images
  • Keyboard Input
  • Sprite Animation
  • Shaders
  • Particle Effects
  • Fonts
  • Canvas Drawing
  • Text Input
  • Camera Tracking
  • Tile Mapping
  • Audio
  • Video
  • Build & Run

Sprite Animation

In CosPlay, sprite animation is supported by the following classes:

  • CPAnimation - animation descriptor.
  • CPAnimationKeyFrame - an animation key frame.
  • CPAnimationContext - animation context that is passed to CPAnimation.getKeyFrame(ctx) method.
  • CPAnimationSprite - sprite that ties all this together.

Animation is defined as a sequence of key frames. Each key frame has an image and the index of its position in the sequence of key frames. Animation produces a key frame given animation context via method CPAnimation.keyFrame(). Note that animation definition is abstracted out from the way it is rendered. The same animation can be rendered differently.

One such rendering is implemented by the built-in sprite CPAnimationSprite class. Class CPAnimationSprite provides convenient built-in support for rendering the animation. Unless you need some very specific rendering implementation - you will use or extend this sprite class to work with the animation.

Animation Is An Asset

Just like other assets such as CPFont, CPImage, CPParticleEmitter, CPShader or CPVideo they are not managed or governed by the CosPlay game engine unlike scenes and scene object, that are managed and governed by the game engine. Assets are typically created outside the game loop and managed by the developer, they can be freely shared between scenes or scene objects as any other standard Scala objects.

Note that CPAnimation companion object provides factory methods that produce often used types of animation:

  • CPAnimation.timeBased() - creates new time-based animation. Time-based animation is based on idea that animation is a sequence of image and duration pairs. Playing such animation simply means sequentially playing and image for its specified duration and then switching to the next pair and repeating the same process.

  • CPAnimation.filmStrip() - creates new filmstrip animation. Filmstrip animation is a variation of time-based animation where all key frames have the same duration, like in a movie, hence the name.

Here's a code snippet from the built-in Animation Example that demonstrates the basic usage of animation functionality:

            // Create key frames for animation.
            val imgVert = new CPArrayImage(
                prepSeq(
                    """
                      |   o/
                      |  /|
                      |  / \
                      |------
                      |   o)
                      |  /|
                      |  ( \
                      |------
                      |  (o
                      |   |\
                      |  / )
                      |------
                      |  \o
                      |   |\
                      |  / \
                      |------
                    """).filter(!_.endsWith("------")
                ),
                skin).split(5, 3)

            // Animation descriptor.
            val vertAni = CPAnimation.filmStrip("vert", 150, imgs = imgVert)

            // Animated player sprite.
            val player = new CPAnimationSprite("player", Seq(vertAni), 45, 19, 0, "vert") {
                ...
            }
        

NOTES:

  • On line 2 we create a sequence of images that will act as key frames for our vertical animation.
  • On line 26 we use factory method to create basic filmstrip animation using the key frame images we just created.
  • On line 29 we create player sprite with animation we created above. Look at Animation Example to see a full code with multiple animations.

The Animation Example looks like this:

Prefab Animations

CosPlay comes with several prefab images that can be used in animation. These images are located in org.cosplay.prefabs.images.ani package. Note that you can preview these images as animation using built-in animation previewer CPImage.previewAnimation(...) method.

Refresh Rate & "Rolling Shutter"

Even though CosPlay's effective FPS is usually around 1,000 on modern computers, the typical ANSI terminal struggles to render a full screen update even at partly 30 FPS. Large frame updates tend to result in "rolling shutter" effect, which is pronounced more for certain shapes and certain movement directions. It is important to note that this effect is more pronounced for horizontal movement of large vertical shapes. Try to avoid this type of movement in your games.

Discrete Animation

It should come as no surprise that animation in ANSI terminal can only happen in one character units. You can't move by individual pixel - you only move by 10-20 pixel at a time depending on the font size used by your terminal. Even the specific font size is not directly available to the native ASCII game.

Discrete animation is obviously more jerky and more stuttering comparing to the pixel-based animation of the traditional graphics games. Vertical movement is more jerky than horizontal one since character height is usually larger than the character width (and we can move only a one character at a time).

There are two ways to mitigate this limitation:

  • Use smaller shapes for animation, prefer horizontal movement, and avoid prolong movements.
    • "Rolling shutter" effect does not happen on each frame (more like every 20-40 frames) and so shorter animation sequences have a lesser chance of encountering this effect.
  • Use discrete animation as an artistic tool for the striking visual design of the game.

Different Ways To Animate

In CosPlay there are different ways one could implement animated scene objects. In the end, all of these approaches deliver similar results but each individual technique is tailor-made for a specific animation type:

  • Animated Sprites
  • Particle Effects
  • Canvas Drawing
  • Video Sprites
  • Shaders

Animated Sprites

The classic sprite animation technique (discussed in this section) ideally suited for animations that can be defined as a sequence of individual similarly or identically sized images. When played, each individual images is shown for a short period of time one after another delivering animation effect.

Lets consider an animation of the airplane in a top-down view game play. The basic animations for the airplane banking left or right, taking off or landing are ideally suited for sprite-based animation as they can easily be defined as a short sequence of individual images.

Particle Effects

Particle Effects animation is based on the concept of a pixel-based particle and particle emitter. Particle emitter emits particles. Each particle and its emitter have a fully programmable behavior. The key characteristic of particle effect animation is the randomness over the large number of individual elements that you can easily implement using fully programmable particles and emitters.

In our airplane example, lets consider how one could implement the explosion when the airplane is hit with the missile. One could potentially implement such animated explosion as a long sequence of images but such process would be very tidies and lack the desired randomness. Particle effect-based animation fits the bill perfectly in such cases allowing to implement such random explosion animation in just a few lines of code.

Canvas Drawing

Sometime, a simple drawing on the canvas is all that's needed for a desired animation. Consider how one could implement a laser strike in our airplane example. A laser strike can be defined as a variable length line of pixel shown for a split second. The best way to implement it is with one line of code using many of the drawing functions in CPCanvas class and putting this logic into CPSceneObject.render() method.

Video Sprites

Video sprite is a variation of sprite-based animation. In case of video, there are typically a lot more frames (often 1000s of frames) and all these frames have the same dimension. CPVideo and CPVideoSprite provide easy-to-use mechanism to implement it. Back to our airplane example, the video-based animation would be ideal choice for the cutscenes, entry video, etc.

Shaders

Shader is a piece of user-defined code that is executed on each frame for each scene object that has one or more shaders attached to it. There are types of animations that simply don't fit any previous type. The typical example of shader-based animation is the various lighting effect: flash-lite, sun shadows, transitions, highlighting, etc. These types of animation simply cannot be reasonably implemented using sprites, or particles, or canvas drawing. In such cases, shaders provide simple and effective contract to implement this behavior. Yet another unique characteristic of shaders is their application reusability. In fact, the same shader can be added to multiple scene objects to provide its effect.

In our airplane example, shaders can be used for shadow effect or "flashing" the airplane when it is hit by the enemy fire.

  • On This Page
  • Sprite Animation
  • Prefab Animation
  • Refresh Rate
  • Discrete Animation
  • Ways To Animate
  • Example
  • Animation Example
  • Quick Links
  • Discord
  • Stack Overflow
  • GitHub
  • @cosplayengine
  • YouTube
  • API
Copyright © 2023 Rowan Games, Inc. Privacy • Docs release: 0.8.8 Latest: