lib/game_loader.rb in shattered_ruby-0.5.0.2 vs lib/game_loader.rb in shattered_ruby-0.5.1

- old
+ new

@@ -3,116 +3,151 @@ include ShatteredState include ShatteredView include ShatteredModel module Shatter #:nodoc:all -#This class is loads the view, controller, and model. It then loads -#and starts the game based on these. -class GameLoader - include Singleton - attr_writer :environment - attr_reader :media_paths, :render_window, :input_manager, :key_manager, :key_converter - attr_accessor :current_state - - # This will recourse into the app/** directories and load all ruby files - # inside those directories. - def load_all_sources(shattered_root) - File.find_by_extension(shattered_root+"/app", "rb").each do |file| - require(file) + #This class is loads the view, controller, and model. It then loads + #and starts the game based on these. + class GameLoader + include Singleton + attr_writer :environment + attr_reader :media_paths, :input_manager, :key_manager, :key_converter + attr_accessor :current_state, :render_window + + # This will recourse into the app/** directories and load all ruby files + # inside those directories. + def load_all_sources(shattered_root) + File.find_by_extension(shattered_root+"/app", "rb").each do |file| + require(file) + end end - end + + # start the game + def run + load_all_sources(SHATTERED_ROOT) + load_environment + + # Create our initial state, as defined by the environment. + create_state(@environment[:start_state]) - # start the game - def run - load_all_sources(SHATTERED_ROOT) - load_environment - - # Create our initial state, as defined by the environment. - create_state(@environment[:start_state]) - - start_game - end - - # Create a state from the given name - # :sample creates a new SampleState object - def create_state(state_name) - state_class = eval("#{state_name.to_s.camelize}State") - raise Error, "#{state_class} is not a class" unless state_class.is_a? Class - state = state_class.new - unless state.is_a? ShatteredState::Base - raise Error, "#{state_class} is an invalid State object (not of ShatteredState::Base)" - end - return state - end - - def load_environment - #Setup Ogre and the scene for the state - raise Error, "Ogre failed to initialize" if !setup_ogre - setup_input - - load_resources(@environment[:media]) - end - - # Given ['app/media', 'media'], searches those directories, recursively, for OGRE media - def load_resources(paths) - @media_paths = paths - # setup our resource paths specified in environment.rb - Resources.instance.add_resource_paths(*paths) - Resources.instance.setup - end - - #Load the root, setup the render window - #TODO: allow for the user to specify whether the window dialogue pops up - #further TODO: allow the user to skin the render window dialogue - def setup_ogre - # TODO: create platform loader for other platforms - plugins = SHATTERED_ROOT + "/config/ogre_plugins.windows.cfg" - config_save=SHATTERED_ROOT + "/config/ogrerb_defaults.save" - log=SHATTERED_ROOT + "/log/ogrerb.log" - @root = ShatteredOgre.create_root(plugins, config_save, log) - return false if !@root.show_config_dialog - # TODO: allow application name to be set. - @render_window = @root.initialise(true) + start_game + end - return true - end + # Create a state from the given name + # :sample creates a new SampleState object + def create_state(state_name) + state_class = eval("#{state_name.to_s.camelize}State") + raise Error, "#{state_class} is not a class" unless state_class.is_a? Class + state = state_class.new + unless state.is_a? ShatteredState::Base + raise Error, "#{state_class} is an invalid State object (not of ShatteredState::Base)" + end + return state + end + + def load_environment + #Setup Ogre and the scene for the state + raise Error, "Ogre failed to initialize" if !setup_ogre + setup_input - #Every time this exits, a game dies. - def start_game - each_frame do |time_elapsed| - current_state.update_timers(time_elapsed) - @keyboard.capture - #@@environment[:input].flush + load_resources(@environment[:media]) + end + + # Given ['app/media', 'media'], searches those directories, recursively, for OGRE media + def load_resources(paths) + @media_paths = paths + # setup our resource paths specified in environment.rb + Resources.instance.add_resource_paths(*paths) + Resources.instance.setup + end + + #Load the root, setup the render window + #TODO: allow for the user to specify whether the window dialogue pops up + #further TODO: allow the user to skin the render window dialogue + def setup_ogre + # TODO: create platform loader for other platforms + plugins = SHATTERED_ROOT + "/config/ogre_plugins.windows.cfg" + config_save=SHATTERED_ROOT + "/config/ogrerb_defaults.save" + log=SHATTERED_ROOT + "/log/ogrerb.log" + @root = ShatteredOgre.create_root(plugins, config_save, log) + return false if !@root.show_config_dialog + # TODO: allow application name to be set. + @render_window = @root.initialise(true) + + return true + end + + #Every time this exits, a game dies. + def start_game + each_frame do |time_elapsed| + Ogre::WindowEventUtilities::message_pump + current_state.update_timers(time_elapsed) + @key_manager.flush + @keyboard.capture + end + shutdown! end + + # Main game loop + def each_frame + timer = Ogre::Timer.new + while !@environment[:quit] && Ogre::Root::instance.render_one_frame + return false if @render_window.closed? + seconds = timer.get_microseconds / 1000000.0 + timer.reset + yield seconds + end + end + + # Shutdown Ogre / OIS / Navi + def shutdown! + #@input_manager.destroy_input_object(@mouse) + @input_manager.destroy_input_object(@keyboard) + #@input_manager.destroy_input_object(@joy_stick) + + OIS::InputManager.destroy_input_system(@input_manager) + + #NEED TO UNREGISTER THE WINDOW LISTENER HERE!!!!!!!!!!!! + + @input_manager = nil + end + + # Leave the game + def quit! + @environment[:quit]=true + end + + # load the input manager, the key manager, etc + # TODO: Investigate any use cases for non-buffered input + def setup_input + setup_window + @input_manager = OIS::InputManager.create_input_system(@environment[:window]) + setup_keyboard + end + + # Creates our window and our window event listener. + def setup_window + windowHnd = render_window.get_custom_attribute_unsigned_long("WINDOW") + @environment[:window]["WINDOW"] = windowHnd.to_s + #@window_listener = WindowEventsListener.new(@render_window) + end + + # Sets up our keyboard object in buffered mode. + def setup_keyboard + @keyboard = @input_manager.create_input_object(OIS::OISKeyboard, true) + @key_manager = OIS::KeyManager.new(@keyboard) + @key_converter = ShatteredPack::KeyConverter.new(@key_manager) + end end + + # Handle window events - closed and resized + # TODO: This class belongs elsewhere... + class WindowEventsListener < Ogre::WindowEventListenerProxy + def window_resized(rw) + # GameLoader.instance.resize(rw) + end + def window_closed(rw) + GameLoader.instance.current_state.quit + end + end - # Main game loop - def each_frame - timer = Ogre::Timer.new - while !@environment[:quit] && Ogre::Root::instance.render_one_frame - seconds = timer.get_microseconds / 1000000.0 - yield seconds - timer.reset - end - end - - # Leave the game - def quit! - @environment[:quit]=true - end - - # load the input manager, the key manager, etc - # TODO: Consider how to make input non-exclusive, as well as mouse, etc. - # TODO: Investigate any use cases for non-buffered input - def setup_input - windowHnd = render_window.get_custom_attribute_unsigned_long("WINDOW") - @input_manager = OIS::InputManager.create_input_system( - { "WINDOW" => "#{windowHnd}", - "w32_mouse" => ["DISCL_FOREGROUND", "DISCL_NONEXCLUSIVE"], - "w32_keyboard" => ["DISCL_FOREGROUND", "DISCL_NONEXCLUSIVE"] - }) - @keyboard = @input_manager.create_input_object(OIS::OISKeyboard, true) - @key_manager = OIS::KeyManager.new(@keyboard) - @key_converter = ShatteredPack::KeyConverter.new(@key_manager) - end -end end