adventure_rl 0.0.1.pre.ld42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +12 -0
  5. data/Gemfile.lock +47 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +31 -0
  8. data/Rakefile +11 -0
  9. data/adventure_rl.gemspec +48 -0
  10. data/bin/console +7 -0
  11. data/bin/mkaudio +196 -0
  12. data/bin/mkclip +223 -0
  13. data/bin/rdoc +9 -0
  14. data/bin/setup +8 -0
  15. data/bin/vimall +5 -0
  16. data/doc/Mask.md +183 -0
  17. data/doc/Point.md +95 -0
  18. data/doc/Window.md +139 -0
  19. data/lib/AdventureRL/Animation.rb +63 -0
  20. data/lib/AdventureRL/Audio.rb +75 -0
  21. data/lib/AdventureRL/AudioPlayer.rb +65 -0
  22. data/lib/AdventureRL/Button.rb +51 -0
  23. data/lib/AdventureRL/Clip.rb +91 -0
  24. data/lib/AdventureRL/ClipPlayer.rb +187 -0
  25. data/lib/AdventureRL/Deltatime.rb +51 -0
  26. data/lib/AdventureRL/EventHandlers/Buttons.rb +225 -0
  27. data/lib/AdventureRL/EventHandlers/EventHandler.rb +62 -0
  28. data/lib/AdventureRL/EventHandlers/MouseButtons.rb +142 -0
  29. data/lib/AdventureRL/Events/Event.rb +69 -0
  30. data/lib/AdventureRL/Events/Mouse.rb +60 -0
  31. data/lib/AdventureRL/FileGroup.rb +100 -0
  32. data/lib/AdventureRL/FileGroupPlayer.rb +226 -0
  33. data/lib/AdventureRL/Helpers/Error.rb +68 -0
  34. data/lib/AdventureRL/Helpers/MethodHelper.rb +20 -0
  35. data/lib/AdventureRL/Helpers/PipeMethods.rb +26 -0
  36. data/lib/AdventureRL/Image.rb +77 -0
  37. data/lib/AdventureRL/Layer.rb +273 -0
  38. data/lib/AdventureRL/Mask.rb +462 -0
  39. data/lib/AdventureRL/Menu.rb +92 -0
  40. data/lib/AdventureRL/Modifiers/Gravity.rb +60 -0
  41. data/lib/AdventureRL/Modifiers/Inventory.rb +104 -0
  42. data/lib/AdventureRL/Modifiers/Pusher.rb +61 -0
  43. data/lib/AdventureRL/Modifiers/Solid.rb +302 -0
  44. data/lib/AdventureRL/Modifiers/Velocity.rb +163 -0
  45. data/lib/AdventureRL/Point.rb +188 -0
  46. data/lib/AdventureRL/Quadtree.rb +237 -0
  47. data/lib/AdventureRL/Rectangle.rb +62 -0
  48. data/lib/AdventureRL/Settings.rb +80 -0
  49. data/lib/AdventureRL/SolidsManager.rb +170 -0
  50. data/lib/AdventureRL/Textbox.rb +195 -0
  51. data/lib/AdventureRL/TimingHandler.rb +225 -0
  52. data/lib/AdventureRL/Window.rb +152 -0
  53. data/lib/AdventureRL/misc/extensions.rb +80 -0
  54. data/lib/AdventureRL/misc/require_files.rb +45 -0
  55. data/lib/AdventureRL/version.rb +3 -0
  56. data/lib/adventure_rl.rb +22 -0
  57. data/lib/default_settings.yml +20 -0
  58. data/vimrc +4 -0
  59. metadata +237 -0
