Class: Ray::Game
Overview
Games are used to manage different scenes. They also init Ray and create a window.
Creating a Game
There are several ways of doing this. Using a block:
Ray::Game.new("my game") do
...
end
Using the instance directly:
game = Ray::Game.new("my game")
...
game.run
Subclassing:
class Game < Ray::Game
def initialize
super("my game")
...
end
end
Game.new.run
Registring scenes to a Game
Games need the scenes they use to be registred. The most obvious way to do it is to use scene with a block:
scene :game do
# See Ray::Scene
end
You may also call it to register a subclass of Ray::Scene
scene(:game, GameScene)
Which is the same as:
GameScene.bind(self) # Assuming GameScene's scene_name is set to :game
Managing the scene stack
You can push a scene to the game:
push_scene :game
When #run will be called, it will show the scene :game. Notice that, if you push more than one scene, only the last one will be seen directly. However, if you remove it later, the previous scene will be shown.
You can thus also remove a scene from your stack:
pop_scene # Removes the last scene
exit is not exactly the same: it will ask the scene to quit before doing this. exit! will do something totally different: completely kill the game.
Handling events
Games can listen to events just like scenes. Since the event runner will change often, it needs to register every time it changes it. You can pass a block to the register method:
register do
on :some_event do some_stuff end
end
You may also want to override register in suclasses:
def register
on :some_event do some_stuff end
end
Instance Method Summary collapse
-
#exit ⇒ Object
Removes the current scene of this game.
-
#exit! ⇒ Object
Kills the game, removing all the scenes it contains.
-
#initialize(title, hash = {}, &block) ⇒ Game
constructor
Creates a new game.
- #inspect ⇒ Object
-
#pop_scene ⇒ Object
Pops the last scene.
-
#push_scene(scene_name, *args) ⇒ Object
Adds a scene to the stack using its name.
-
#register(&block) ⇒ Object
Registers a block to listen to events Subclasses can also overrid this method to register for events.
-
#resize_window(w, h) ⇒ Object
Resizes the window and raises a window_resize event.
-
#run ⇒ Object
Runs the game until the last scene gets popped.
-
#scene(name, klass = Scene, &block) ⇒ Object
Registers a new scene with a given name.
- #title ⇒ Object
Methods included from Helper
#channel, #create_event_runner, #event_runner, #event_runner=, #font, #image, #music, #sound, #sprite
Methods included from Matchers
Methods included from DSL::EventListener
#add_hook, #listener_runner, #listener_runner=, #on
Methods included from DSL::EventRaiser
#raise_event, #raiser_runner, #raiser_runner=
Constructor Details
#initialize(title, hash = {}, &block) ⇒ Game
Creates a new game.
You can pass all the arguments you would pass to create_window, except width and height which should be given in :video_mode:
Ray::Game.new('hello', :video_modes => %w(480x272 640x480))
It will try to get the biggest resolution available (so it will most likely choose 640x480 in this case).
If a block is passed, it is instance evaluated, then the game is directly run.
This methods creates a new window and inits Ray.
81 82 83 84 85 86 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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/ray/game.rb', line 81 def initialize(title, hash = {}, &block) @game_registred_scenes = {} @game_scenes = [] defaults = { :double_buf => true, :bpp => 32, :hw_surface => true, :sw_surface => false, :video_modes => %w(480x272 640x480) } = defaults.merge(hash) common_settings = { :sw_surface => [:sw_surface], :hw_surface => [:hw_surface], :bpp => [:bpp] || [:bits_per_pixel], :async_blit => [:async_blit], :double_buf => [:double_buf], :fullscreen => [:fullscreen], :resizable => [:resizable], :no_frame => [:no_frame] } modes = [:video_modes].map { |m| m.split('x').map { |i| i.to_i } } # The biggest resolution is privileged modes = modes.sort_by { |(w, h)| w * h }.map do |(w, h)| common_settings.merge(:w => w, :h => h) end Ray.init last_mode = modes.select { |mode| Ray.can_use_mode? mode }.last raise ArgumentError, "No valid mode found" unless last_mode if @game_title = title Ray.window_title = @game_title Ray.text_icon = @game_title end if icon = [:icon] Ray.icon = icon.is_a?(Ray::Image) ? icon : icon.to_image end @game_last_mode = last_mode @game_window = Ray.create_window(last_mode) if block instance_eval(&block) run end end |
Instance Method Details
#exit ⇒ Object
Removes the current scene of this game
203 204 205 206 207 208 |
# File 'lib/ray/game.rb', line 203 def exit return if @game_scenes.empty? @game_scenes.last.exit pop_scene end |
#exit! ⇒ Object
Kills the game, removing all the scenes it contains.
211 212 213 214 215 216 |
# File 'lib/ray/game.rb', line 211 def exit! return if @game_scenes.empty? @game_scenes.last.exit @game_scenes.clear end |
#inspect ⇒ Object
235 236 237 |
# File 'lib/ray/game.rb', line 235 def inspect "game(#{title.inspect})" end |
#pop_scene ⇒ Object
Pops the last scene.
154 155 156 |
# File 'lib/ray/game.rb', line 154 def pop_scene @game_scenes.delete_at(-1) end |
#push_scene(scene_name, *args) ⇒ Object
Adds a scene to the stack using its name.
You must call Game#scene before this. If you subclassed scene, then call bind to register it:
scene :something, SomeClass
SomeClass.bind(self)
145 146 147 148 149 150 151 |
# File 'lib/ray/game.rb', line 145 def push_scene(scene_name, *args) scene = @game_registred_scenes[scene_name] raise ArgumentError, "Unknown scene #{scene_name}" unless scene @game_scenes << scene @game_scene_arguments = args end |
#register(&block) ⇒ Object
Registers a block to listen to events Subclasses can also overrid this method to register for events.
194 195 196 197 198 199 200 |
# File 'lib/ray/game.rb', line 194 def register(&block) if block_given? @game_register_block = block else @game_register_block.call if @game_register_block end end |
#resize_window(w, h) ⇒ Object
Resizes the window and raises a window_resize event
219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/ray/game.rb', line 219 def resize_window(w, h) @game_window = Ray.create_window(@game_last_mode.merge!(:w => w, :h => h)) @game_scenes.each do |scene| scene.window = @game_window end @game_scenes.last.need_render! raise_event(:window_resize, Ray::Rect.new(0, 0, w, h)) end |
#run ⇒ Object
Runs the game until the last scene gets popped. Will call Ray.stop.
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/ray/game.rb', line 169 def run until @game_scenes.empty? create_event_runner register @game_scenes.each do |scene| scene.game = self scene.window = @game_window scene.event_runner = event_runner scene.scene_arguments = @game_scene_arguments end scene = @game_scenes.last scene.setup(*@game_scene_arguments) scene.register_events scene.need_render! scene.run end Ray.stop end |
#scene(name, klass = Scene, &block) ⇒ Object
Registers a new scene with a given name. the block will be passed to klass.new.
163 164 165 |
# File 'lib/ray/game.rb', line 163 def scene(name, klass = Scene, &block) @game_registred_scenes[name] = klass.new(&block) end |
#title ⇒ Object
231 232 233 |
# File 'lib/ray/game.rb', line 231 def title @game_title end |