Ruby/SDL FAQ
Ruby/SDLのFAQ(よくある質問と答)です。 ほとんど項がありませんが追々増やしていきます。
Q. FreeBSDでうまく動作しない
FreeBSDにRuby/SDLをインストールしたのですが、
/usr/libexec/ld-elf.so.1: /usr/local/lib/libSDL-1.1.so.4: Undefined symbol "pthread_mutexattr_init"
というメッセージがでてうまく動きません。
A. ruby_rを使いましょう
ruby_rというrubyにpthread関連のライブラリをリンクしたものがあります。 こちらを使えばうまく動作するでしょう。ruby_rはPortsやPackagesから インストールできます。最新のportではこちらを利用するようになっています。
Q. スレッドを使いたい
SDLにはスレッドを利用する関数があります。これを利用したいのですが。
A. 使えません
Rubyでは外部のスレッドを安全に利用する方法は存在しません。どうしても スレッドが使いたければRubyのを使ってください。どちらかというと 設計をスレッドを使わないものにしたほうが良いでしょう。
Q. スクリプトがきちんと停止しない
Linux上でSDL::Mixerを使って音声を再生した後、スクリプトを終了させようとしても きちんと終了しない。
A. --disable-pthreadsを使う、もしくはシグナルをトラップする
Lorien Dunnさんからの情報によると、 シグナルの扱いに問題があるためこの問題が生じるらしいです。 対策は2つあり、 ひとつはREADMEにあるようにSDLをconfigureするときに--disable-pthreadsをわたす、 もうひとつは以下の内容をスクリプトの最初に書く、です。
require 'rbconfig' if RUBY_PLATFORM =~ /linux/ trap('INT','EXIT') trap('EXIT','EXIT') end
これで「uninitialized constant EXIT (NameError)」というエラーがでる場合は、
require 'rbconfig' if RUBY_PLATFORM =~ /linux/ trap('EXIT','DEFAULT') end
というのを使うと良いようです。
Q. Ruby/SDLがMacOSXで動かない
MacOSXでRuby/SDLをインストールしても動かない。
A. Cocoaアプリケーションとしての初期化が必要です。
MacOSXで動かす場合、Cocoaアプリケーションとしての初期化をあらかじめしておく 必要があるようです。 詳しくは布川さんのページ <URL:http://www2s.biglobe.ne.jp/~nunokawa/wiki.cgi?page=Ruby%2FSDL+on+Mac+OS+X> を見てください。
また、パッチを当てたruby処理系のソースがRuby/SDL用rubyにあります。
さらに <URL:http://mono.kmc.gr.jp/~mak/hiki/?mac_ruby_sdl>に を参照してください。OSXでRuby/SDLを動かすための総合的なドキュメント があります。
Q. もっと高速に動作させたい
動作が遅いのでもっと高速にしたい。
A. 様々な対策があります。
一番時間がかかるのは描画部分です。以下のような工夫をすることでその部分を 高速化できるでしょう。
ハードウェアサーフィスを使う
SDL.setVideoModeの第四変数に SDL::HWSURFACE|SDL::FULLSCREEN を指定することで 描画が高速になります。WindowsではDirectDraw、XではDGAを使うようになります。 ソフトウェアサーフェスの数倍から数十倍の高速化が期待できます。
SDL::Surface#displayFormatで高速描画可能な状態にしておく
特に上で挙げたハードウェアサーフィスを使う場合はこれで相当高速になります。
SDL.blitSurface, SDL::Surface#put, SDL::Surface.fillRectのみを使う
これ以外の描画関数(drawLine, drawRectなど)はサーフィスのロックが 必要なため遅くなります。
拡大縮小回転はあらかじめしておく
これらの操作は非常に低速です。 あらかじめ必要な変形をしておき、SDL::Surface#displayFormatで高速描画 可能な形式に変換しておくとよいでしょう。
アルファブレンディングは最小限にする
アルファブレンディングもかなり遅いので使用は少なくしたほうが高速になります。
OpenGLを使う
上で挙げた方法を使えば確かに高速になりますが、そうすると描画に非常に制限が かかります。OpenGLを使えばビデオカードのアクセラレーション機能を使えます。 そのおかげで回転縮小拡大変形アルファブレンドが十分実用的な速度で可能になります。
OpenGLで2D描画をするにはGL::Orthoを使うとよいでしょう。
また OpenGL を使う場合の注意として、SDLの2D描画機能が使えないことを 挙げておきます。
Q. 音声の再生に遅延が発生する
SDL::Mixer.playChannelで再生しようとしてから実際に再生されるまでに 0.1秒くらいの遅延が発生する。
A. SDL::Mixer.openの引数を調整する
SDL::Mixer.open の引数を調整することでこの問題が解決する可能性があります。 第一変数を 44100 や 22050にしてみたり、第4変数を小さくしてみたりしてください。
Q. MP3が再生できない
<URL:http://www.kmc.gr.jp/~ohai/rubysdl_download.html> で配布しているバイナリを使って SDL::Mixer::Music.load で mp3 をロードできません。
A. 仕様です
Windowsでのビルドシステムの関連上 1.1.0 の Windows用のバイナリでは mp3 をロードできません。ogg vorbis を代わりに利用してください。 だだまあ1.3.0では動くはずです。 もしくは自分でRuby/SDLや各種依存ライブラリを一からコンパイルしてください。
Q. 加算合成をしたい
加算合成をしたいのですがそのようなメソッドはありませんか?
A. SDLでは対応できません
SDLが対応していないので使えません。単に動くようにするのは難しくない のですが他のメソッドとの整合性をとるのが難しいので実装していません。 OpenGLを使うと加算合成も高速にできるはずなのでこちらがおすすめです。
Q. SDL::Event.waitを呼ぶとスレッドが切りかわらない
Rubyでマルチスレッドのプログラムを書いたのですが SDL::Event.waitを呼ぶと全スレッドが停止してしまいます
A. Rubyのスレッドの仕様です
Rubyのスレッドはユーザランドスレッドで、SDL::Event.waitを呼んで 待っている間はスレッドが切り替わりません。 sleepとポーリングで対応してください。
Ruby 1.9.1以降ではネイティブスレッド利用に変わっているため、 最新のRuby/SDLを合わせて利用すればスレッドが切り変わります。
Q. Windowsでハードウェアアクセラレーションが有効になっていない
最近のSDLはWindowsでのハードウェアアクセラレーションが デフォルトでOFFになっています。 環境変数 SDL_VIDEODRIVER を directx に設定すると有効になるようです。 コマンドライン上で
set SDL_VIDEODRIVER=directx
とすればよいはずです。
このデフォルトは directx ドライバがノートPCなどでうまく動かない場合が あるためにこうなっています。つまりうまく動かない場合の想定が 必要です。