フレームワークの叩き台を上げてみました

55 views
Skip to first unread message

ISA

unread,
Jul 2, 2008, 10:20:34 AM7/2/08
to Star Ruby
まだ未実装の部分が多いですが、叩き台として意見を伺おうと思って上げてみました。
一段落すらしてないのでバージョンナンバーはついてません。

http://isaisstillalive.googlepages.com/starframe.zip

SceneとSpriteクラスのサブクラスを作り、
init,quit,update,renderメソッドに処理を記入するといったオーソドックスな作りになっています。

特徴は、
・StarRuby::Game.runに直接渡せるようにClass#to_procを持っていること
・Spriteのサブクラスにモジュールをincludeすることで機能を追加していくこと
の二点です。

前者の利点は、
「StarRuby::Game.run 640, 480, &MainScene」という記述のみで実行できるため、mainが簡潔になることで
す。

後者の利点は、必要なモジュールだけincludeするので処理が早い(かもしれない)ことと、
Spriteへの拡張機能の共有が容易なことです。


現在、「当たり判定自体のクラスはあるがSpriteに当たり判定を実装するモジュールがない」という切ないことになっています。
今の予定では、initイベント内で当たり判定クラスのインスタンスを作成しSpriteに追加していくという形で、
一つのSpriteに対して複数の当たり判定を設けられるような形を考えています。
が、もしかしたら一つのSpriteではシンプルな一つの当たり判定で十分かもしれません。

ライブラリを作るのに夢中でゲーム自体には手をつけられてないという本末転倒っぷりなので、
実際のゲーム製作者の意見と乖離してしまっている可能性もあります。

なので、よろしければ触ってみて感想を頂けるとうれしいです。

Hajime Hoshi

unread,
Jul 2, 2008, 11:00:08 AM7/2/08
to star...@googlegroups.com
星です。

まだソースをざっと見ただけですが、気になるところを。

* Sprite が Texture の子クラスであるのが気になりました。
コンポジットにしなかった理由はありますか?
* Scene の method_missing は便利かもしれませんがやりすぎではありませんか。
* Eventable は、意味は分かるのですが、そういう英単語はないと思います。
* イベント周りですが、メソッドのフックを使うと綺麗に書けそうな気がします。
http://ja.doukaku.org/169/lang/ruby/
* StarFrame.camelize メソッドは、グローバルなメソッドにするより
String クラスに追加定義したほうが使いやすくないでしょうか。

その他 Collision とか便利そうだなーとか思ったので後でじっくり拝見させていただきます。

--
Hajime Hoshi <hajim...@gmail.com>

ISA

unread,
Jul 2, 2008, 12:15:06 PM7/2/08
to Star Ruby
ISAです。
ご感想ありがとうございます。

> * Sprite が Texture の子クラスであるのが気になりました。
意味的に、Spriteのベース部分は「座標等の情報を持つだけのTexture」なのかなと思ってそうしました。
render_textureのオプションで渡せる部分をインスタンスで保持できて、「Sprite#render_to texture」で描画でき
ると楽かなといったところです。
逆に、Texture#render_spriteを実装してしまったほうが良いのかもしれません。

ただ、サブクラスである利点は現状殆どないですね。
renderイベント内でrender系メソッドを関数的に使用できるくらいでしょうか。

座標と角度の情報をLocatableモジュールに分離するという手はありかも?


> * Scene の method_missing は便利かもしれませんがやりすぎではありませんか。
Spriteと同様に、renderイベント内でrender系メソッドを関数的に使用したかっただけです。
render系の数はそう多くないので、@screenに丸投げするだけのメソッドを定義してしまったほうが親切ですね。


> * Eventable は、意味は分かるのですが、そういう英単語はないと思います。
そうなんです。ありません(笑)
何か他に適切な名称があれば変更したいところです。


> * イベント周りですが、メソッドのフックを使うと綺麗に書けそうな気がします。
イベント周りはRailsの手法を参考にしました。
これだとモジュール側の実装は手間ですが、対象のメソッドの前後どちらに(あるいは両方に)割り込む場合にでも同じ形式で記述でき、
実行時の処理が簡潔になるので速度面で有利かなと思いました。


> * StarFrame.camelize メソッドは、グローバルなメソッドにするより
> String クラスに追加定義したほうが使いやすくないでしょうか。
これは確かにそのほうが良いと思いますね。
Rails(ActiveSupport)も同様ですし、何より他のモジュールのメソッドは記述が面倒。


> その他 Collision とか便利そうだなーとか思ったので後でじっくり拝見させていただきます。
ありがとうございます。

Collisionは悩みましたが、悩んだだけのものは出来たんじゃないかと思っています。
開発メモを同梱し忘れたので別途上げました。
http://isaisstillalive.googlepages.com/starframe_memo.txt
上記の通り、Numericのダブルディスパッチとcoerceを意識しています。(coercingは未実装ですが)

ただ、Spriteが矩形である以上、ダブルディスパッチだけでもある程度上手くいくと思うので、ここまでリッチにする必要はないのかもしれません。
ゲームである以上、正確さはほどほどにして速度を優先しなければならない部分も多いと思うので、そこが悩みどころです。

ISA

unread,
Jul 3, 2008, 6:35:19 AM7/3/08
to Star Ruby
試しに、StarFrame::Spriteを使用して、サンプルのsprite.rbを移植してみました。

純正が800fps出るところで、
StarFrame版は40fpsしか出ませんでした。

これは遅い。遅すぎるということで調べてみると、遅いと思われる原因がいくつかありました。
・常にrender_textureのオプションを指定している
->オプションを全て切捨てたら
40fps -> 46fps (*1.15)

・描画座標と移動にVector同士の演算を使っている
->配列同士の演算にしたら
40fps -> 120fps (*3)

・オフスクリーン描画(自分に描画)してからスクリーンに描画している
->直接スクリーンに描画するようにしたら
40fps -> 42fps (*1.05)

->直接描画するならTextureのサブクラスにする必要は無いので単独クラスにしたら
40fps -> 42fps (*1.05)

->三種類全て適用で
40fps -> 210fps (*5.25)

この手法ではこれが限界のようです。

->ここから、モジュールを使用せずに直接Spriteクラスに移動用メソッドを定義し、メソッドチェインの回数を減らすと
210fps -> 260fps (*1.24)

おいつけない……。

モジュールによる拡張方式は速度の面で不利なようですね。
もう少し良い手段がないか考えてみます。

Hajime Hoshi

unread,
Jul 3, 2008, 7:22:53 AM7/3/08
to star...@googlegroups.com
星です。

実行しようとしたのですが、エラーになりました。

