Module: Chingu::Traits::Timer

Defined in:
lib/chingu/traits/timer.rb

Overview

A chingu trait providing timer-methods to its includer, examples:

during(300) { @color = Color.new(0xFFFFFFFF) }   # forces @color to white ever update for 300 ms
after(400) { self.destroy! }                     # destroy object after 400 ms
between(1000,2000) { self.rotate(10) }           # starting after 1 second, call rotate(10) each update during 1 second

All the above can be combined with a ‘then { do_something }’. For example, a classic shmup damage effect:

during(100) { @color.alpha = 100 }.then { @color.alpha = 255 }

Instance Method Summary collapse

Instance Method Details

#after(time, options = {}, &block) ⇒ Object

Executes block after ‘time’ milliseconds



62
63
64
65
66
67
68
69
70
# File 'lib/chingu/traits/timer.rb', line 62

def after(time, options = {}, &block)
  return if timer_exists?(options[:name]) && options[:replace] == false
  stop_timer(options[:name])

  ms = Gosu::milliseconds()
  @_last_timer = [options[:name], ms + time, nil, block]
  @_timers << @_last_timer
  self
end

#between(start_time, end_time, options = {}, &block) ⇒ Object

Executes block each update during ‘start_time’ and ‘end_time’



75
76
77
78
79
80
81
82
83
# File 'lib/chingu/traits/timer.rb', line 75

def between(start_time, end_time, options = {}, &block)
  return if timer_exists?(options[:name]) && options[:replace] == false
  stop_timer(options[:name])

  ms = Gosu::milliseconds()
  @_last_timer = [options[:name], ms + start_time, ms + end_time, block]
  @_timers << @_last_timer
  self
end

#during(time, options = {}, &block) ⇒ Object

Executes block each update during ‘time’ milliseconds



49
50
51
52
53
54
55
56
57
# File 'lib/chingu/traits/timer.rb', line 49

def during(time, options = {}, &block)
  return if timer_exists?(options[:name]) && options[:replace] == false
  stop_timer(options[:name])

  ms = Gosu::milliseconds()
  @_last_timer = [options[:name], ms, ms + time, block]
  @_timers << @_last_timer
  self
end

#every(delay, options = {}, &block) ⇒ Object

Executes block every ‘delay’ milliseconds



88
89
90
91
92
93
94
# File 'lib/chingu/traits/timer.rb', line 88

def every(delay, options = {}, &block)
  return if timer_exists?(options[:name]) && options[:replace] == false
  stop_timer(options[:name])
  
  ms = Gosu::milliseconds()
  @_repeating_timers << [options[:name], ms + delay, delay, block]
end

#setup_trait(options) ⇒ Object



36
37
38
39
40
41
42
43
44
# File 'lib/chingu/traits/timer.rb', line 36

def setup_trait(options)        
  #
  # Timers are saved as an array of arrays where each entry contains:
  # [name, start_time, end_time (or nil if one-shot), &block]
  #
  @_timers = Array.new
  @_repeating_timers = Array.new
  super
end

#stop_timer(name) ⇒ Object

Stop timer with name ‘name’



120
121
122
123
# File 'lib/chingu/traits/timer.rb', line 120

def stop_timer(name)
  @_timers.reject! { |name, start_time, end_time, block| name == name }
  @_repeating_timers.reject! { |name, start_time, end_time, block| name == name }
end

#stop_timersObject

Stop all timers



128
129
130
131
# File 'lib/chingu/traits/timer.rb', line 128

def stop_timers
  @_timers.clear
  @_repeating_timers.clear
end

#then(&block) ⇒ Object

Executes block after the last timer ends …use one-shots start_time for our trailing “then”. …use durable timers end_time for our trailing “then”.



101
102
103
104
# File 'lib/chingu/traits/timer.rb', line 101

def then(&block)
  start_time = @_last_timer[2].nil? ? @_last_timer[1] : @_last_timer[2]
  @_timers << [@_last_timer[0], start_time, nil, block]
end

#timer_exists?(timer_name = nil) ⇒ Boolean

See if a timer with name ‘name’ exists

Returns:

  • (Boolean)


110
111
112
113
114
115
# File 'lib/chingu/traits/timer.rb', line 110

def timer_exists?(timer_name = nil)
  return false if timer_name.nil?
  @_timers.each { |name, | return true if timer_name == name }
  @_repeating_timers.each { |name, | return true if timer_name == name }
  return false
end

#update_traitObject



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/chingu/traits/timer.rb', line 133

def update_trait
  ms = Gosu::milliseconds()
  
  @_timers.each do |name, start_time, end_time, block|
    block.call  if ms > start_time && (end_time == nil || ms < end_time)
  end
          
  index = 0
  @_repeating_timers.each do |name, start_time, delay, block|
    if ms > start_time
      block.call  
      @_repeating_timers[index] = [name, ms + delay, delay, block]
    end
    index += 1
  end

  # Remove one-shot timers (only a start_time, no end_time) and all timers which have expired
  @_timers.reject! { |name, start_time, end_time, block| (ms > start_time && end_time == nil) || (end_time != nil && ms > end_time) }

  super
end