遷移図を描く様に、ってどんなの?
遷移図クラスにノードとアロー(ノード間の有向グラフと考えていただければ・・・)を追加していきます。
こういうふうに書きます。
リストのうち、DiagramProcessorクラスが、遷移図の操作クラスです。
PreMesNode1〜3などが遷移図のノードとなります。
PreMesNode1では、画像を一定間隔で透明にしていきます。
PreMesNode2では、画像を変更せずに4秒間表示します。
PreMesNode3では、画像を一定間隔で不透明にしていきます。
PreMesTriggerクラスは、ノードの実行条件を設定するクラスです。
サンプルでは、0.1秒ごとに処理を実行するようになっています。
これらのクラスのインスタンスを、:trans_0_0〜:trans_1_2として登録して、
それぞれのインスタンスのメソッドを順に実行するように設定しています。
最後に、処理を終了する場合は移動先を nil に設定します。
ちなみに、開始は :trans_0_0 で登録したインスタンス
class PreMesNode1 include DiagramNodeBase attr_reader :finished def initialize(base, sprite) @base = base @sprite = sprite @finished = false end def start @base.show @sprite.show end def update @base.alpha -= 5 if @base.alpha <= 0 @base.alpha = 0 @finished = true end end end class PreMesNode2 include DiagramNodeBase attr_reader :finished def initialize(base, sprite) @base = base @sprite = sprite @timer = WaitCounter.new(4.0) @finished = false end def start @timer.start end def stop @timer.stop end def update @finished = @timer.finish? end end class PreMesNode3 include DiagramNodeBase attr_reader :finished def initialize(base, sprite) @base = base @sprite = sprite @finished = false end def update @base.alpha += 5 if @base.alpha >= 255 @base.alpha = 255 @finished = true end end def stop @sprite.hide @base.hide end end class PreMesTrigger include NodeTriggerBase def initialize(wait) @counter = WaitCounter.new(wait) end def pre_process @counter.start end def post_process @counter.stop end def update? return @counter.finish? end def post_update @counter.start end end class PreMessage include Story::Scene def self.scene_type return :scene end def init @info = Shape.text(:font=>Font.serif){ text "Press Any Key to Skip" }.center.bottom{|b| 5.percent(b) } @info.dp = 2 @base = Sprite.new(:size=>[Screen.w, Screen.h], :type=>:as).centering @base.fill([0,0,0]) @base.alpha = 255 @base.dp = 1 @images = ["image/pre1.png", "image/pre2.png"].inject([]) {|images, img_fname| images << Sprite.new(:file=>img_fname, :type=>:ac).property{|o| o.dp = 0 }.centering } @processor = DiagramProcessor.new{|dia| @images.each_with_index{|img, idx| dia.add "trans_#{idx}_0".to_sym, PreMesNode1.new(@base, img), PreMesTrigger.new(0.05) dia.add "trans_#{idx}_1".to_sym, PreMesNode2.new(@base, img) dia.add "trans_#{idx}_2".to_sym, PreMesNode3.new(@base, img), PreMesTrigger.new(0.05) } dia.add_arrow(:trans_0_0, :trans_0_1){|obj| obj.finished } dia.add_arrow(:trans_0_1, :trans_0_2){|obj| obj.finished } dia.add_arrow(:trans_0_2, :trans_1_0){|obj| obj.finished } dia.add_arrow(:trans_1_0, :trans_1_1){|obj| obj.finished } dia.add_arrow(:trans_1_1, :trans_1_2){|obj| obj.finished } dia.add_arrow(:trans_1_2, nil){|obj| obj.finished } } end def setup @info.show @processor.start end def update return Prologue if Input.pushed_any? # 何かキーが押されたらメッセージ表示をスキップ return Prologue if @processor.finish? # 注意メッセージが終了したら次のシーンへ return @now end def final @processor.stop @info.hide @images.each{|img| img.hide } @base.hide end def dispose @base.dispose @images.each{|img| img.dispose } @info.dispose end end
次のサンプルは、移動条件による移動先ノードを変更するサンプルです。
(ちなみに、開始は :first で登録したインスタンス)
に振り分けています。
class Node1 include DiagramNodeBase attr_reader :v def initialize @v = 0 end def update puts "1" @v = (@v == 0 ? 1 : 0) end def render puts "render 1" end end class Node2 include DiagramNodeBase def update puts "2" end def render puts "render 2" end end class Node3 include DiagramNodeBase attr_reader :v def initialize @v = 0 end def update puts "3 : #{@v}" @v += 1 end def render puts "render 3" end end class Trigger2 include NodeTriggerBase def update? sleep(1) return true end end if __FILE__ == $0 # TODO Generated stub pr = DiagramProcessor.new{|dia| dia.add :first, Node1.new dia.add :second, Node2.new, Trigger2.new dia.add :third, Node3.new dia.add_arrow(:first, :third ){|node| node.v == 1 } dia.add_arrow(:first, :second ) dia.add_arrow(:second, :third ) dia.add_arrow(:third, nil ){|node| node.v > 10 } dia.add_arrow(:third, :first ) } rr = pr.renderer pr.start until pr.finish? do rr.render end pr.stop end
たぶん、このままではわかりにくいとは思いますので、時間があれば説明していきたいと思います。