とある方から、「メインループを後で実行する形にしてしまうと、
インタプリタで実行するメリットが失われる」旨の指摘を受けました。
たしかにその通りで、更新タイミングを自分で制御できないので、
たとえば irb で逐次実行などができません。
そこで提案なのですが、いまの Game.run メソッドを、次のように分解するのはどうでしょうか。
(Game がモジュールからクラスになるので、その点非互換です。)
def Game.run(*args, &block)
begin
g = Game.new(*args)
loop do
g.wait
g.update
break if g.terminated?
end
ensure
g.dispose
end
end
Game.run メソッドをつかわないで、 new を使うことによって
ゲームループを自由に制御することができるようになります。
Game.screen などはどうするんだとか、いろいろ問題は出てきそうですけれども。
ご意見お待ちしております。
--
Hajime Hoshi <hajim...@gmail.com>
yield が抜けてました。
def Game.run(*args)
begin
g = Game.new(*args)
loop do
g.wait
yield(g)
g.update
break if g.terminated?
end
ensure
g.dispose
end
end
--
Hajime Hoshi <hajim...@gmail.com>
> とても良いと思います。
どうもありがとうございます。
> Game.screenがGame.runの前に取得できなかったので、Scene.screenが初期化できなかったんですよね。
> それを取るために初回にのみ回るProcを作っていました。
> こういう形になればもっと素直に実装できそうです。
>
> それぞれのSceneは
>> loop do
>> g.wait
>> g.update_state
>> break if g.window_closed?
>> yield(g)
>> g.update_screen
>> end
> のループさえ記憶していれば良いだけになりますし。
なるほど。
スクリーンはいままで入りえなかった場所 (def Game.run(...) と loop do ... end との間) で
取得できますね。
> 描画が重い場合のフレームスキップも、
> renderイベントだけではなくGame#update_screenの呼び出し自体を飛ばせるのでFPSを確保しやすくなりそうですね。
確かにそうですね。
あとは Game.tick を使って自分でフレームレート管理ができますね。
> Game#waitですが、LifeGame等はfpsに関係なく最高速度で処理したいと思うので呼ばなくても良くなりますね。
> それ以外では、アニメーションや台詞のスキップなんかで使用されるんでしょうか。
あまりそこらへん考えていませんでしたが (笑)、
irb から使うなど「FPS が関係ない」場合に使えるのではないかと思いました。
> Game#window_scaleはどういう場合に使われるのでしょう?
> 320*240のゲーム画面をフルスクリーン表示した際などでしょうか?
0.2 にも window_scale オプションは Game.run メソッドにすでにあります。
ウィンドウを単純に拡大したい場合に使います。
単純な拡大なのでドットが立ち、そういう低解像度ゲームが好きな人にはよいかと。
> 既存のコードに影響はほとんどないと思うので、分離するのは良いことだと思います。
> というか、一番嬉しいのはフレームワーク側だったり。
なるほど。
そういうご意見は貴重 (Star Ruby のユーザーが少ない上、フレームワーク作成者はもっと少ない) ので
とてもありがたいです。
--
Hajime Hoshi <hajim...@gmail.com>