Skip to content
burtlo edited this page Nov 26, 2012 · 2 revisions

Animations

Overview

Metro provides an implicit property animation system or key frame animations. This is similar to those familiar with iOS development or those that have used animations within jQuery.

Animations can be defined for Models within Scenes. The animation is defined with the model and the proposed final value of the model property over a given interval of time.

Defining an animation

A scene has a number of helper methods (animate and change) that allow you to quickly add animations within your scene.

A scene's ability to register animations is because a Scene includes the model HasAnimations which extends the ClassMethods.

Example

This is an example of animation which fades out (i.e. Setting the alpha property to 0) over 120 ticks of the game:

class HellScene < GameScene

  draw :title, model: 'metro::ui::label',
    text: 'Welcome To Hell!',
    position: "320,240,0",
    color: "rgba(255,255,255,1.0)"

  animate :title, to: { alpha: 0 }, interval: 120.ticks do
    puts "Title is now faded."
  end
end

Properties

When defining an animation a hash of properties are provided. An important key is to: which defines another hash.

The to hash's keys are the names of properties on the actor. The to hash's values are the final value to set the property.

Any property of the actor can be animated. A property can be model properties but more simply it is any name which matches a getter and setter on the actor. Multiple properties of an actor can also be animated at the same time.

Here we define a scene which will move the hero to a position while rotating them:

class Hero < Metro::Model
  property :location

  attr_accessor :angle

  def after_initialize
    @angle = 0
  end

  # ... a draw method which draws our hero at the location and angle
end

class MovieScene < GameScene

  draws :hero

  animate :hero, to: { x: 320, y: 240, angle: 180 }, interval: 2.seconds

end

NOTE: The angle attr_accessor is a situation better suited for a property. A getter and setter is used here to illustrate that animations simply require getter and setter methods on the actor's model.

Interval

Each animation must provide an interval to perform the animation. Metro provides some additional functionality on Numeric instances to assist with providing more clarity when expressing the interval.

By default the interval, without a suffix, is expressed in game ticks.

Easings

Every animation may also be defined with a different easing value. An easing allows you to effect subtly affect the way in which the final result is reached. By default the defined easing is linear.

Linear

An animation will by default use a linear easing.

This example we explicitly specify the easing, even though the default is already linear:

class MovieScene < GameScene

  draws :hero

  animate :hero, to: { x: 320, y: 240, angle: 180 },
    interval: 2.seconds, easing: :linear

end

Ease In

Metro defines 'Ease In' easing.

This example we specify that the animation should be performed with ease in.

class MovieScene < GameScene

  draws :hero

  animate :hero, to: { x: 320, y: 240, angle: 180 },
    interval: 2.seconds, easing: :ease_in

end

Defining a Custom Easing

Metro allows you define a custom easing. An easing is any class that adheres to the following interface:

class CustomEasing < Metro::Easing

  #
  # @param [Float] moment the point in time within the interval. For example for
  #   a 60 tick interval, this would be the values 0, 1, 2, 3, 4, 5, 6, ... 59.
  # @param [Float] start the starting value of the property
  # @param [Float] change the final value for the property
  # @param [Float] interval the total length of the interval
  #
  # @return [Float] the value at the particular moment of the interval
  def self.calculation(moment,start,change,interval)
    # this is the exact same as a linear calculation
    change * moment / interval + start
  end
end

Metro::Easing.register :custom, CustomEasing

An example of using the newly defined custom easing in an animation:

class MovieScene < GameScene

  draws :hero

  animate :hero, to: { x: 320, y: 240, angle: 180 },
    interval: 2.seconds, easing: :custom

end
Clone this wiki locally