Module: Zif::Actions::Animatable

Included in:
Sprite
Defined in:
lib/zif/actions/animatable.rb

Overview

A mixin to assist with sprite animations, to use with an object which already includes Actionable. Under the hood, these are implemented as Sequences which modify the path over time.

Instance Attribute Summary collapse

1. Public Interface collapse

Instance Attribute Details

#animation_sequencesHash<(String, Symbol), Zif::Actions::Sequence> (readonly)

Returns Registered sequences by name.

Returns:



7
8
9
# File 'lib/zif/actions/animatable.rb', line 7

def animation_sequences
  @animation_sequences
end

#cur_animationString, Symbol (readonly)

Returns Name of last run animation sequence.

Returns:

  • (String, Symbol)

    Name of last run animation sequence.



10
11
12
# File 'lib/zif/actions/animatable.rb', line 10

def cur_animation
  @cur_animation
end

Instance Method Details

#new_basic_animation(named:, paths_and_durations:, repeat: :forever, &block) ⇒ Object

Creates and registers a new Sequence named named to animate across the paths_and_durations array

Examples:

Register the animation for a flying Dragon (dragon here is a Sprite or any Zif::Actions::Animatable) class


dragon.new_basic_animation(
  named: :fly,
  paths_and_durations: [
    ["dragon_1", 4], # This animation has 4 separate images, we go from 1 to 4 and then back to 1
    ["dragon_2", 4], # Hold each frame for 4 ticks
    ["dragon_3", 4], # The actual image exists at: app/sprites/dragon_3.png
    ["dragon_4", 4], # Frames 1 and 4 aren't duplicated in the sequence, so it's a fluid motion
    ["dragon_3", 4],
    ["dragon_2", 4]  # By default this repeats forever, which takes it back to 1
  ]
)

# We don't have to register this sequence manually using #register_animation_sequence, the #new_basic_animation
# method takes care of that for us.

# So now we can run this animation:
dragon.run_animation_sequence(:fly)

Parameters:

  • named (String, Symbol)

    The name of the sequence, used when calling #run_animation_sequence

  • paths_and_durations (Array<Array<String, Integer>>)

    The frames of the animation. Each element in this array should be like [“some_path”, 4] where “some_path” is the path of the frame png image like “sprites/#{some_path}.png”, and the integer is the duration in ticks it should be held for.

  • repeat (Integer, Symbol) (defaults to: :forever)

    (see Zif::Actions::Action::REPEAT_NAMES for valid symbols)

  • block (Block)

See Also:



45
46
47
48
49
50
# File 'lib/zif/actions/animatable.rb', line 45

def new_basic_animation(named:, paths_and_durations:, repeat: :forever, &block)
  actions = paths_and_durations.map do |(path, duration)|
    new_action({path: "sprites/#{path}.png"}, duration: duration, easing: :immediate, rounding: :none)
  end
  register_animation_sequence(named: named, sequence: Sequence.new(actions, repeat: repeat, &block))
end

#new_tiled_animation(named:, path:, width:, height:, durations:, repeat: :forever, &block) ⇒ Object

Similar to new_basic_animation, but for a tiled animation. Use this function when you have a single image with multiple tiles, and you want to animate across them, rather than a separate image per animation frame.

This helper assumes that the spritesheet image is laid out in a single row of tiles, each of the same size and with no spacing/padding between them.

Parameters:

  • named (String, Symbol)

    The name of the sequence, used when calling #run_animation_sequence

  • path (String)

    the path to the spritesheet image.

  • width (Integer)

    The width of each tile in the spritesheet.

  • height (Integer)

    The height of each tile in the spritesheet.

  • durations (Array<Integer>)

    The duration in ticks of each tile in the spritesheet. Can be either :tile or :source, and will target props _x, _y, _w and _h. Defaults to :tile.

  • repeat (Integer, Symbol) (defaults to: :forever)

    (see Zif::Actions::Action::REPEAT_NAMES for valid symbols)

  • block (Block)

See Also:



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/zif/actions/animatable.rb', line 68

def new_tiled_animation(named:, path:, width:, height:, durations:, repeat: :forever, &block)
  actions = durations.map_with_index do |duration, tile_index|
    new_action(
      {
        path:     "sprites/#{path}.png",
        source_x: 0 + (tile_index * width),
        source_y: 0,
        source_w: width,
        source_h: height
      },
      duration: duration,
      easing:   :immediate,
      rounding: :none
    )
  end
  register_animation_sequence(named: named, sequence: Sequence.new(actions, repeat: repeat, &block))
end

#register_animation_sequence(named:, sequence:) ⇒ Object

Manually register an animation sequence. If you need more control over your Sequence than #new_basic_animation provides, you can create it manually, and then register it here.

Parameters:



91
92
93
94
95
96
# File 'lib/zif/actions/animatable.rb', line 91

def register_animation_sequence(named:, sequence:)
  # puts "Registering animation #{named} with repeat #{sequence.repeat}"

  @animation_sequences ||= {}
  @animation_sequences[named] = sequence
end

#run_animation_sequence(name) ⇒ Object

Run an animation sequence which has been previously registered. Since animations are mutually exclusive, this will #stop_animating any previously running animation. It will also reset the progress of the current action on the invoked sequence.

Parameters:

  • name (String, Symbol)

    The name of the sequence to run.

Raises:

  • (ArgumentError)

See Also:



103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/zif/actions/animatable.rb', line 103

def run_animation_sequence(name)
  raise ArgumentError, "No animation sequence named '#{name}' registered" unless @animation_sequences[name]

  stop_animating

  @cur_animation = name
  @animation_sequences[@cur_animation].restart
  @animation_sequences[@cur_animation].setup_action
  # puts "Running animation sequence #{@cur_animation} #{@animation_sequences[@cur_animation].inspect}"

  run_action(@animation_sequences[@cur_animation])
end

#stop_animatingObject

Stop the current animation.



117
118
119
120
121
122
# File 'lib/zif/actions/animatable.rb', line 117

def stop_animating
  return unless @cur_animation && @animation_sequences && @animation_sequences[@cur_animation]

  # puts "Stopping animation #{@cur_animation} -> #{@animation_sequences[@cur_animation]}"
  stop_action(@animation_sequences[@cur_animation])
end