Spriteオブジェクトの管理方法
アクションゲームなどを作る場合に、キャラのオブジェクトを管理する方法としては、Rubyなので標準で組み込まれている配列クラスを使うのが普通じゃないかと思う。
しかし、配列はループ中に消したりできないから、何らかのフラグなどを用いてArray#delete_ifなどで後から消すような処理を書く必要がある。
そういった部分については基本機能ではなくフレームワークレベルなのでDXRuby本体では提供しない方針としていて、ユーザーがそれぞれ使いやすい方法で実装するのが望ましい。
じゃあ、例えば配列以外にどんな方法があるのか、というのが今回の話題。
例えばSpriteクラスにnextというプロパティを追加して、それを使ってSpriteオブジェクトを連鎖させる、いわゆるリンクリストとか。Cなどの場合はよく使われる手ではある。
再帰で書けば簡単だが、Rubyには末尾再帰最適化が無いから、それを展開したコードを自分で書くほうがよい。
だいたいこんな感じ。
#!ruby -Ks require 'dxruby' class Sprite attr_accessor :next end class Sprites def initialize @top = nil @last = nil end def add(s) if @last == nil @top = s else @last.next = s end @last = s end def update if @top s = @top while s s.update s = s.next end end end def draw if @top s = @top while s s.draw s = s.next end end end end sprites = Sprites.new image = Image.new(40,40,[255,255,255]) 10.times do s = Sprite.new(rand(600), rand(440), image) sprites.add(s) end Window.loop do sprites.draw end
nextでつながったオブジェクトを辿って一連の処理を行う。このコードは片方向のリンクだから削除することができない。最初から辿って検索すれば可能だが、実行性能的にあまり喜ばしくない。双方向リストにしたほうが性能的にはよい。
ただ、現時点ではSprite.checkの衝突判定は引数に配列を受け取るから、使う場合は予めリンクを辿って配列を作る必要がある。そういう意味ではDXRuby1.3系は配列による管理を推奨していると言えるかもしれない。
まあ、オブジェクト数が異様に多くない限りは配列を作る負荷など気にするほどでもないから、配列以外のやり方をいろいろ試してみる価値はあるとは思う。