Class: MovieMaker::Movie
- Inherits:
-
Object
- Object
- MovieMaker::Movie
- Defined in:
- lib/movie_maker.rb
Instance Attribute Summary collapse
-
#actions ⇒ Object
Returns the value of attribute actions.
-
#background ⇒ Object
readonly
Returns the value of attribute background.
-
#clock ⇒ Object
readonly
Returns the value of attribute clock.
-
#screen ⇒ Object
readonly
Returns the value of attribute screen.
-
#stop_at ⇒ Object
readonly
Calculates the length of the movie by checking stop_at-times of all @actions that the movie consists of.
-
#updated_count ⇒ Object
readonly
Returns the value of attribute updated_count.
Instance Method Summary collapse
-
#at(start_at) ⇒ Object
Starts action at a start_time millisecs into the movie, no specific stop time.
-
#between(start_at, stop_at) ⇒ Object
Start following action start_at millisecs into the movie ..
- #camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true) ⇒ Object
-
#classify(table_name) ⇒ Object
Ripped from rails Inflector Used to convert move()-calls to a new instance of class Move and play_sound()-calls to a new instance of PlaySound ..
-
#delay(time) ⇒ Object
Start following action after the last one finishes + a millisecs delay argument.
-
#during(length) ⇒ Object
Start following action right away and specify how long is should run.
-
#gosu_draw(current_time) ⇒ Object
gosu_update - GOSU specific updateloop.
-
#gosu_update(current_time) ⇒ Object
gosu_update - GOSU specific updateloop.
-
#initialize(options = {}) ⇒ Movie
constructor
Takes an options-hash as argument: :screen => the screen to draw on :target_framerate => what framerate should it aim for, defaults to 60 :background => Color or Imageinstance :framework => :rubygame (default) or :gosu.
-
#method_missing(method, *args) ⇒ Object
Makes Object-initializing out of incomming missing actions ie.
-
#pause ⇒ Object
Pauses the movie, which should resume with a call to play() - NOT YET IMPLEMENTED.
-
#play(options = {}) ⇒ Object
Loops through the movie’s full timeline and updates all the @actions This method blocks until the movie ends.
-
#playing?(current_time) ⇒ Boolean
Is movie still playing?.
-
#resource(resource) ⇒ Object
(also: #sprite, #sound)
Sprite/Sound/Resource selection.
- #restart_at(time) ⇒ Object
-
#rubygame_update(current_time) ⇒ Object
rubygame_update() - Rubygame specific update Rubygame specific include: blit, sprite rects, dirty_rects and update_rects.
-
#setup ⇒ Object
Starts the clock which time will be sent to all events update()‘s Also paint a background, if any.
-
#stop ⇒ Object
Stops/resets the movie- NOT YET IMPLEMENTED.
-
#then ⇒ Object
Start following action after the last one finishes.
Constructor Details
#initialize(options = {}) ⇒ Movie
Takes an options-hash as argument: :screen => the screen to draw on :target_framerate => what framerate should it aim for, defaults to 60 :background => Color or Imageinstance :framework => :rubygame (default) or :gosu
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/movie_maker.rb', line 44 def initialize( = {}) @screen = [:screen] || nil @framework = [:framework] || :rubygame # this can also be :gosu @target_framerate = [:target_framerate] || 100 @background = [:background] || nil @draw_mode = [:draw_mode] || nil @loop = [:loop] || false if [:background].kind_of? ::Rubygame::Color::ColorRGB @background = Surface.new(@screen.size) @background.draw_box_s([0,0],[@screen.width,@screen.height], [:background]) end @actions = [] @onetime_actions = [] @update_actions = [] @tick = @start_at = @stop_at = 0 @restart_at = nil end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
Makes Object-initializing out of incomming missing actions ie. @movie.rotate(*arg) => Rotate.new(*arg) This makes for standalone extendable actions, one class per action
Ex. movie.between(0,2000).move(:ball, :from => [100,100], :to => [500,100])
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/movie_maker.rb', line 262 def method_missing(method, *args) ## ".move" (the string) ==> Move.new (the class) klass = MovieMaker::Action.const_get(camelize(method)) = { :start_at => @start_at, :stop_at => @stop_at, :screen => @screen, :background => @background, :object => @resource, :framework => @framework || :rubygame } standard_args = [] args.each do |arg| if arg.is_a? Hash .merge!(arg) else standard_args << arg end end action = klass.new(, *standard_args) #puts "ACTION: #{action.class}(#{standard_args}) - between(#{@start_at}, #{@stop_at})" @actions << action # # Separate actions that needs 1-time trigger # if @resource.kind_of? Sound or @stop_at == @start_at @onetime_actions << action # # And thoose who needs constant update/drawing # else @update_actions << action end self end |
Instance Attribute Details
#actions ⇒ Object
Returns the value of attribute actions.
33 34 35 |
# File 'lib/movie_maker.rb', line 33 def actions @actions end |
#background ⇒ Object (readonly)
Returns the value of attribute background.
34 35 36 |
# File 'lib/movie_maker.rb', line 34 def background @background end |
#clock ⇒ Object (readonly)
Returns the value of attribute clock.
34 35 36 |
# File 'lib/movie_maker.rb', line 34 def clock @clock end |
#screen ⇒ Object (readonly)
Returns the value of attribute screen.
34 35 36 |
# File 'lib/movie_maker.rb', line 34 def screen @screen end |
#stop_at ⇒ Object (readonly)
Calculates the length of the movie by checking stop_at-times of all @actions that the movie consists of.
TODO:
-
current the method at() doesn’t provide at stop_at, which makes total_playtime fail
70 71 72 |
# File 'lib/movie_maker.rb', line 70 def stop_at @stop_at end |
#updated_count ⇒ Object (readonly)
Returns the value of attribute updated_count.
34 35 36 |
# File 'lib/movie_maker.rb', line 34 def updated_count @updated_count end |
Instance Method Details
#at(start_at) ⇒ Object
Starts action at a start_time millisecs into the movie, no specific stop time
Example: @movie.at(2000).play_sound(@moo_sound)
325 326 327 328 329 |
# File 'lib/movie_maker.rb', line 325 def at(start_at) @start_at = start_at @stop_at = start_at self end |
#between(start_at, stop_at) ⇒ Object
Start following action start_at millisecs into the movie .. and stop it stop_at millisecs into the movie.
313 314 315 316 317 |
# File 'lib/movie_maker.rb', line 313 def between(start_at, stop_at) @start_at = start_at @stop_at = stop_at self end |
#camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true) ⇒ Object
247 248 249 250 251 252 253 |
# File 'lib/movie_maker.rb', line 247 def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true) if first_letter_in_uppercase lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } else lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1] end end |
#classify(table_name) ⇒ Object
Ripped from rails Inflector Used to convert move()-calls to a new instance of class Move and play_sound()-calls to a new instance of PlaySound .. etc.
244 245 246 |
# File 'lib/movie_maker.rb', line 244 def classify(table_name) camelize(singularize(table_name.to_s.sub(/.*\./, ''))) end |
#delay(time) ⇒ Object
Start following action after the last one finishes + a millisecs delay argument
Example:
@movie.at(1).play_sound(@drip).delay(0.1).play_sound(@drip, => 0.5).delay(0.1).play_sound(@drip, => 0.2)
363 364 365 366 |
# File 'lib/movie_maker.rb', line 363 def delay(time) @start_at = @stop_at||@start_at + time self end |
#during(length) ⇒ Object
Start following action right away and specify how long is should run
334 335 336 337 338 339 340 341 342 343 |
# File 'lib/movie_maker.rb', line 334 def during(length) if @stop_at==0 @start_at = :now else @start_at = @stop_at end @stop_at = @stop_at + length self end |
#gosu_draw(current_time) ⇒ Object
gosu_update - GOSU specific updateloop
205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/movie_maker.rb', line 205 def gosu_draw(current_time) @background.draw(0, 0, 0) if @background @update_actions.select { |action| action.started?(current_time) }.each do |action| action.sprite.image.draw_rot( action.sprite.x, action.sprite.y, 1, action.sprite.angle, 0.5, 0.5, action.sprite.width_scaling, action.sprite.height_scaling, action.sprite.color, (@draw_mode || action.sprite.draw_mode)) end end |
#gosu_update(current_time) ⇒ Object
gosu_update - GOSU specific updateloop
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/movie_maker.rb', line 183 def gosu_update(current_time) @updated_count = 0 # Restart movie cleanly? #if current_time > @restart_at #end @onetime_actions.select { |action| action.started?(current_time) and !action.finalized? }.each do |action| #puts "onetime action: #{action.start_at} - #{action.stop_at}" + action.class.to_s action.finalize end @update_actions.select { |action| action.(current_time) }.each do |action| #puts "update(#{current_time}): #{action.start_at} - #{action.stop_at}" + action.class.to_s action.update(current_time - action.start_at) @updated_count += 1 end end |
#pause ⇒ Object
Pauses the movie, which should resume with a call to play() - NOT YET IMPLEMENTED
234 235 236 |
# File 'lib/movie_maker.rb', line 234 def pause self end |
#play(options = {}) ⇒ Object
Loops through the movie’s full timeline and updates all the @actions This method blocks until the movie ends
To play the movie Within your own gameloop, use update()
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/movie_maker.rb', line 87 def play( = {}) @framework ||= [:framework] || :rubygame # this can also be :gosu @movie_stop_at ||= [:stop_at] ? [:stop_at] * 1000.0 : stop_at # Convert all start_at's filled with :now to current timestamp (meaning they'll start .. "now") @actions.each do |action| action.start_at = @clock.lifetime if action.start_at.is_a? Symbol and action.start_at == :now end setup while @clock.lifetime < @movie_stop_at @tick = @clock.tick() title = "[framerate: #{@clock.framerate.to_i}] [Spriteupdates last tick: #{@updated_count}]" if @framework == :rubygame @screen.title = title rubygame_update(@clock.lifetime) else @screen. = title gosu_update(@clock.lifetime) gosu_draw(@clock.lifetime) end yield if block_given? end end |
#playing?(current_time) ⇒ Boolean
Is movie still playing?
77 78 79 |
# File 'lib/movie_maker.rb', line 77 def (current_time) current_time <= stop_at end |
#resource(resource) ⇒ Object Also known as: sprite, sound
Sprite/Sound/Resource selection
371 372 373 374 375 376 |
# File 'lib/movie_maker.rb', line 371 def resource(resource) @resource = resource @start_at = 0 @stop_at = 0 self end |
#restart_at(time) ⇒ Object
220 221 222 223 |
# File 'lib/movie_maker.rb', line 220 def restart_at(time) @restart_at = time self end |
#rubygame_update(current_time) ⇒ Object
rubygame_update() - Rubygame specific update Rubygame specific include: blit, sprite rects, dirty_rects and update_rects
-
goes through all @actions and calls undraw/update/draw.
-
goes through all @onetime_actions and calls play on them once.
Several optimizations are possible here:
-
sort @actions after start_at so update doesn’t have to loop through all events each time only until start_at isn’t lower then current_time anymore
-
remove “played-out” actions from @actions
-
remove “played-out” actions from @onetime_actions
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/movie_maker.rb', line 143 def rubygame_update(current_time) @updated_count = 0 #@onetime_actions.select { |action| !action.playing?(current_time) and action.started?(current_time) }.each do |action| @onetime_actions.select { |action| action.started?(current_time) and !action.finalized?}.each do |action| action.finalize end dirty_rects = [] # Only undraw/update actions that are active on the timeline @update_actions.select { |action| action.(current_time) }.each do |action| dirty_rects << @background.blit(@screen, action.sprite.rect, action.sprite.rect) action.update(current_time - action.start_at) #puts "update(#{current_time}): #{action.start_at} - #{action.stop_at}" + action.class.to_s @updated_count += 1 # # Rotozoom lies here because of 2 reasons: # - Action can't do the actual imagemanipulation since Gosu does it drawtime # - By moving it out of the action, we can have more then 1 action manipulting rotozoom parameeters # if action.sprite.angle != 0 || action.sprite.width_scaling != 1 || action.sprite.height_scaling != 1 action.sprite.image = action.image.rotozoom( action.sprite.angle, [action.sprite.width_scaling, action.sprite.height_scaling], true) action.sprite.realign_center end end @update_actions.select { |action| action.started?(current_time) }.each do |action| dirty_rects << action.sprite.image.blit(@screen, action.sprite.rect) end @screen.update_rects(dirty_rects) end |
#setup ⇒ Object
Starts the clock which time will be sent to all events update()‘s Also paint a background, if any.
120 121 122 123 124 125 126 127 |
# File 'lib/movie_maker.rb', line 120 def setup @clock = ::Gosu::Clock.new @clock.target_framerate = @target_framerate if @framework == :rubygame @background.blit(@screen, [0, 0]) if @background @screen.update end end |
#stop ⇒ Object
Stops/resets the movie- NOT YET IMPLEMENTED
227 228 229 |
# File 'lib/movie_maker.rb', line 227 def stop self end |
#then ⇒ Object
Start following action after the last one finishes
Example: @movie.between(0,1).move(@stone, :from => [0,0], :to => [0,400]).then.play_sound(@crash)
351 352 353 354 |
# File 'lib/movie_maker.rb', line 351 def then @start_at = @stop_at self end |