CPAnimation

abstract class CPAnimation(id: String) extends CPGameObject with CPAsset

Definition of the animation.

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 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.

Animation is an asset. Just like other assets such as images, sounds, fonts or videos they are not managed or governed by the CosPlay game engine unlike scenes and scene objects 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.

Class CPAnimationSprite provides convenient built-in support for animation-driven sprites. In most cases you will to use or extend this sprite class to work with this animation.

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

Refresh Rate

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. When used properly and consistently it can result in a unique 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

This is a classic sprite animation technique 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 effect 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 model and 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.

Value parameters:
id

Unique ID of the animation.

See also:

CPAnimationSprite for the built-in sprite that works with this animation.

Example:

See CPAnimationExample source code for an example of animation functionality.

Companion:
object
Source:
CPAnimation.scala
trait CPAsset
class Object
trait Matchable
class Any

Value members

Abstract methods

Gets number of key frames in this animation.

Gets number of key frames in this animation.

Source:
CPAnimation.scala

Gets a key frame for a given animation context.

Gets a key frame for a given animation context.

This is the "brains" of the animation. Given the animation context, that provides access to the state of the game as well as the information about sprite that is rendering this animation, this method should return an appropriate key frame.

Returning None will result in not showing any image in the current game frame, effectively hiding the sprite that is rendering this animation (this is the behaviour of CPAnimationSprite). Returning Some will result in rendering key frame's image by the sprite. Note that this method may return the same key frame throughout multiple calls indicating that the same image should be rendered over consecutive game frames.

See factory methods in the companion object CPAnimation.timeBased and CPAnimation.filmStrip that create animations with frequently used strategies.

Value parameters:
ctx

Animation context.

Returns:

Key frame for given context or None if one isn't available. None should typically be returned when you want to stop and hide the animation. Note that this method may return the same key frame throughout multiple calls indicating that the same image should be rendered over consecutive game frames.

See also:
Source:
CPAnimation.scala
def reset(): Unit

Resets this animation to its initial state.

Resets this animation to its initial state.

Source:
CPAnimation.scala

Concrete methods

Shortcut method that checks if given key frame is the first one in the sequence.

Shortcut method that checks if given key frame is the first one in the sequence.

Value parameters:
kf

Key frame to check. Note that this key frame must belong to this animation.

Source:
CPAnimation.scala

Shortcut method that checks if given key frame is the last one in the sequence.

Shortcut method that checks if given key frame is the last one in the sequence.

Value parameters:
kf

Key frame to check. Note that this key frame must belong to this animation.

Returns:

true if it is indeed the last key frame, false otherwise.

Source:
CPAnimation.scala

Inherited methods

override def equals(obj: Any): Boolean
Definition Classes
Inherited from:
CPGameObject
Source:
CPGameObject.scala
def getId: String

Gets unique ID of this game object.

Gets unique ID of this game object.

Inherited from:
CPGameObject
Source:
CPGameObject.scala
def getTags: Set[String]

Gets optional set of organizational tags. Note that by default the set of tags is empty.

Gets optional set of organizational tags. Note that by default the set of tags is empty.

See also:
Inherited from:
CPGameObject
Source:
CPGameObject.scala

Concrete fields

override val getOrigin: String

Gets the origin of this asset. Typically, this should be a URL, file name or class name for in-code assets like array images, animations or system font.

Gets the origin of this asset. Typically, this should be a URL, file name or class name for in-code assets like array images, animations or system font.

Source:
CPAnimation.scala