12.ビットマップとキャッシュ
1.画像の作成
ビットマップを作成する方法は2種類あります。
まず、画像ファイルを読み込む方法です。
# 予め用意された画像を読み込む
bitmap = Bitmap.new("Graphics/System/Window")
そして、サイズを設定して透明な画像を作る方法です。
# 透明な画像を作る
bitmap = Bitmap.new(320, 240)
画面に画像や文字を表示させるためには、このビットマップに描画する必要があります。
また、それ以外の方法はありませんので、このクラスの使い方がわかれば、
Window_Base や Sprite など、どのようなスプライトのクラスを使用しても
思い通りの内容が描画できるようになると思います。
2.文字の描画
文字を描画するのは、Bitmap#draw_text メソッドです。
canvas = Bitmap.new(320, 320)
canvas.draw_text(canvas.rect, "Hello, World!")

sp = Sprite.new
sp.bitmap = canvas
Graphics.wait(120)
sp.bitmap.dispose   # 画像を消去
sp.dispose          # スプライトを消去
これで、中央に文字が表示されます。
Bitmap オブジェクト canvas が解放されてないよ!
って思った方は、一番最後の行にp canvas.disposed?を付け加えて確認してください。
trueと表示されると、解放されているということです。
どこで消されたのかというと、sp.bitmap.dispose というところですね。
sp.bitmap というのは、canvas を指します。
これはほら、会社では社長と呼ばれ、家ではお父さん、友人には太郎と呼ばれるのと同じです。
太郎さんが消えれば、会社での社長も消え、家でのお父さんも消えてしまうということですね。
なんか怖い喩えでした。。。
3.塗り潰し処理
Bitmap#fill_rect, Bitmap#gradient_fill_rect, Bitmap#set_pixel
これらのメソッドを使うと指定位置の色を変更することができます。
注意点は、色を変更するのであって、描き加えるわけではないという点です。

例えば、赤い画像を用意して半透明な青で塗り潰すとします。
結果は、紫ではなく半透明の青の画像になります。
透明な色で塗り潰せば、Bitmap#clear と同じ効果があります。
bitmap = Bitmap.new(544, 416)
# 赤
bitmap.fill_rect(bitmap.rect, Color.new(255,0,0))
# 半透明な青
bitmap.fill_rect(bitmap.rect, Color.new(0,0,255,128))
# 透明な画像に
bitmap.fill_rect(bitmap.rect, Color.new(0,0,0,0))
※ gradient_fill_rect(x, y, width, height, color1, color2[, vertical]) には、
vertical の引数が機能しない不具合があります。 (修正済)
4.キャッシュ
この機能の説明は、[スクリプト入門]-[解読編]-[Cache モジュール] に書かれています。

一度読み込んだ画像を変数に保存して、次回からの呼び出しの際はこの画像を表示します。
ファイルから読み込む必要がなくなるので、処理が高速化します。
生成した画像を保存しているだけなので、これもビットマップオブジェクトです。
Cache は、画像の種類ごとにメソッドが違うので、フォルダ名を含めずに画像を指定することができます。
つまり、Bitmap.new("Graphics/Pictures/ファイル名") と Cache.picture("ファイル名") は、
同じファイルの画像を取得できます。
cache = Cache.system("Window")
# キャッシュは、不要になっても解放しない
cache.dispose # ×

キャッシュの注意するところは、キャッシュを使って呼び出された画像は
すべて同じオブジェクトであるというところです。
つまり、この画像に何かを描画したりすると、このキャッシュを使用している場所、
これから使用する際に編集された画像がそのまま表示されてしまうことになります。
cache = Cache.system("Window")
cache.fill_rect(cache.rect, Color.new(0,0,0))
sp = Sprite.new
sp.bitmap = cache
Graphics.wait(60)
sp.dispose
#~ cache.dispose
キャッシュを解放すると、次回はファイルから読み込み直します。
コメントアウトした状態とそうでない状態と比べてみてください。

キャッシュしている画像をどうしても編集したい場合は、
clone や dup を使用して画像をコピーしてください。
その際、その画像はキャッシュされているものとは別のものなので、
使用後に dispose するのを忘れないようにしましょう。
cache = Cache.system("Window")
copy = cache.dup
# キャッシュのコピーは、不要になったら解放する
copy.dispose # ○
5.今回のポイント
・画像や文字を書き込めるのは、Bitmap オブジェクトのみである。
・キャッシュは、一度読み込んだ画像をハッシュに保存したものである。
・キャッシュは、Bitmap オブジェクトである。
・キャッシュは、解放しない。
・キャッシュのコピーは、不要になったら解放する。