$ ruby main.rb
./lib/starframe/sprite.rb:89: warning: parenthesize argument(s) for
future version
./lib/starframe/loadable.rb:4:in `open': No such file or directory -
images (Errno::ENOENT)
from ./lib/starframe/loadable.rb:4:in `foreach'
from ./lib/starframe/loadable.rb:4:in `load'
from ./lib/starframe/image.rb:9:in `load'
from main.rb:6

--
Hajime Hoshi <hajim...@gmail.com>

ISA

unread,
Jul 3, 2008, 7:25:31 AM7/3/08
to Star Ruby
忘れてました。

main.rbはimagesディレクトリが必要です。
お手数ですが、starruby自体のsampleディレクトリにあるimagesをコピーしてください。

Hajime Hoshi

unread,
Jul 3, 2008, 7:47:41 AM7/3/08
to star...@googlegroups.com
星です。

次はこのようなエラーが…
ひょっとして Ruby 1.8.7 用ですか?

$ ruby main.rb
./lib/starframe/sprite.rb:89: warning: parenthesize argument(s) for
future version

./lib/starframe.rb:21:in `camelize': wrong argument type Symbol
(expected Proc) (TypeError)
from ./lib/starframe.rb:20:in `map'
from ./lib/starframe.rb:20:in `camelize'
from ./lib/starframe/loadable.rb:8:in `load'

ISA

unread,
Jul 3, 2008, 10:17:16 AM7/3/08
to Star Ruby
あーはい。そうです。

symbol#to_procを使ってるだけなので普通のブロック方式にすれば動きます。
すいません。

Hajime Hoshi

unread,
Jul 3, 2008, 3:00:41 PM7/3/08
to star...@googlegroups.com
星です。

該当箇所の map(&:capitalize) は map{|s| s.capitalize} と直しました。
が、次なるエラーが…。

$ ruby main.rb
./lib/starframe/sprite.rb:89: warning: parenthesize argument(s) for
future version