@@ -0,0 +1,170 @@
1
+ module AdventureRL
2
+ class SolidsManager
3
+ DEFAULT_SOLID_TAG = :default
4
+
5
+ DEFAULT_SETTINGS = Settings.new(
6
+ use_cache: false
7
+ )
8
+
9
+ def initialize settings = {}
10
+ @settings = DEFAULT_SETTINGS.merge settings
11
+ @quadtrees = {}
12
+ @reset_queue = {}
13
+ @cache = {}
14
+ @use_cache = @settings.get :use_cache
15
+ end
16
+
17
+ # Add one (or multiple) <tt>object</tt>(s)
18
+ # with one (or multiple) <tt>solid_tag</tt>(s).
19
+ def add_object object, solid_tag = DEFAULT_SOLID_TAG
20
+ objects = [object].flatten
21
+ solid_tags = [solid_tag].flatten
22
+ solid_tags.each do |tag|
23
+ if (@quadtrees[tag])
24
+ @quadtrees[tag].add_object objects
25
+ else
26
+ @quadtrees[tag] = Quadtree.new objects: objects
27
+ end
28
+ end
29
+ end
30
+ alias_method :add, :add_object
31
+
32
+ def remove_object object, solid_tag = DEFAULT_SOLID_TAG
33
+ objects = [object].flatten
34
+ solid_tags = [solid_tag].flatten
35
+ objects.each do |obj|
36
+ @cache.delete obj
37
+ end
38
+ get_quadtrees_for(solid_tags).each do |quadtree|
39
+ quadtree.remove_object objects
40
+ end
41
+ end
42
+ alias_method :remove, :remove_object
43
+
44
+ def remove_object_from_all_quadtrees object
45
+ objects = [object].flatten
46
+ objects.each do |obj|
47
+ @cache.delete obj
48
+ end
49
+ @quadtrees.values.flatten.each do |quadtree|
50
+ quadtree.remove_object objects
51
+ end
52
+ end
53
+ alias_method :remove_from_all_quadtrees, :remove_object_from_all_quadtrees
54
+
55
+ # Returns <tt>true</tt> if the given <tt>object</tt> (or multiple objects),
56
+ # collide with any other objects with a mutual <tt>solid_tag</tt>.
57
+ def collides? object, solid_tag = DEFAULT_SOLID_TAG
58
+ objects = [object].flatten
59
+ solid_tags = [solid_tag].flatten
60
+ return objects.any? do |obj|
61
+ handle_collides_cache_for obj, solid_tags
62
+ next @cache[obj][:collides?]
63
+ end if (@use_cache)
64
+ return objects.any? do |obj|
65
+ next get_quadtrees_for(solid_tags).any? do |quadtree|
66
+ next quadtree.collides?(obj)
67
+ end
68
+ end
69
+ end
70
+
71
+ # Returns all objects colliding with <tt>object</tt>(s).
72
+ def get_colliding_objects object, solid_tag = DEFAULT_SOLID_TAG
73
+ objects = [object].flatten
74
+ solid_tags = [solid_tag].flatten
75
+ return objects.map do |obj|
76
+ handle_colliding_objects_cache_for obj, solid_tags
77
+ next @cache[obj][:colliding_objects]
78
+ end .flatten if (@use_cache)
79
+ return objects.map do |obj|
80
+ next get_quadtrees_for(solid_tags).map do |quadtree|
81
+ next quadtree.get_colliding_objects(obj)
82
+ end
83
+ end .flatten
84
+ end
85
+
86
+ # Pass an <tt>object</tt> (or multiple), to queue it/them for
87
+ # resetting next update.
88
+ def reset_object object, solid_tag = DEFAULT_SOLID_TAG
89
+ objects = [object].flatten
90
+ solid_tags = [solid_tag].flatten
91
+ solid_tags.each do |tag|
92
+ @reset_queue[tag] ||= []
93
+ @reset_queue[tag].concat objects
94
+ end
95
+ end
96
+
97
+ # Resets for every object in <tt>@reset_queue</tt>.
98
+ def reset
99
+ @reset_queue.each do |solid_tag, objects|
100
+ @quadtrees.map do |quadtree_tag, quadtree|
101
+ next quadtree if (solid_tag == quadtree_tag)
102
+ next nil
103
+ end .compact.each do |quadtree|
104
+ quadtree.reset_object objects
105
+ end
106
+ @reset_queue[solid_tag] = []
107
+ end
108
+ end
109
+
110
+ def reset_cache_for object
111
+ @collides_cache.delete object
112
+ @colliding_objects_cache.delete object
113
+ end
114
+
115
+ # Called once every frame by Window.
116
+ def update
117
+ reset
118
+ end
119
+
120
+ private
121
+
122
+ def get_quadtrees_for solid_tag = DEFAULT_SOLID_TAG
123
+ solid_tags = [solid_tag].flatten
124
+ return @quadtrees.map do |quadtree_tag, quadtree|
125
+ next quadtree if (solid_tags.include?(quadtree_tag))
126
+ next nil
127
+ end .compact
128
+ end
129
+
130
+ def handle_collides_cache_for object, solid_tags
131
+ cached = @cache[object]
132
+ update_collides_cache_for object, solid_tags unless (
133
+ # TODO: Remove cache or improve, it can break stuff
134
+ @use_cache &&
135
+ cached &&
136
+ (cached[:position] == object.get_position) &&
137
+ (cached[:size] == object.get_size)
138
+ )
139
+ end
140
+
141
+ def update_collides_cache_for object, solid_tags
142
+ @cache[object] ||= {}
143
+ @cache[object][:position] = object.get_position.dup
144
+ @cache[object][:size] = object.get_size.dup
145
+ @cache[object][:collides?] = get_quadtrees_for(solid_tags).any? do |quadtree|
146
+ next quadtree.collides?(object)
147
+ end
148
+ end
149
+
150
+ def handle_colliding_objects_cache_for object, solid_tags
151
+ cached = @cache[object]
152
+ update_colliding_objects_cache_for object, solid_tags unless (
153
+ # TODO: Remove cache or improve, it can break stuff
154
+ @use_cache &&
155
+ cached &&
156
+ (cached[:position] == object.get_position) &&
157
+ (cached[:size] == object.get_size)
158
+ )
159
+ end
160
+
161
+ def update_colliding_objects_cache_for object, solid_tags
162
+ @cache[object] ||= {}
163
+ @cache[object][:position] = object.get_position.dup
164
+ @cache[object][:size] = object.get_size.dup
165
+ @cache[object][:colliding_objects] = get_quadtrees_for(solid_tags).map do |quadtree|
166
+ next quadtree.get_colliding_objects(object)
167
+ end .flatten
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,195 @@
1
+ module AdventureRL
2
+ # This is similar to a Rectangle, but it can display text
3
+ # with basic formatting.
4
+ class Textbox < Rectangle
5
+ DEFAULT_SETTINGS = Settings.new(
6
+ text: '',
7
+ font_size: 24,
8
+ font_name: 'MonoSpace',
9
+ font_color: 0xff_ffffff,
10
+ text_alignment: {
11
+ x: :center,
12
+ y: :center
13
+ },
14
+ border_padding: {
15
+ x: 16,
16
+ y: 8
17
+ },
18
+ border_color: 0xff_000000,
19
+ border_size: {
20
+ width: 0,
21
+ height: 0
22
+ },
23
+ background_color: 0xff_000000,
24
+ z_index: 0,
25
+ position: {
26
+ x: 0,
27
+ y: 0
28
+ },
29
+ size: {
30
+ width: 256,
31
+ height: 64
32
+ },
33
+ origin: {
34
+ x: :left,
35
+ y: :top
36
+ }
37
+ )
38
+
39
+ def initialize settings = {}
40
+ @settings = DEFAULT_SETTINGS.merge settings
41
+ @font_cache = {} # This Hash will be filled with any loaded Gosu::Font (see #set_font_size)
42
+ set_font_size @settings.get(:font_size)
43
+ @text = @settings.get :text
44
+ @font_color = @settings.get :font_color
45
+ @text_alignment = @settings.get :text_alignment
46
+ @border_padding = @settings.get :border_padding
47
+ @border_color = @settings.get :border_color
48
+ @border_size = @settings.get :border_size
49
+ super @settings
50
+ @color_original = @settings.get :background_color
51
+ end
52
+
53
+ def get_text
54
+ return @text
55
+ end
56
+
57
+ def set_text text
58
+ @text = text.to_s
59
+ end
60
+
61
+ # NOTE:
62
+ # This method is expensive, because it loads a new Gosu::Font.
63
+ # Call this sparingly.
64
+ # Once a new Gosu::Font is created, it is cached,
65
+ # wo when you resize to a previously used font it will not need to load a new Gosu::Font.
66
+ def set_font_size size
67
+ @font = @font_cache[size]
68
+ return if (@font)
69
+ @font = Gosu::Font.new(
70
+ size,
71
+ name: @settings.get(:font_name)
72
+ )
73
+ @font_cache[size] = @font
74
+ end
75
+
76
+ # TODO: This doesn't really work, it still takes a while to draw a Font the first time; look into this.
77
+ # Pass any amount of integers, which will each preload a new Gosu::Font,
78
+ # with the size of the integer.
79
+ def preload_font_sizes *sizes
80
+ sizes.flatten.each do |size|
81
+ Helpers::Error.error(
82
+ "Expected size to be an Integer, but got",
83
+ "`#{size.inspect}:#{size.class.name}'."
84
+ ) unless (size.is_a? Integer)
85
+ @font_cache[size] ||= Gosu::Font.new(
86
+ size,
87
+ name: @settings.get(:font_name)
88
+ )
89
+ end
90
+ end
91
+
92
+ def draw
93
+ draw_border
94
+ draw_background
95
+ draw_text
96
+ @color_temporary = nil
97
+ end
98
+
99
+ private
100
+
101
+ def draw_border
102
+ return unless (has_border?)
103
+ corner = get_corner :left, :top
104
+ Gosu.draw_rect(
105
+ corner.x, corner.y,
106
+ get_size(:width), get_size(:height),
107
+ @border_color,
108
+ @z_index
109
+ )
110
+ end
111
+
112
+ def draw_background
113
+ pos = get_position_for_background
114
+ size = get_size_for_background
115
+ Gosu.draw_rect(
116
+ pos.x, pos.y,
117
+ size[:width], size[:height],
118
+ get_color,
119
+ @z_index
120
+ )
121
+ end
122
+
123
+ def draw_text
124
+ pos = get_position_for_text
125
+ rel = get_relative_for_text
126
+ @font.draw_rel(
127
+ @text,
128
+ pos[:x], pos[:y], @z_index,
129
+ rel[:x], rel[:y],
130
+ 1, 1, # Scale
131
+ @font_color
132
+ )
133
+ end
134
+
135
+ def has_border?
136
+ return @border_size.values.any? do |size|
137
+ next size > 0
138
+ end
139
+ end
140
+
141
+ def get_position_for_background
142
+ corner = get_corner :left, :top
143
+ return corner unless (has_border?)
144
+ pos = corner.dup
145
+ pos.set_position(
146
+ x: (corner.x + @border_size[:width]),
147
+ y: (corner.y + @border_size[:height])
148
+ )
149
+ return pos
150
+ end
151
+
152
+ def get_size_for_background
153
+ size = get_size
154
+ return size unless (has_border?)
155
+ return {
156
+ width: (size[:width] - (@border_size[:width] * 2)),
157
+ height: (size[:height] - (@border_size[:height] * 2))
158
+ }
159
+ end
160
+
161
+ def get_position_for_text
162
+ return [:x, :y].map do |axis|
163
+ alignment = @text_alignment[axis]
164
+ case alignment
165
+ when :center
166
+ pos = get_center axis
167
+ else
168
+ mult = 1 if ([:left, :top].include? alignment)
169
+ mult = -1 if ([:right, :bottom].include? alignment)
170
+ pos = (
171
+ (@border_size[(axis == :x) ? :width : :height] * mult) +
172
+ (@border_padding[axis] * mult) +
173
+ get_side(alignment)
174
+ )
175
+ end
176
+ next [axis, pos]
177
+ end .to_h
178
+ end
179
+
180
+ def get_relative_for_text
181
+ return [:x, :y].map do |axis|
182
+ alignment = @text_alignment[axis]
183
+ case alignment
184
+ when :center
185
+ pos = 0.5
186
+ when :left, :top
187
+ pos = 0.0
188
+ when :right, :bottom
189
+ pos = 1.0
190
+ end
191
+ next [axis, pos]
192
+ end .to_h
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,225 @@
1
+ module AdventureRL
2
+ # The TimingHandler has nice methods to handle timing.
3
+ # It can #set_timeout or #set_interval for methods.
4
+ class TimingHandler
5
+ include Helpers::Error
6
+
7
+ def initialize
8
+ @queue = {
9
+ timeouts: [],
10
+ intervals: []
11
+ }
12
+ @elapsed_seconds = 0.0
13
+ @deltatime = Deltatime.new
14
+ @is_running = true
15
+ end
16
+
17
+ # #update should be called every frame,
18
+ # this is where it checks if any methods need to be called
19
+ # and calls them if necessary.
20
+ def update
21
+ return if (is_paused?)
22
+ handle_timeouts
23
+ handle_intervals
24
+ @elapsed_seconds += @deltatime.dt
25
+ @deltatime.update
26
+ end
27
+
28
+ def continue
29
+ return if (is_running?)
30
+ @is_running = true
31
+ reset
32
+ end
33
+
34
+ def pause
35
+ return if (is_paused?)
36
+ @is_running = false
37
+ end
38
+
39
+ def is_running?
40
+ return !!@is_running
41
+ end
42
+
43
+ def is_paused?
44
+ return !is_running?
45
+ end
46
+
47
+ # Reset the Deltatime
48
+ def reset
49
+ @deltatime.reset
50
+ end
51
+
52
+ # Set a timeout for a method.
53
+ # Call a method after a specified amount of time has passed.
54
+ # The passed <tt>args</tt> Hash should include the following keys:
55
+ # <tt>:method</tt>:: The method to be called. Can be one of the following:
56
+ # - a Method -- <tt>method(:my_method)</tt>
57
+ # - a Proc -- <tt>Proc.new { puts 'My method!' }</tt>
58
+ # - a method name as a Symbol -- <tt>:my_method</tt>
59
+ # <tt>:seconds</tt> _or_ <tt>:secs</tt>:: Integer or Float. The time to wait in seconds, before calling the method.
60
+ # <tt>:arguments</tt> _or_ <tt>:args</tt>:: Optional Array of arguments, which will be passed to the target method.
61
+ # <tt>:id</tt>:: Optional value which can be used to remove the timeout afterwards. See #remove_timeout.
62
+ # You can also pass a block to the method,
63
+ # which will be used instead of the <tt>:method</tt> key's value.
64
+ def set_timeout args = {}, &block
65
+ validate_args args, !!block
66
+ _args = get_unified_args args, &block
67
+ at = get_time_in _args[:seconds]
68
+ @queue[:timeouts] << {
69
+ method: _args[:method],
70
+ at: at,
71
+ arguments: _args[:arguments],
72
+ id: _args[:id]
73
+ }
74
+ end
75
+ alias_method :in, :set_timeout
76
+
77
+ # Set an interval for a method.
78
+ # Call a method in regular intervals.
79
+ # The passed <tt>args</tt> Hash should include the following keys:
80
+ # <tt>:method</tt>:: The method to be called. Can be one of the following:
81
+ # - a Method -- <tt>method(:my_method)</tt>
82
+ # - a Proc -- <tt>Proc.new { puts 'My method!' }</tt>
83
+ # - a method name as a Symbol -- <tt>:my_method</tt>
84
+ # <tt>:seconds</tt> _or_ <tt>:secs</tt>:: Integer or Float. The time to wait in seconds, before calling the method.
85
+ # <tt>:arguments</tt> _or_ <tt>:args</tt>:: Optional Array of arguments, which will be passed to the target method.
86
+ # <tt>:id</tt>:: Optional value which can be used to remove the interval afterwards. See #remove_interval.
87
+ # You can also pass a block to the method,
88
+ # which will be used instead of the <tt>:method</tt> key's value.
89
+ def set_interval args = {}, &block
90
+ validate_args args, !!block
91
+ _args = get_unified_args args, &block
92
+ at = get_time_in _args[:seconds]
93
+ @queue[:intervals] << {
94
+ method: _args[:method],
95
+ interval: _args[:seconds],
96
+ at: at,
97
+ arguments: _args[:arguments],
98
+ id: _args[:id]
99
+ }
100
+ end
101
+ alias_method :every, :set_interval
102
+
103
+ # If you passed an <tt>:id</tt> to your timeout when you set it with #set_timeout,
104
+ # then you can remove / clear it before it executes by calling this method and
105
+ # passing the same <tt>id</tt>.
106
+ def remove_timeout id
107
+ @queue[:timeouts].reject! do |timeout|
108
+ next timeout[:id] == id
109
+ end
110
+ end
111
+ alias_method :clear_timeout, :remove_timeout
112
+
113
+ # If you passed an <tt>:id</tt> to your interval when you set it with #set_interval,
114
+ # then you can remove / clear it by calling this method and
115
+ # passing the same <tt>id</tt>.
116
+ # If you did _not_ pass an <tt>id</tt>, then your interval will be running endlessly!
117
+ def remove_interval id
118
+ @queue[:intervals].reject! do |interval|
119
+ next interval[:id] == id
120
+ end
121
+ end
122
+ alias_method :clear_interval, :remove_interval
123
+
124
+ # Returns <tt>true</tt> if the given <tt>id</tt> exists as a timeout,
125
+ # and <tt>false</tt> if not.
126
+ def has_timeout? id
127
+ return @queue[:timeouts].any? do |timeout|
128
+ next timeout[:id] == id
129
+ end
130
+ end
131
+
132
+ # Returns <tt>true</tt> if the given <tt>id</tt> exists as an interval,
133
+ # and <tt>false</tt> if not.
134
+ def has_interval? id
135
+ return @queue[:intervals].any? do |interval|
136
+ next interval[:id] == id
137
+ end
138
+ end
139
+
140
+ private
141
+
142
+ def handle_timeouts
143
+ current_seconds = get_elapsed_seconds
144
+ @queue[:timeouts].reject! do |timeout|
145
+ next false unless (current_seconds >= timeout[:at])
146
+ timeout[:method].call *timeout[:arguments]
147
+ next true
148
+ end
149
+ end
150
+
151
+ def handle_intervals
152
+ current_seconds = get_elapsed_seconds
153
+ @queue[:intervals].each do |interval|
154
+ next unless (current_seconds >= interval[:at])
155
+ interval[:method].call *interval[:arguments]
156
+ interval[:at] = get_time_in interval[:interval]
157
+ end
158
+ end
159
+
160
+ def validate_args args, block_given = false
161
+ error(
162
+ "Passed argument must be a Hash."
163
+ ) unless (args.is_a? Hash)
164
+ unless (block_given)
165
+ error(
166
+ "Passed args Hash must include the key `:method'."
167
+ ) unless (args.key? :method)
168
+ method_class = args[:method].class
169
+ error(
170
+ "Key `:method' must be a Method, Proc, or Symbol, but is a `#{method_class.name}'"
171
+ ) unless ([Method, Proc, Symbol].include? method_class)
172
+ end
173
+ error(
174
+ "Passed args Hash must include the key `:seconds' or `:secs'."
175
+ ) unless (args.key?(:seconds) || args.key?(:secs))
176
+ seconds_key = :secs if (args.key? :secs)
177
+ seconds_key = :seconds if (args.key? :seconds)
178
+ seconds_class = args[seconds_key].class
179
+ error(
180
+ "Key `:#{seconds_key.to_s}' must be an Integer or Float, but is a `#{seconds_class.name}'"
181
+ ) unless ([Integer, Float].include? seconds_class)
182
+ if (args.key?(:arguments) || args.key?(:args))
183
+ arguments_key = :args if (args.key? :args)
184
+ arguments_key = :arguments if (args.key? :arguments)
185
+ arguments_class = args[arguments_key].class
186
+ error(
187
+ "Key `:#{arguments_key.to_s}' must be an Array, but is a `#{arguments_class.name}'"
188
+ ) unless (arguments_class == Array)
189
+ end
190
+ end
191
+
192
+ def get_unified_args args, &block
193
+ prc = get_proc_from(block || args[:method])
194
+ return {
195
+ method: prc,
196
+ seconds: args[:seconds] || args[:secs],
197
+ arguments: args[:arguments] || args[:args] || [],
198
+ id: args[:id]
199
+ }
200
+ end
201
+
202
+ def get_proc_from meth
203
+ prc = nil
204
+ if (meth.is_a? Method)
205
+ prc = meth.to_proc
206
+ elsif (meth.is_a? Proc)
207
+ prc = meth
208
+ elsif (meth.is_a? Symbol)
209
+ error(
210
+ "Method `:#{meth.to_s}' is not available in this scope."
211
+ ) unless (methods.include? meth)
212
+ prc = method(meth).to_proc
213
+ end
214
+ return prc
215
+ end
216
+
217
+ def get_time_in seconds
218
+ return get_elapsed_seconds + seconds
219
+ end
220
+
221
+ def get_elapsed_seconds
222
+ return @elapsed_seconds
223
+ end
224
+ end
225
+ end