lib/ray/scene.rb in ray-0.1.0.pre1 vs lib/ray/scene.rb in ray-0.1.0

- old
+ new

@@ -21,11 +21,11 @@ # # Do drawing here # end # # Or you can override render: # def render(win) - # # Do drawing here + # # Do draw ing here # end # # Once your scene is loaded, you'll probably want to clean it up (set some # instance variables to nil so they can be garbaged collected for instance). # You can do that by passing a block to clean_up: @@ -63,33 +63,37 @@ # == Limiting the loop rate # You can prevent a scene from always running by using #loops_per_second=: # self.loops_per_second = 30 # will sleep some time after each loop # This defaults to 60. # - # == Lazy rendering - # By default, the scene is always rendered. You can enable lazy rendering: - # self.lazy_rendering = true - # In this case, the scene will render in its own Image when requested (using - # #need_render!), and that image will be drawn in every loop. - # # @see Ray::DSL::EventTranslator class Scene include Ray::Helper class << self # Registers a scene to a game object, used for subclasses. def bind(game) - game.scene(scene_name, self) + game.scene(@scene_name || snake_cased_name, self) end # @overload scene_name # @return [Symbol] the name of the scene # @overload scene_name(value) - # Sets the name of the scene - def scene_name(val = nil) - @scene_name = val || @scene_name + # Sets the name of the scene. Defaulted to the snake cased name of the + # scene. + def scene_name(val) + @scene_name = val end + + private + def snake_cased_name + if name + last_part = name.split("::").last + last_part[0] = last_part[0, 1].downcase + last_part.gsub(/[A-Z]/) { |letter| "_#{letter.downcase}" }.to_sym + end + end end scene_name :scene # Creates a new scene. block will be instance evaluated when @@ -98,14 +102,13 @@ @scene_register_block = block @scene_always_block = nil @scene_render_block = nil @scene_clean_block = nil - @scene_need_render = true @scene_loops_per_second = 60 - @scene_shader = nil + @scene_animations = Ray::AnimationList.new end def register_events if @scene_register_block instance_exec(@scene_arguments, &@scene_register_block) @@ -130,47 +133,12 @@ # to directly listen to a such event. def run until @scene_exit loop_start = Time.now - ev = Ray::Event.new - until ev.type == Ray::Event::TYPE_NOEVENT - DSL::EventTranslator.translate_event(ev).each do |args| - raise_event(*args) - end + run_tick - ev.poll! - end - - @scene_always_block.call if @scene_always_block - - listener_runner.run - - @scene_window.fill(Ray::Color.none) - - if lazy_rendering? - unless @scene_lazy_cache - @scene_lazy_cache = Ray::Image.new(:w => @scene_window.w, - :h => @scene_window.h) - end - - if @scene_need_render - @scene_lazy_cache.fill Ray::Color.none - - render @scene_lazy_cache - @scene_lazy_cache.update - - @scene_need_render = false - end - - @scene_lazy_cache.draw(:on => @scene_window, :shader => @scene_shader) - else - render @scene_window - end - - @scene_window.update - if @scene_loops_per_second ellapsed_time = Time.now - loop_start time_per_loop = 1.0 / @scene_loops_per_second sleep(time_per_loop - ellapsed_time) if ellapsed_time < time_per_loop @@ -178,10 +146,27 @@ end clean_up end + # Runs one tick of the scene, checking for events, running the event loop, + # and drawing on the window. + # + # @param [true, false] check_events True to check for events + def run_tick(check_events = true) + collect_events if check_events + + @scene_always_block.call if @scene_always_block + listener_runner.run + + @scene_animations.update + + @scene_window.clear Ray::Color.none + render @scene_window + @scene_window.update + end + # Runs another scene over the current one. # This method will return when the scene is done running. def run_scene(name, *args) scene_list = SceneList.new(game) scene_list.push(name, *args) @@ -220,15 +205,10 @@ # Registers a block to be excuted as often as possible. def always(&block) @scene_always_block = block end - # Marks the scene should be redrawn. - def need_render! - @scene_need_render = true - end - # Registers the block to draw the scene. # # If no block is given, renders the scen on the image passed as # an argument. # @@ -246,15 +226,10 @@ def push_scene(scene, *args) game.push_scene(scene, *args) exit end - # @see Ray::Game#resize_window - def resize_window(w, h) - game.resize_window(w, h) - end - # Cleans the scene or registers a block to clean it. def clean_up(&block) if block_given? @scene_clean_block = block else @@ -293,35 +268,22 @@ end alias :frames_per_second :loops_per_second alias :frames_per_second= :loops_per_second= - def lazy_rendering - @scene_lazy_rendering ||= false - end - - alias :lazy_rendering? :lazy_rendering - - def lazy_rendering=(val) - @scene_lazy_rendering = val - - unless lazy_rendering? - @scene_lazy_cache = nil - end - end - # The arguments passed to the scene with push_scene attr_accessor :scene_arguments - # @return [Ray::Shader] The shader used for this scene. - # It will be used when drawing the scene on the window. - # This won't do anything unless lazy_rendering is enabled. - def shader - @scene_shader + # @return [Ray::AnimationList] An animation list automatically updated by + # the scene. + def animations + @scene_animations end - # Sets the shader used for this scene - def shader=(value) - @scene_shader = value + private + def collect_events + window.each_event do |ev| + raise_event(*DSL::EventTranslator.translate_event(ev)) + end end end end