main.rb:45:in `init': uninitialized constant StarFrame::Image::Back3x1
(NameError)
from ./lib/starframe/eventable.rb:12:in `call_init_without_animation'
from ./lib/starframe/sprite/animatable.rb:18:in `call_init'
from ./lib/starframe/scene.rb:16:in `initialize'
from ./lib/starframe/scene.rb:27:in `new'
from ./lib/starframe/scene.rb:27:in `to_proc'
from ./lib/starframe/scene.rb:28:in `call'
from ./lib/starframe/scene.rb:28:in `to_proc'
from main.rb:145:in `run'
from main.rb:145

--
Hajime Hoshi <hajim...@gmail.com>

ISA

unread,
Jul 3, 2008, 7:53:33 PM7/3/08
to Star Ruby
それは画像の上げ忘れでした(汗)

http://isaisstillalive.googlepages.com/back3x1.png
この画像をimagesの中に入れてください。

圧縮ファイル内にsample/imagesを含めるのはどうかなと思って別にしたんですが、
やはりちゃんと画像をこちらで用意しておくべきでした。

お手数かけまして申し訳ありません。

Hajime Hoshi

unread,
Jul 4, 2008, 2:59:37 AM7/4/08
to star...@googlegroups.com
星です。

main.rb 動かせました。
なかなかキャッチーな映像が出てきました。

> > * Sprite が Texture の子クラスであるのが気になりました。
> 意味的に、Spriteのベース部分は「座標等の情報を持つだけのTexture」なのかなと思ってそうしました。
> render_textureのオプションで渡せる部分をインスタンスで保持できて、「Sprite#render_to texture」で描画でき
> ると楽かなといったところです。
> 逆に、Texture#render_spriteを実装してしまったほうが良いのかもしれません。
>
> ただ、サブクラスである利点は現状殆どないですね。
> renderイベント内でrender系メソッドを関数的に使用できるくらいでしょうか。

関数的に指定できるのは嬉しいのですが、
Texture の子クラスであるという縛りをつけてまでそれが嬉しいかというと
僕はちょっと疑問です。
速度面まで考えると逆に ISA さんの方法のほうがいいのかな。うーん。

> > * Eventable は、意味は分かるのですが、そういう英単語はないと思います。
> そうなんです。ありません(笑)
> 何か他に適切な名称があれば変更したいところです。

EventHandleable とか?

> > * イベント周りですが、メソッドのフックを使うと綺麗に書けそうな気がします。
> イベント周りはRailsの手法を参考にしました。
> これだとモジュール側の実装は手間ですが、対象のメソッドの前後どちらに(あるいは両方に)割り込む場合にでも同じ形式で記述でき、
> 実行時の処理が簡潔になるので速度面で有利かなと思いました。

Eventable を使用して、こんなに簡潔に書けるようになった、というサンプルがやっぱりほしいです。

> > その他 Collision とか便利そうだなーとか思ったので後でじっくり拝見させていただきます。
> ありがとうございます。
> Collisionは悩みましたが、悩んだだけのものは出来たんじゃないかと思っています。
> 開発メモを同梱し忘れたので別途上げました。
> http://isaisstillalive.googlepages.com/starframe_memo.txt
> 上記の通り、Numericのダブルディスパッチとcoerceを意識しています。(coercingは未実装ですが)
>
> ただ、Spriteが矩形である以上、ダブルディスパッチだけでもある程度上手くいくと思うので、ここまでリッチにする必要はないのかもしれません。
> ゲームである以上、正確さはほどほどにして速度を優先しなければならない部分も多いと思うので、そこが悩みどころです。

イベントと同様に、実際のサンプルを見てみたいです。
フレームワークは、実際のゲームを作りながら考えていったほうが、
必要十分なものができると思うのですがいかがでしょうか。

> ・常にrender_textureのオプションを指定している
> ->オプションを全て切捨てたら
> 40fps -> 46fps (*1.15)

実は、 options 引数が省略されたときに、オプション関係の処理を飛ばす
ようになっています。

> ->ここから、モジュールを使用せずに直接Spriteクラスに移動用メソッドを定義し、メソッドチェインの回数を減らすと
> 210fps -> 260fps (*1.24)
>
> おいつけない……。
>
> モジュールによる拡張方式は速度の面で不利なようですね。
> もう少し良い手段がないか考えてみます。

ふむー、モジュールをいったんかむと遅くなってしまうのですね。
効率を考えるとモジュールや継承を避けたほうがいいのかなあ。

あといろいろ見て気づいたことです:

* require 'lib/...' が気になりました (パスと名前空間が一致してない)。
$LOAD_PATH に './lib' を加えてしまうのはどうでしょう。
* Loadable についてですが、文字列 (String) で指定するのに比べて
どのようなメリットがあるのかありますか。
定数でとってしまうのはいろいろトラブルになりそうな気がしますが。
* 点をあらわすのを Vector でやっていますが、やっぱり配列で十分な気がします
(もうそうなっていると思われますが)。
Vector (Matrix) は Ruby べた書きなので速度面では期待できません。
* Animatable モジュールは Eventable モジュール include 前提ですか?
* Movable モジュールは分ける必要あったのでしょうか。
Sprite クラスに組み込みにしてもよかったんじゃないかなあ。

--
Hajime Hoshi <hajim...@gmail.com>

ISA

unread,
Jul 4, 2008, 6:23:46 AM7/4/08
to Star Ruby
長いメッセージですいません。
短くする時間が取れませんでした。


> Texture の子クラスであるという縛りをつけてまでそれが嬉しいかというと
> 僕はちょっと疑問です。

良く考えると、スプライトにはrenderイベントはいらないかもしれませんね。
背景がある上でさらに何か書いてから、というのはスプライトの範疇を超えているような気がしてきました。

そして、オフスクリーンに一旦描画していたのは、
alphaが設定されている時にrenderイベントで描画されたものをどうするかという問題があったからです。
(renderイベントでscreenに直接半透明で描いてしまうと、背景が透けてしまう)

そうすると、「保持している画像を適宜図形変換させて指定されたTextureに描画する」という単純な機能だけで良さそうです。
(純正のものと同じです)


> EventHandleable とか?
EventTriggerableとか、EventObservableなんかも考えました。
何かもう少し一言で表せる何かがあると良いんですけどねー。


> Eventable を使用して、こんなに簡潔に書けるようになった、というサンプルがやっぱりほしいです。

> イベントと同様に、実際のサンプルを見てみたいです。
> フレームワークは、実際のゲームを作りながら考えていったほうが、
> 必要十分なものができると思うのですがいかがでしょうか。

そうですね。サンプル重要。
もう少しゲームっぽいものを作りながら考えていきたいと思います。


> 実は、 options 引数が省略されたときに、オプション関係の処理を飛ばす
> ようになっています。

これはやはりそうですね。
Spriteの描画でもちゃんと無視するようにしたほうが良さそうです。
OptionのHashは最初に持っておいて、プロパティへの代入の際にHashも更新するようにすれば描画時の処理が減って良いかと思います。


> ふむー、モジュールをいったんかむと遅くなってしまうのですね。
> 効率を考えるとモジュールや継承を避けたほうがいいのかなあ。

http://isaisstillalive.googlepages.com/hook.rb
call方式とalias方式のHook比較をしてみましたが、alias方式の方がはやいようです。
ベタ書きが一番早いことは確かだと思いますが。
ここらへんはもう少し調査してみないとわからないですね。
updateの前後に実行するメソッドを配列か何かで持っている、という手段も考えられます。


> * require 'lib/...' が気になりました (パスと名前空間が一致してない)。
> $LOAD_PATH に './lib' を加えてしまうのはどうでしょう。

それはmain.rbの話ですね。
基本のローダにしたいのでそこまでパスを含めてしまいましょうか。


> * Loadable についてですが、文字列 (String) で指定するのに比べて
> どのようなメリットがあるのかありますか。
> 定数でとってしまうのはいろいろトラブルになりそうな気がしますが。

あまり利点はないかもしれないですねー。
Pathだけ保持するようにして、簡単にアクセスできる、程度でも良いかと思われます。

ローダが存在するのは、exerbで固める際に、
exyファイルにデータのパスを全て含める機能を付けたいと思ってるからです。
http://exerb.sourceforge.jp/man/doc/recipe.ja.html#0304
暗号化はできませんが、まとめてexeにしてしまうだけでもある程度の効果はあるんじゃないかと思っています。


> * 点をあらわすのを Vector でやっていますが、やっぱり配列で十分な気がします
> (もうそうなっていると思われますが)。
> Vector (Matrix) は Ruby べた書きなので速度面では期待できません。

配列で十分だと思いました(笑)
むしろ、@x,@yプロパティにして、positionをメソッドにしちゃっても良いですね。
def position; [@x, @y]; end


> * Animatable モジュールは Eventable モジュール include 前提ですか?

そうです。
汎用的な描画メソッド(to_texture等)が存在すればそこにホックをかけても良いかと思っているのですが、
どちらにせよupdateイベントがないとアニメのフレームを自動更新できないんですよね。

Sprite::Managableが実装されてスプライト管理ができるようになれば、SpriteにEventableはいらなくなりそうな予感。


> * Movable モジュールは分ける必要あったのでしょうか。
> Sprite クラスに組み込みにしてもよかったんじゃないかなあ。

移動しないオブジェクトもスプライトで表示すると思うので、そういった場合にincludeしなければ速度面で有利かなと思ったんですが、
移動するオブジェクトの際に速度面で有利なほうが現実的ですね。
組み込みにしちゃいましょうか。

Hajime Hoshi

unread,
Jul 4, 2008, 7:28:01 AM7/4/08
to star...@googlegroups.com
星です。

>> Texture の子クラスであるという縛りをつけてまでそれが嬉しいかというと
>> 僕はちょっと疑問です。
>
> 良く考えると、スプライトにはrenderイベントはいらないかもしれませんね。
> 背景がある上でさらに何か書いてから、というのはスプライトの範疇を超えているような気がしてきました。
>
> そして、オフスクリーンに一旦描画していたのは、
> alphaが設定されている時にrenderイベントで描画されたものをどうするかという問題があったからです。
> (renderイベントでscreenに直接半透明で描いてしまうと、背景が透けてしまう)
>
> そうすると、「保持している画像を適宜図形変換させて指定されたTextureに描画する」という単純な機能だけで良さそうです。
> (純正のものと同じです)

Texture#render_texture のオプション云々を管理してくれるクラスとして、
それに専念するということでしょうか。

>> * Loadable についてですが、文字列 (String) で指定するのに比べて
>> どのようなメリットがあるのかありますか。
>> 定数でとってしまうのはいろいろトラブルになりそうな気がしますが。
>
> あまり利点はないかもしれないですねー。
> Pathだけ保持するようにして、簡単にアクセスできる、程度でも良いかと思われます。

むしろ定数名とファイル名がかぶってしまえるのがちょっと怖いなあと。

> ローダが存在するのは、exerbで固める際に、
> exyファイルにデータのパスを全て含める機能を付けたいと思ってるからです。
> http://exerb.sourceforge.jp/man/doc/recipe.ja.html#0304
> 暗号化はできませんが、まとめてexeにしてしまうだけでもある程度の効果はあるんじゃないかと思っています。

Exerb と似たようなもので rubyscript2exe っていうものがあるのですが、
ディレクトリを tar で固めて exe にしてくれたりします。

>> * 点をあらわすのを Vector でやっていますが、やっぱり配列で十分な気がします
>> (もうそうなっていると思われますが)。
>> Vector (Matrix) は Ruby べた書きなので速度面では期待できません。
>
> 配列で十分だと思いました(笑)
> むしろ、@x,@yプロパティにして、positionをメソッドにしちゃっても良いですね。
> def position; [@x, @y]; end

それはいいですね。取得も直感的。
x, y = hoge.position

>> * Animatable モジュールは Eventable モジュール include 前提ですか?
>
> そうです。
> 汎用的な描画メソッド(to_texture等)が存在すればそこにホックをかけても良いかと思っているのですが、
> どちらにせよupdateイベントがないとアニメのフレームを自動更新できないんですよね。

すると Animatable モジュールが Eventable モジュールを include すべきじゃないかと。

>> * Movable モジュールは分ける必要あったのでしょうか。
>> Sprite クラスに組み込みにしてもよかったんじゃないかなあ。
>
> 移動しないオブジェクトもスプライトで表示すると思うので、そういった場合にincludeしなければ速度面で有利かなと思ったんですが、
> 移動するオブジェクトの際に速度面で有利なほうが現実的ですね。
> 組み込みにしちゃいましょうか。

そのほうがよいかと思います。
もともと組み込みなら include のコスト云々考える必要もないですね。
(移動する / しない の区別をつける必要がそもそもあったのでしょうか。)

--
Hajime Hoshi <hajim...@gmail.com>

ISA

unread,
Jul 9, 2008, 12:02:10 AM7/9/08
to Star Ruby
Sprite::MovableをSpriteに統合し、Spriteクラスにフレームごとの移動量を持たせることにしました。

SpriteをTextureクラスのサブクラスにするのをやめ、
「一枚のTextureとそれを表示するためのオプション全てを管理するクラス」と再定義しました。

----
上記に伴い、Sprite::Animatableモジュールについても仕様変更を行おうと思っていて、
「Spriteのオプションを時間軸に沿って変更するモジュール」と再定義しようと思っています。

・複数の画像を横に並べた一枚の画像を、:src_xを変更して表示することでアニメーションさせることができる。
・「一瞬だけ光って元に戻る」といったエフェクトをループしないアニメーションのオン/オフで制御できる。
・フレームごとに角度を微妙に変更することで回転アニメーションができる。
 (回転は移動ではなくアニメーションになる)

といった表現が可能になります。

懸念点として、1番は表示するTextureを変更するのに比べて遅くなりそうな気がします。
オプションのほかに、表示するTexture自体も変更できるようにしたほうが良いかもしれません。

----
これを書きながら思いついたのですが、
一つのSpriteに複数のTextureをHashで保持することができるようになると、
RPGでの上下左右を向いた画像や、STGでの機体の傾きを管理するのが便利かもしれませんね。

アニメーションも、表示するキーを変更するだけになるので扱いが楽で良いかも。

----
> Exerb と似たようなもので rubyscript2exe っていうものがあるのですが、
> ディレクトリを tar で固めて exe にしてくれたりします。
tarで固めてくれるのは良いですね、そうするとわざわざレシピファイルを書き出さなくて良くなりますね。


> すると Animatable モジュールが Eventable モジュールを include すべきじゃないかと。
Eventableモジュールは、SpriteとSceneで同じことをしていたので抜き出しただけなんです。
ユーザがEventableモジュールをincludeして使うことは考えていないので、他のモジュールがincludeする必要はないと考えてま
す。

> むしろ定数名とファイル名がかぶってしまえるのがちょっと怖いなあと。
これについてですが、定数はLoadableモジュールをincludeしたモジュールのネームスペース下に作成されます。
これもEventableモジュールと同じく、画像、音声、シーンをそれぞれロードする必要があったために作成したモジュールですので、
あまり衝突はしないのではないかと考えています。

ISA

unread,
Jul 9, 2008, 11:35:03 AM7/9/08
to Star Ruby
http://isaisstillalive.googlepages.com/starframe_2.zip
Spriteクラス、Sprite::Animatableモジュールを修正したファイルを上げました。

----
今回の特徴はアニメーションです。
main.rbのうち、
・点滅しながらバウンドする星(alphaの変化)
・左上から右下まで弧を描くように動く音符(x,yの変化)
・背景の切り替え(src_xの変化)
をSprite::Animatableで行っています。

----
class AnimatedSprite < StarFrame::Sprite
animate 0, [0, 1, 2, 3] do |c|
self.x = c
end
end

のように、クラス定義内でanimateメソッドを使用することでアニメーションを作成することができます。

animateメソッドの引数は
・開始フレーム
・各コマでブロックに渡される値の配列
・コマの間隔(1で毎フレーム)
となり、同時に渡されたブロックが適宜実行されます。

コマ数は第二引数の配列サイズで、「コマ数×間隔」フレームでループします。
複数のアニメーションを定義することができ、その場合は一番長いものに合わせます。

----
また、第二引数の配列を簡単に作成するためにIntegerにメソッドを追加しています。
・linearメソッド
  0からselfの直前までを直線的に表した配列
  ex) 10.linear #=> [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
・accelerateメソッド
  0からselfの直前までを二次関数的な加速で表した配列
  ex) 10.accelerate #=> [0.0, 0.1, 0.4, 0.9, 1.6, 2.5, 3.6, 4.9, 6.4,
8.1]
・decelerateメソッド
  0からselfの直前までを二次関数的な減速で表した配列
  ex) 10.decelerate #=> [0.0, 1.9, 3.6, 5.1, 6.4, 7.5, 8.4, 9.1, 9.6,
9.9]

※このあたりはStepManiaというDDR(ダンスゲーム)クローンのアニメーション機能を参考にしています。
http://foonmix.nothing.sh/foonplus_html/bganimations.html

Hajime Hoshi

unread,
Jul 10, 2008, 10:27:35 AM7/10/08
to star...@googlegroups.com
星です。

> Sprite::MovableをSpriteに統合し、Spriteクラスにフレームごとの移動量を持たせることにしました。
>
> SpriteをTextureクラスのサブクラスにするのをやめ、
> 「一枚のTextureとそれを表示するためのオプション全てを管理するクラス」と再定義しました。

了解です。

> 上記に伴い、Sprite::Animatableモジュールについても仕様変更を行おうと思っていて、
> 「Spriteのオプションを時間軸に沿って変更するモジュール」と再定義しようと思っています。
>
> ・複数の画像を横に並べた一枚の画像を、:src_xを変更して表示することでアニメーションさせることができる。
> ・「一瞬だけ光って元に戻る」といったエフェクトをループしないアニメーションのオン/オフで制御できる。
> ・フレームごとに角度を微妙に変更することで回転アニメーションができる。
> (回転は移動ではなくアニメーションになる)
>
> といった表現が可能になります。
>
> 懸念点として、1番は表示するTextureを変更するのに比べて遅くなりそうな気がします。
> オプションのほかに、表示するTexture自体も変更できるようにしたほうが良いかもしれません。
>
> ----
> これを書きながら思いついたのですが、
> 一つのSpriteに複数のTextureをHashで保持することができるようになると、
> RPGでの上下左右を向いた画像や、STGでの機体の傾きを管理するのが便利かもしれませんね。
>
> アニメーションも、表示するキーを変更するだけになるので扱いが楽で良いかも。

昔親子関係をもつスプライトというのを作ったことがありますが、
もしかしたら便利かもしれません。

> > すると Animatable モジュールが Eventable モジュールを include すべきじゃないかと。
> Eventableモジュールは、SpriteとSceneで同じことをしていたので抜き出しただけなんです。
> ユーザがEventableモジュールをincludeして使うことは考えていないので、他のモジュールがincludeする必要はないと考えてま
> す。

よくわからなかったのですが、 Animatable モジュールはユーザが include する可能性はありますか。

> > むしろ定数名とファイル名がかぶってしまえるのがちょっと怖いなあと。
> これについてですが、定数はLoadableモジュールをincludeしたモジュールのネームスペース下に作成されます。
> これもEventableモジュールと同じく、画像、音声、シーンをそれぞれロードする必要があったために作成したモジュールですので、
> あまり衝突はしないのではないかと考えています。

それもそうなんですが、モジュールを完璧に名前空間的に使うのには若干の不安があります。
include すれば上書きできてしまうので。
また、文字列よりも定数で扱うほうが決定的に便利だ、という点は特になさそうなのですが、
わざわざ定数にする必要はあったのかなーと思いました。
たとえば Image に [] 特異メソッドを定義して
texture = Image[:back_3x1]
とかでも十分できますよね。

> http://isaisstillalive.googlepages.com/starframe_2.zip
> Spriteクラス、Sprite::Animatableモジュールを修正したファイルを上げました。
>

> 今回の特徴はアニメーションです。
> main.rbのうち、
> ・点滅しながらバウンドする星(alphaの変化)
> ・左上から右下まで弧を描くように動く音符(x,yの変化)
> ・背景の切り替え(src_xの変化)
> をSprite::Animatableで行っています。
>
> ----
> class AnimatedSprite < StarFrame::Sprite
> animate 0, [0, 1, 2, 3] do |c|
> self.x = c
> end
> end
>
> のように、クラス定義内でanimateメソッドを使用することでアニメーションを作成することができます。
>
> animateメソッドの引数は
> ・開始フレーム
> ・各コマでブロックに渡される値の配列
> ・コマの間隔(1で毎フレーム)
> となり、同時に渡されたブロックが適宜実行されます。
>
> コマ数は第二引数の配列サイズで、「コマ数×間隔」フレームでループします。
> 複数のアニメーションを定義することができ、その場合は一番長いものに合わせます。

なるほど。時間軸にそって変わってゆくと。
だいごくんの Interval クラスと似ていますね。
ゲームにおいては「右に 10 ピクセル、上に 10 ピクセル、左に 10 ピクセル」などの
「普通の手続き型プログラムではでは表しにくい」動きが多かろうと思うのですが、
そこらへんは表現できますか。

> また、第二引数の配列を簡単に作成するためにIntegerにメソッドを追加しています。
> ・linearメソッド
> 0からselfの直前までを直線的に表した配列
> ex) 10.linear #=> [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
> ・accelerateメソッド
> 0からselfの直前までを二次関数的な加速で表した配列
> ex) 10.accelerate #=> [0.0, 0.1, 0.4, 0.9, 1.6, 2.5, 3.6, 4.9, 6.4,
> 8.1]
> ・decelerateメソッド
> 0からselfの直前までを二次関数的な減速で表した配列
> ex) 10.decelerate #=> [0.0, 1.9, 3.6, 5.1, 6.4, 7.5, 8.4, 9.1, 9.6,
> 9.9]

linear は Range オブジェクトでいいような気がします。
0...10
decelerate メソッドも Range#map でいけますね。
(0...10).map{|x| (x**2)/10.0}

個人的には既存クラスにメソッドを増やすのはあまり好きではなく、
よほど汎用的に使えるものではない限り、増やすのはどうかなーと思うのですが。

ところで、浮動小数点を加算してふやす形にすると、
丸め誤差が生じますがそこらへんどうでしょう。

> ※このあたりはStepManiaというDDR(ダンスゲーム)クローンのアニメーション機能を参考にしています。
> http://foonmix.nothing.sh/foonplus_html/bganimations.html

ほうほう。後で見てみます。

--
Hajime Hoshi <hajim...@gmail.com>

ISA

unread,
Jul 10, 2008, 1:55:01 PM7/10/08
to Star Ruby
> よくわからなかったのですが、 Animatable モジュールはユーザが include する可能性はありますか。

Animatableモジュールはユーザがincludeすることではじめて使用できます。

class StarFrame::Sprite
include StarFrame::Sprite::Animatable

animate ...
...
end
end

という形で使用します。

これは、第三者が作成したSpriteへの機能拡張をプラグイン形式で共有できるように
モジュール単位で機能を追加していこうと考えているためです。
全てincludeしておいてしまうと処理に時間がかかってしまうのでこうしてます。

ActiveRecordのように、includeは自動的に行われ
acts_as_xxxなどを実行したときのみその機能が登録される、
という方向性もあるとは考えてます。

----
> それもそうなんですが、モジュールを完璧に名前空間的に使うのには若干の不安があります。
> include すれば上書きできてしまうので。
> また、文字列よりも定数で扱うほうが決定的に便利だ、という点は特になさそうなのですが、
> わざわざ定数にする必要はあったのかなーと思いました。

定数にする利点は特に思いつかないので、
とりあえずは無くす方向で考えてみます。

----
> なるほど。時間軸にそって変わってゆくと。
> だいごくんの Interval クラスと似ていますね。
> ゲームにおいては「右に 10 ピクセル、上に 10 ピクセル、左に 10 ピクセル」などの
> 「普通の手続き型プログラムではでは表しにくい」動きが多かろうと思うのですが、
> そこらへんは表現できますか。

コンセプトは近いと思います。
こちらはSpriteのサブクラスに対して、それぞれ一種類しか定義できないのが欠点ですね。
アニメーションを使いまわせる&切り替えられる上手い手段が欲しいところです。
モジュールかなぁ。

上記の移動は
animate 0, 0...10 do
@x += 1
end
animate 10, 0...10 do
@y -= 1
end
animate 20, 0...10 do
@x -= 1
end
開始フレームをズラし、アニメーションを複数指定することで表現できます。
アニメーションを後ろに足していく指定方法ではないので、
開始フレームが重なってしまうと平行して実行されてしまうので注意が必要です。

----
> linear は Range オブジェクトでいいような気がします。
> 0...10
Rangeでも特別問題ありません思います。

個人的には、引数として渡される係数はFloat固定のほうが良いので、
(linearとaccelerate系で別に考えなくて良くなるので)
そうすると内部でeachを使用している関係上FloatのRangeは使用できなかったのです。

> decelerate メソッドも Range#map でいけますね。
> (0...10).map{|x| (x**2)/10.0}

Array.newの方が微妙に早かったので現在の実装になりました。

animateの第二引数はeachで回せれば何でも良いので、
Rangeを渡しつつブロック内で直接計算するのが一番わかりやすいですね。

> 個人的には既存クラスにメソッドを増やすのはあまり好きではなく、
> よほど汎用的に使えるものではない限り、増やすのはどうかなーと思うのですが。

他のモジュールを作成した際に汎用的に使えるかなと思ったのですが、
今のところ他で使えそうな予定がないんですよね。
Animatableモジュールでincludeされるメソッドでも良い気がします。

---
> ところで、浮動小数点を加算してふやす形にすると、
> 丸め誤差が生じますがそこらへんどうでしょう。

加算や減算をする場合は初期値が重要だと思うので、それをどこかに保存しておかなければなりませんね。
誤差に関しては、このブロックはインスタンスメソッドになるので、
animate 0, 0...10 do |c|
@x_animate += 1
@x = @x_animate*1.6
end
というように、間にIntegerのインスタンス変数をはさむのはどうでしょう。

そうするとわざわざ第二引数に「係数の配列」を設定する必要がなくなってしまう気はしますが。
animate 0, [0x00, 0xFF] do |c|
self.alpha = c # 点滅
end
animate 0, 17.linear do |c|
self.tone = 256-16*c # 白く光って元に戻る
end
初期値が関係ないアニメーションならば係数を利用するほうが楽だと思います。

Hajime Hoshi

unread,
Jul 11, 2008, 1:48:59 AM7/11/08
to star...@googlegroups.com
星です。

> > よくわからなかったのですが、 Animatable モジュールはユーザが include する可能性はありますか。
>
> Animatableモジュールはユーザがincludeすることではじめて使用できます。
>
> class StarFrame::Sprite
> include StarFrame::Sprite::Animatable
>
> animate ...
> ...
> end
> end
>
> という形で使用します。
>
> これは、第三者が作成したSpriteへの機能拡張をプラグイン形式で共有できるように
> モジュール単位で機能を追加していこうと考えているためです。
> 全てincludeしておいてしまうと処理に時間がかかってしまうのでこうしてます。

> class StarFrame::Sprite
の部分は継承してオリジナルなクラスを作るのが正しいのかな?
class HogeClass < StarFrame::Sprite

Sprite が Eventable を元から include しているので、 Animatable が
Eventable を include してしまうと二重 include になってしまう、
ということでしょうか。なるほど。

Animation で、「Eventable を include してないならば include する」というのを
付け加えるのはどうでしょう。実際に動かしていませんが以下の要領でできるかと。
unless self.ancestors.include?(Eventable)
include Eventable
end

Sprite が Animatable を最初から include してもいいような気がしてきました。

> > なるほど。時間軸にそって変わってゆくと。
> > だいごくんの Interval クラスと似ていますね。
> > ゲームにおいては「右に 10 ピクセル、上に 10 ピクセル、左に 10 ピクセル」などの
> > 「普通の手続き型プログラムではでは表しにくい」動きが多かろうと思うのですが、
> > そこらへんは表現できますか。
>
> コンセプトは近いと思います。
> こちらはSpriteのサブクラスに対して、それぞれ一種類しか定義できないのが欠点ですね。
> アニメーションを使いまわせる&切り替えられる上手い手段が欲しいところです。
> モジュールかなぁ。
>
> 上記の移動は
> animate 0, 0...10 do
> @x += 1
> end
> animate 10, 0...10 do
> @y -= 1
> end
> animate 20, 0...10 do
> @x -= 1
> end
> 開始フレームをズラし、アニメーションを複数指定することで表現できます。
> アニメーションを後ろに足していく指定方法ではないので、
> 開始フレームが重なってしまうと平行して実行されてしまうので注意が必要です。

それは途中で挿入したくなった場合や、一部フレーム数が変更になった場合に厳しいのでは。

> > ところで、浮動小数点を加算してふやす形にすると、
> > 丸め誤差が生じますがそこらへんどうでしょう。
>
> 加算や減算をする場合は初期値が重要だと思うので、それをどこかに保存しておかなければなりませんね。
> 誤差に関しては、このブロックはインスタンスメソッドになるので、
> animate 0, 0...10 do |c|
> @x_animate += 1
> @x = @x_animate*1.6
> end
> というように、間にIntegerのインスタンス変数をはさむのはどうでしょう。
>
> そうするとわざわざ第二引数に「係数の配列」を設定する必要がなくなってしまう気はしますが。
> animate 0, [0x00, 0xFF] do |c|
> self.alpha = c # 点滅
> end
> animate 0, 17.linear do |c|
> self.tone = 256-16*c # 白く光って元に戻る
> end
> 初期値が関係ないアニメーションならば係数を利用するほうが楽だと思います。

ふーむ。
今のところ animate メソッドは、フレームごとにある規則にしたがって
更新される数値を使って、自身のプロパティをどうにかするというものですよね。

線形変化や二次関数的変化できるルーチンが用意されたとして、
ちょっとでもその用意されたものから離れたアニメ (更新) をしたくなった場合、
結局自分で書くことになりそうです。
すると極端な話、最初から何もない (単純に更新時に呼ばれるルーチンをユーザーが定義) か、
実際にゲームを作り分析した上で、必要だと思われるルーチンを抽出するかの
どちらかになると思います。
フレームワークとしてどこまで提供するのかは難しいですね。

アニメーションや、もっと一般的に「時間軸にそって更新されゆくもの」は
さまざまな表現がありますが (だいご君の Interval など)、
何がベストだというのはいまだにわからず、非常に興味深いものがあります。
(コルーチンでかけるのがもっとも自然だと思うのですが、
Ruby のコルーチン (もとい Continuation) は重くて使い物になりません。)

--
Hajime Hoshi <hajim...@gmail.com>

ISA

unread,
Jul 11, 2008, 1:34:03 PM7/11/08
to Star Ruby
> > class StarFrame::Sprite
>
> の部分は継承してオリジナルなクラスを作るのが正しいのかな?
> class HogeClass < StarFrame::Sprite
あー、そうです。すいません。

----
> Animation で、「Eventable を include してないならば include する」というのを
> 付け加えるのはどうでしょう。実際に動かしていませんが以下の要領でできるかと。
それは安全だとは思いますが、そこまでモジュールが面倒を見てしまってよいのかとも思います。
Eventableをincludeしていなければ例外を発生させるという手もあると思いますし、
eachなしのEnumerableと同様に、実行時に例外を投げるというのもありますね。

> Sprite が Animatable を最初から include してもいいような気がしてきました。
Movableと同じくそれでも良さそうな感じはしてます。
Animatableを最初からincludeしてしまうと、毎updateごとにフレーム数をカウントしているのでコストが気になるかもしれませ
ん。
animationが何もない場合はそこらへんを無視するようにすれば気にならないのかも?

----
> それは途中で挿入したくなった場合や、一部フレーム数が変更になった場合に厳しいのでは。
事前に作成しておいたアニメーションを実行する、という形のアニメーションしか考えてませんでした。
クラス定義で設定したアニメーション設定を、initialize実行時に内部で使いやすい形に変換してしまっているので動的に変更するのは難しいです
ね。
インスタンス単位でアニメーションを作成できるほうが便利なのかもしれません。


> すると極端な話、最初から何もない (単純に更新時に呼ばれるルーチンをユーザーが定義) か、
> 実際にゲームを作り分析した上で、必要だと思われるルーチンを抽出するかの
> どちらかになると思います。
> フレームワークとしてどこまで提供するのかは難しいですね。
そうですね。現状もユーザがupdateメソッド内に処理を書くのとほとんど同じですので。


> アニメーションや、もっと一般的に「時間軸にそって更新されゆくもの」は
> さまざまな表現がありますが (だいご君の Interval など)、
> 何がベストだというのはいまだにわからず、非常に興味深いものがあります。
> (コルーチンでかけるのがもっとも自然だと思うのですが、
> Ruby のコルーチン (もとい Continuation) は重くて使い物になりません。)
そこらへんは、Ruby1.9のFiberがあれば楽そうですね。
ゲームへの応用例もいくつかありますし。

http://mono.kmc.gr.jp/~yhara/d/?date=20080210
http://blogs.wankuma.com/myugaru/archive/2008/03/10/127059.aspx

1.8のEnumerable::Enumeratorで同じようなことができましたが、
内部でGeneratorを使用しているようで、さらにGeneratorは内部でcallccを使っているそうなので結局は重そうです。

Hajime Hoshi

unread,
Jul 12, 2008, 12:02:42 PM7/12/08
to star...@googlegroups.com
星です。

>> Animation で、「Eventable を include してないならば include する」というのを
>> 付け加えるのはどうでしょう。実際に動かしていませんが以下の要領でできるかと。
> それは安全だとは思いますが、そこまでモジュールが面倒を見てしまってよいのかとも思います。
> Eventableをincludeしていなければ例外を発生させるという手もあると思いますし、
> eachなしのEnumerableと同様に、実行時に例外を投げるというのもありますね。

まあ例外なげるならそうですね。
いまの状態だとうっかりエラーになるのが遅延するかなーと思って。

>> それは途中で挿入したくなった場合や、一部フレーム数が変更になった場合に厳しいのでは。
> 事前に作成しておいたアニメーションを実行する、という形のアニメーションしか考えてませんでした。
> クラス定義で設定したアニメーション設定を、initialize実行時に内部で使いやすい形に変換してしまっているので動的に変更するのは難しいです
> ね。
> インスタンス単位でアニメーションを作成できるほうが便利なのかもしれません。

動的に、もそうですけど、ゲームを作っている最中の変更にも弱いかなと思いました。

>> アニメーションや、もっと一般的に「時間軸にそって更新されゆくもの」は
>> さまざまな表現がありますが (だいご君の Interval など)、
>> 何がベストだというのはいまだにわからず、非常に興味深いものがあります。
>> (コルーチンでかけるのがもっとも自然だと思うのですが、
>> Ruby のコルーチン (もとい Continuation) は重くて使い物になりません。)
> そこらへんは、Ruby1.9のFiberがあれば楽そうですね。
> ゲームへの応用例もいくつかありますし。
>
> http://mono.kmc.gr.jp/~yhara/d/?date=20080210
> http://blogs.wankuma.com/myugaru/archive/2008/03/10/127059.aspx
>
> 1.8のEnumerable::Enumeratorで同じようなことができましたが、
> 内部でGeneratorを使用しているようで、さらにGeneratorは内部でcallccを使っているそうなので結局は重そうです。

1.8 は結局 Continuation になるのでとても重いです。
Fiber はあまりいじってませんが、その記事みる限りではいけそうですね。
1.8 でも拡張ライブラリレベルで Fiber を実現することは可能なのかなあ…。
調べてみます。

--
Hajime Hoshi <hajim...@gmail.com>

ISA

unread,
Jul 15, 2008, 11:02:05 AM7/15/08
to Star Ruby
http://isaisstillalive.googlepages.com/starframe_3.zip

StarRuby 0.3のGameクラスに対応しました。
が、まだメイン部分をフレームワーク内で綺麗に動かす部分を作っていないのでサンプルはすべて外出しです。

その他いろいろ修正+サンプルを作成しました。

今回サンプルを作っていて足りない部分、使いづらい部分がわかってきたので、
やはり現実的なものを作っていくことは大事だと実感しました。

----
> > Eventableをincludeしていなければ例外を発生させるという手もあると思いますし、
> まあ例外なげるならそうですね。
> いまの状態だとうっかりエラーになるのが遅延するかなーと思って。
Animatableインクルード時に、Eventable(仮)がインクルードされていなければ例外を発生させるようにしました。

----
> 動的に、もそうですけど、ゲームを作っている最中の変更にも弱いかなと思いました。
コルーチンは1.9のFiberを待つとして、animationの仕様を変更しました。
・Spriteごとにアニメーションを複数持つことができるようになった(オンオフもアニメーションごとに行える)。
・アニメーション定義ではフレームを最後に追加していくという形になった。
・並列でフレームを追加できるようになった。

# アニメーションを追加する
animate :name do
# 10フレーム分の処理を実行する
frames 0...10 { |c| }

# 5フレーム分の間を空ける
wait 5

# 並列ブロック内の
parallel do
# この20フレーム分の処理と
frames 20 { |c| }

# この直列ブロック内(10+5フレーム分)の処理を同時に実行する
serial do
frames 10 { |c| }
frames 5 { |c| }
end
end

# 最後に1フレーム分の処理を実行する
frame {}
end

並列化機能の作成にあたり、DaigoさんのIntervalモジュールを参考にさせていただきました。
ありがとうございます。そして勝手に参考にしてしまって申し訳ありません。

同梱されている「samples/stg」がアニメーション機能を現実的に使用したサンプルになります。

hajimehoshi

unread,
Jul 17, 2008, 10:40:22 AM7/17/08
to Star Ruby
星です。

$LOAD_PATH << "../lib" よりも、実行時に -I../lib としたほうが綺麗かなあ。
(コマンドオプションを知らない人は実行できなくなりますが…)

Symbol#to_proc は Ruby 1.8.6 だとまだありませんが、 1.8.6 の人はまだ多数派だと思います。
次のように回避してみては如何でしょう。

class ::Symbol
unless defined? to_proc
def to_proc
proc {|x| x.send(self)}
end
end
end

アニメーションの API はなかなかいいかもしれませんね。
いまのところ :roll や :move など、スプライトに特化したものになっていますが
(Sprite クラスなので当たり前ですが)、もっと汎用化できれば便利かも。

> 並列化機能の作成にあたり、DaigoさんのIntervalモジュールを参考にさせていただきました。

だいごくんも参考にしてもらえて喜んでいるみたいです。

ISA

unread,
Jul 22, 2008, 9:56:10 AM7/22/08
to Star Ruby
Collision系をまとめて修正しました。
http://isaisstillalive.googlepages.com/starframe_4.zip

----
> $LOAD_PATH << "../lib" よりも、実行時に -I../lib としたほうが綺麗かなあ。
> (コマンドオプションを知らない人は実行できなくなりますが…)
これはソースに書いておくほうが良いと思いますね。
実行時にオプションを渡すのは面倒ですし、敷居が高くなってしまうかと。

----
> Symbol#to_proc は Ruby 1.8.6 だとまだありませんが、 1.8.6 の人はまだ多数派だと思います。
> 次のように回避してみては如何でしょう。
ありがとうございます。
1.8.6に対応しておくのは悪くないですし、そのまま拝借させていただいてよろしいですか?

----
> アニメーションの API はなかなかいいかもしれませんね。
> いまのところ :roll や :move など、スプライトに特化したものになっていますが
> (Sprite クラスなので当たり前ですが)、もっと汎用化できれば便利かも。
stgサンプルでやっているのですが、Sceneにも適用できるんですよね。
Spriteネームスペースではなく他、たとえばEventable(仮)モジュールとかに移すのが良い気がしています。

----
> > 並列化機能の作成にあたり、DaigoさんのIntervalモジュールを参考にさせていただきました。
> だいごくんも参考にしてもらえて喜んでいるみたいです。
いえ、こちらこそありがとうございます。

hajimehoshi

unread,
Jul 23, 2008, 5:40:37 AM7/23/08
to Star Ruby
星です。

取り急ぎ返事をば。

> ----> Symbol#to_proc は Ruby 1.8.6 だとまだありませんが、 1.8.6 の人はまだ多数派だと思います。
> > 次のように回避してみては如何でしょう。
>
> ありがとうございます。
> 1.8.6に対応しておくのは悪くないですし、そのまま拝借させていただいてよろしいですか?

どうぞどうぞ。

Daigo

unread,
Jul 24, 2008, 5:19:12 PM7/24/08
to Star Ruby
こんにちは、だいごです。

ISAさん >
確認なのですが、まだ、1.8.6には対応していないのですよね?
試してみたのですが、動作しませんでした。
これは、シューティングゲームですか?

animationの機能が売りだと思うのですが、この機能はスプライトにのみ適用するよう設計されているのでしょうか?
スプライトに限定しない利用が出来たら、便利だろうなぁ と思います。
例えば、音楽のフェードイン・フェードアウトなども、このアニメーション機能のようなものを利用して実装できるように思います。現在のところどうお考え
でしょうか?もちろんスプライト限定ゆえの便利さもあるとは思いますが。mix-inで機能を拡張できるあたりが、便利な予感がします。

ISA

unread,
Jul 24, 2008, 7:21:29 PM7/24/08
to Star Ruby
> 確認なのですが、まだ、1.8.6には対応していないのですよね?
> 試してみたのですが、動作しませんでした。
> これは、シューティングゲームですか?

そうです。
やはり1.8.6に対応していないのは使用してもらえる環境が限定されてしまうので問題ですね。
すぐ対応します。

----
> animationの機能が売りだと思うのですが、この機能はスプライトにのみ適用するよう設計されているのでしょうか?
> スプライトに限定しない利用が出来たら、便利だろうなぁ と思います。
> 例えば、音楽のフェードイン・フェードアウトなども、このアニメーション機能のようなものを利用して実装できるように思います。現在のところどうお考え
> でしょうか?もちろんスプライト限定ゆえの便利さもあるとは思いますが。mix-inで機能を拡張できるあたりが、便利な予感がします。

Classにインスタンスメソッドを追加してupdateのタイミングで定期的に実行するというだけなので、
Eventable(仮)さえincludeしてあればどのクラスでも使用できます。
実際、STGサンプルでもSceneにincludeして敵の出現を管理してたりしてます。

また、現在作成中のサンプルに至っては盤面を管理する新規クラス(フレームワークとは無関係)に、
EventableとAnimatableをincludeしてアニメーションをさせています。

なので、Animatableモジュールは将来的にはSpriteネームスペースから外したいですね。
# というか、Animatableという名前も悪いかも?

Spriteに特化したSprite用拡張モジュール(Collidableなど)とは別に、
Eventableさえincludeしていれば動く汎用的な拡張モジュールという位置づけにしたいと考えています。

ISA

unread,
Jul 24, 2008, 8:12:39 PM7/24/08
to Star Ruby
http://isaisstillalive.googlepages.com/starframe_5.zip

Symbol#to_proc等を修正した最新バージョンを上げてみました。

軽く調べてはみたのですが、1.8.6の環境がないので他がよくわかりませんでした。
お手数でなければエラーが出る箇所を教えて頂けませんか?

hajimehoshi

unread,
Jul 30, 2008, 10:54:17 AM7/30/08
to Star Ruby
星です。

先日の Symbol#to_proc の実装には欠陥がありまして、 Enumerable#inject に与えるとバグります。

(1..2).inject(&:+)

以下のように定義すれば直ります。上司 (というか教員) の作です。

class Symbol
def to_proc
proc { |*args|
(args.shift).__send__(self, args)
}
end
end

Hajime Hoshi

unread,
Jul 31, 2008, 5:50:06 AM7/31/08
to Star Ruby
星です。

間違い発見!

> (args.shift).__send__(self, args)

(args.shift).__send__(self, *args)

でした。


--
Hajime Hoshi <hajim...@gmail.com>

Reply all
Reply to author
Forward
0 new messages