2013/12/11(水) [n年前の日記]
#5 [dxruby][game] DXRubyで安直な画面フラッシュを試してみる
今日もDXRubyを使って何か書きますよ。と言っても、ゲーム制作をしてる人なら誰でも知ってそうな話ですけど…。
例えば、シューティングゲームやアクションゲームを作る時、敵の爆発時に画面をビカッと光らせたいな、一瞬だけ真っ白にしたいな、と思う時がありまして。要するに、画面をフラッシュさせたい時があるわけですよ。
昔のTVゲーム機だったら、画面の色は、全てパレットで管理されてたので、パレット内容を書き換えれば画面を真っ白にすることができました。1パレット16色で、1色2バイト使ってるなら ―― たった32バイトを書き換えるだけで、そのパレットを使って表示してる全てが真っ白になったわけです。 *1
でも、今のゲーム機って、パレットで色を管理〜なんてケチ臭いことしてないし。ちょっと書き換えれば全部の色が変わる、なんて仕組みじゃない。
じゃあ、どうするのかというと…。
かなり安直な方法ですが、画面全体に、真っ白な画像や、真っ黒な画像を、べた書きしちゃえばええやん、みたいな。どうせ今時のハードウェアは、強力なハードウェア描画機能を持ってますから、そのくらいなら描画処理時間もさほど影響ないやろと。
てなわけで、一応自分もサンプルを書いてみました。
実に安直ですが、それらしく見えてるし、コレで済んじゃう場合もあるんじゃないかなと。どんな方法でも、60FPSが維持できていれば、それでOKじゃないかしらん。
しかし。この方法では、例えば敵に自機の弾が当たった時に、敵だけフラッシュさせるとかできないわけですよ。
じゃあ、どうするかというと。
スイマセン。思いつきません…。明日までに考えておきます…。というか、DXRubyのシューティングゲームサンプルで、そういう処理してましたよね…?
それはそれとして。この、安直な画面フラッシュ。他のライブラリでもフツーに使えるやり方なので、こうして書いてしまいましたが。DXRuby の場合は HLSL という機能があるわけで。DXRuby のサンプルにも、sample_flash.rb という、そのものズバリがありますし。そっちを勉強しといたほうが応用効くんじゃないのかな、と思えていたりもするのでした。
例えば、シューティングゲームやアクションゲームを作る時、敵の爆発時に画面をビカッと光らせたいな、一瞬だけ真っ白にしたいな、と思う時がありまして。要するに、画面をフラッシュさせたい時があるわけですよ。
昔のTVゲーム機だったら、画面の色は、全てパレットで管理されてたので、パレット内容を書き換えれば画面を真っ白にすることができました。1パレット16色で、1色2バイト使ってるなら ―― たった32バイトを書き換えるだけで、そのパレットを使って表示してる全てが真っ白になったわけです。 *1
でも、今のゲーム機って、パレットで色を管理〜なんてケチ臭いことしてないし。ちょっと書き換えれば全部の色が変わる、なんて仕組みじゃない。
じゃあ、どうするのかというと…。
かなり安直な方法ですが、画面全体に、真っ白な画像や、真っ黒な画像を、べた書きしちゃえばええやん、みたいな。どうせ今時のハードウェアは、強力なハードウェア描画機能を持ってますから、そのくらいなら描画処理時間もさほど影響ないやろと。
てなわけで、一応自分もサンプルを書いてみました。
# 画面を白く、あるいは黒く(?)、フラッシュさせる。(安直版) require 'dxruby' Window.resize(320, 240) bgimg = Image.load("bg.jpg") whiteimg = Image.new(Window.width, Window.height, C_WHITE) blackimg = Image.new(Window.width, Window.height, C_BLACK) white_alpha = 0 black_alpha = 0 Window.loop do break if Input.keyPush?(K_ESCAPE) Window.draw(0, 0, bgimg) if Input.mousePush?(M_LBUTTON) # マウス左ボタンがクリックされた white_alpha = 255 end if Input.mousePush?(M_RBUTTON) # マウス右ボタンがクリックされた black_alpha = 255 end if white_alpha > 0 # 画面全体に、真っ白な画像を、透明度を変えながら描画する Window.drawAlpha(0, 0, whiteimg, white_alpha) white_alpha -= 5 end if black_alpha > 0 # 画面全体に、真っ黒な画像を、透明度を変えながら描画する Window.drawAlpha(0, 0, blackimg, black_alpha) black_alpha -= 5 end end
実に安直ですが、それらしく見えてるし、コレで済んじゃう場合もあるんじゃないかなと。どんな方法でも、60FPSが維持できていれば、それでOKじゃないかしらん。
しかし。この方法では、例えば敵に自機の弾が当たった時に、敵だけフラッシュさせるとかできないわけですよ。
じゃあ、どうするかというと。
スイマセン。思いつきません…。明日までに考えておきます…。というか、DXRubyのシューティングゲームサンプルで、そういう処理してましたよね…?
それはそれとして。この、安直な画面フラッシュ。他のライブラリでもフツーに使えるやり方なので、こうして書いてしまいましたが。DXRuby の場合は HLSL という機能があるわけで。DXRuby のサンプルにも、sample_flash.rb という、そのものズバリがありますし。そっちを勉強しといたほうが応用効くんじゃないのかな、と思えていたりもするのでした。
◎ フラッシュのさせ方。 :
そのまま何も考えずに、画面全体を単に白くフラッシュさせても、最低限の仕様は満たせるのですけど。
ちょっと気の利いた人ならば、いや、アニメオタクなプログラマーさんなら、おそらく、たまには、「黒」→「白」とか、「白」→「黒」とかフラッシュさせたりしてますよ、と、念のために書いておきます。TVアニメで画面フラッシュするカットをコマ送りしてみれば、このあたり、とても勉強になりますのでオススメです。結構いろんなタイミングのつけ方がありますので。
だけど、日本全国のちびっ子達がポケモンのアニメを見ていてバタバタと倒れたあの日から、そういうカットには放送局側が機械的にフィルタをかけてしまう、そんな状況になったので…。昔のアニメじゃないと、その手の小技を学べないかもしれない、という不安もあるのですけど。
いや、待てよ。逆に、今現在放送されてるアニメで、画面フラッシュしてるのに、フィルタがかからないとしたら…? ただそれだけでも、アニメスタッフさんが、何かノウハウを駆使してる可能性が高そうですね。そういうシーンをたまたま見かけたら、ソイツはお宝映像。要チェックですな。そこには、更に洗練された秘術が存在する…かもしれませんな…。
ちょっと気の利いた人ならば、いや、アニメオタクなプログラマーさんなら、おそらく、たまには、「黒」→「白」とか、「白」→「黒」とかフラッシュさせたりしてますよ、と、念のために書いておきます。TVアニメで画面フラッシュするカットをコマ送りしてみれば、このあたり、とても勉強になりますのでオススメです。結構いろんなタイミングのつけ方がありますので。
だけど、日本全国のちびっ子達がポケモンのアニメを見ていてバタバタと倒れたあの日から、そういうカットには放送局側が機械的にフィルタをかけてしまう、そんな状況になったので…。昔のアニメじゃないと、その手の小技を学べないかもしれない、という不安もあるのですけど。
いや、待てよ。逆に、今現在放送されてるアニメで、画面フラッシュしてるのに、フィルタがかからないとしたら…? ただそれだけでも、アニメスタッフさんが、何かノウハウを駆使してる可能性が高そうですね。そういうシーンをたまたま見かけたら、ソイツはお宝映像。要チェックですな。そこには、更に洗練された秘術が存在する…かもしれませんな…。
*1: と言っても、昔のゲーム機はめっちゃ遅かったんで、その程度のバイト数の書き換えも結構もったいなくて。パレットデータはVRAM上にあって、かつ、VRAMへのアクセスは垂直帰線期間(区間?)内に済ませておかないといけないけれど。VRAM上の値を読んで計算してまた書き戻して、なんてやってたら間に合わない。メインRAM上にパレット内容を持っておいて、そこであらかじめ計算しといて、VSYNC割り込みが来たら「今だ! 急げー!」とばかりに、VRAMに対しては上書きオンリーでひたすらDMA転送、てな感じの処理をしてたような気もします。…違ったっけ? たしかそうだったような。
ですので、パレットをたくさん持てるハードウェアなら、フラッシュ専用のパレットを持っておいて、スプライト等のパレット番号を切り替えるだけでフラッシュさせてた、そんな記憶もありまして。
パレットが少ないハードウェアでは、誰かが使ってるパレットを、中身を気にせず無理矢理流用して別の色に変えてたり。…そんなことをしてたので、某ゲームは、赤と青が激しく点滅する、今では絶対販売禁止であろうポケモンフラッシュ画面になっていたのでした。
ですので、パレットをたくさん持てるハードウェアなら、フラッシュ専用のパレットを持っておいて、スプライト等のパレット番号を切り替えるだけでフラッシュさせてた、そんな記憶もありまして。
パレットが少ないハードウェアでは、誰かが使ってるパレットを、中身を気にせず無理矢理流用して別の色に変えてたり。…そんなことをしてたので、某ゲームは、赤と青が激しく点滅する、今では絶対販売禁止であろうポケモンフラッシュ画面になっていたのでした。
[ ツッコむ ]
以上です。