シンプルなSceneクラス

簡単なシーン制御クラス。

class Scene
  EXIT = :exit
  def self.start(scene)
    loop do
      next_scene = scene.update
      if Scene === next_scene
        scene.quit
        scene = next_scene
        scene.init
      elsif next_scene == EXIT
        scene.quit
        break
      end
    end
  end

  def init
  end

  def update
  end

  def quit
  end
end

基本的にはnewで作ってScene.startに渡す。
initializeで初期化しといて、initでシーン導入時の効果(フェードインとか)、updateがたくさん呼ばれるからそこで処理、updateの戻り値にEXITで終了、別のSceneオブジェクトを返すとシーン遷移、遷移する前にquitが呼ばれるからそこでフェードアウトとか。
別のシーンをnewするときに引き継ぐオブジェクトを渡す。
ようするにシーン制御としてやりたいことってのはこんな程度なのではなかろうか。
使い方はこんな感じ。

require 'dxruby'
require 'scene'

class TestScene1 < Scene
  def initialize
    @x = 0
    @y = 0
    @image = Image.new(100,100,[255,255,255])
  end

  def update
    @x += 1
    if @x == 100
      return TestScene2.new(@x, @y, @image)
    end
    Window.draw(@x, @y, @image)
    Window.sync
    Window.update
  end
end

class TestScene2 < Scene
  def initialize(x, y, image)
    @x = x
    @y = y
    @image = image
  end

  def update
    @x -= 1
    if @x == 0
      return EXIT
    end
    Window.draw(@x, @y, @image)
    Window.sync
    Window.update
  end
end

Window.create
Scene.start(TestScene1.new)

右に移動するのがTestScene1で、左に移動するのがTestScene2。
ゲームループを分解しているからWindow.syncとWindow.updateを呼ばないといけないが、逆にこうすることで、1ループの中に複数フレームを詰め込むことができる。
うまく使えばたとえばinitの中でループしてフェードインするとかも可能だ。
この仕組みをもうちょっと作りこんで、DXRubyFrameworkのSpriteを使いやすくして連動させれば、簡単に高速動作をするゲームが作れる基盤になるかもしれない、となんとなく思った。