STGのフレームワークとRubyのeach

るびまに投稿する記事をあれこれ考えてつつ、下書き中である。
紹介するなら、その特徴は当然「簡単で高速」となる。
ライブラリの話だからそれしかない。
なので、それを手っ取り早く見せられるように、オブジェクト数の多いゲームのコードを載せて、動かしてみてもらおう、と思った。
オブジェクト数の多いゲームで簡単に作れるものっつーと、俺的には弾幕ゲーになる。
イデア貧乏ですから。


つーことでSTGモドキを作ってみたわけだが、ゼロから作ったにもかかわらず、サンプルSTGととても似たコードになってしまった。
俺の頭の中では、こーいうものはこうだ、と固まってしまっている、ということらしい。
それぞれ動くモノのクラスを作って、インスタンスを生成して配列に突っ込んで、移動(delete_if)→衝突判定(DXRubyExtension)→deleteフラグが立っているものを消す(delete_if)→描画、という流れだ。
DXRubyExtensionは汎用的に作ってあるものだから、これを挟むことで無駄が増えているが、それを帳消しにして余りあるほどには速い。
とりあえず、敵を出現させて、弾を撃たせて、自分も弾を撃って、衝突判定をしてみたところ、総オブジェクト数300ほどでCPU負荷が30%となった。
素のDXRubyとRuby1.8.7では、DXRubyExtensionを持ち出してもやっぱりこのあたりが限度だ。


ところで、他の人はこういうゲームをどう作っているんだろう。
と思ってruby+シューティングで検索していたら、こんなものを見つけた。
しろりん’s開発ラボ はてな別館さま
http://d.hatena.ne.jp/shirolabo/20090622/1245636814
すげー最近。
これはとてもよいですな。
Ruby/SDLとRUDLで簡単なフレームワークを作っておられる。
第1回が簡単なシューティングゲームということなので、ちょうどいいやん、というかんじでフレームワークのコードも見てみた。
ふむ・・・。
実装の違いはかなりあれど、基本的な考え方というのは結局あまり変わらないのかな?
当たり前と言えば当たり前のような気もしてきた。


ところでこのフレームワーク、キャラのmoveなどの中でstopメソッドを呼ぶと、キャラ配列から要素をdeleteメソッドで消しているのだが、これはなんだかまずそうだ。

a = Array.new(10) { |i| i }
p a
a.each do |i|
  a.delete i if i ==4 or i == 5
end
p a

とするとわかるが、each内でdeleteすると消した時点で前詰めされるために、消した要素の次の1つが処理されない。

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 5, 6, 7, 8, 9]

この場合だとdeleteの条件が4と5なのに、5が残ってしまう。
俺がフラグを立ててdelete_ifしている理由はそれだ。
フレームワークを動かして確認したわけじゃないから、ちゃんと動くようになってるのかもしれんけど。
トラックバックでも送っておくか。
どうやって送るんだろう・・・。