第15章 ラスタースクロール


0爆弾

 今回はラスタースクロールです。ラスタースクロールとは、横方向のスキャンライン毎にBGをドット単位で別々に横スクロールさせることです。 画面を2つ以上に分割したり、奥行きのある画面を表現したり、画面をうねうねと揺らすのに使用されるテクニックです。

 ファミコンは0番スプライトを画面に描画すると$2002の6ビット目が1になるという機能があり、非VBlank時にそのタイミングを拾うことができます。 そのタイミングでスクロールレジスタ$2005を変えると、その0番スプライトのY座標からBGをスクロールすることができます。 (通称「0爆弾」と呼ばれるらしい)また、0番スプライトとは無関係に、しばらくwait時間を置いてから スクロールレジスタを変更することにより、スキャンライン毎に別々にスクロールさせることができます。 スキャンライン(走査線)とは、画面を描画する横ラインのことです。画面に表示されるのは256でなく240ラインまでであることに注意してください。

 ちなみにVBlank割り込みは240ラインまで描き終えて画面外の仮想の241ライン目を描くタイミングで発生します。 そして仮想の262ラインまで描いてから0に戻ります。(私が調べた限り262までのようですが、なぜ262なのかは、わかりません) VBlank割込みで呼び出されるメインループでは、この262ライン描画までの間にVRAM更新処理を終わらせる必要があります。 0ラインに戻ると描画が始まるのでVRAMにアクセスすると画面が乱れます。 もっとも、ラスタースクロールは敢えてそれをやっておかしな画面にしているわけですが。

 0番スプライトの描画を待つのは、以下のようにします。


waitZeroSpriteClear:			; 0番スプライト描画前まで待つ
	bit $2002
	bvs waitZeroSpriteClear		; $2002の6ビット目が0になるまで待つ
waitZeroSpriteHit:			; 0番スプライト描画まで待つ
	bit $2002
	bvc waitZeroSpriteHit		; $2002の6ビット目が1になるまで待つ

 bitは指定したメモリの値のビット7,6を調べるための命令です。指定したメモリの値のビット7は ステータスレジスタのNフラグにセットされ、ビット6はV(オーバーフロー)フラグにセットされます。 上の例のように、Vフラグの結果により分岐するbvs,bvcと組み合わせて使うと効率が良いです。

 0番スプライトヒット後は、適当にwaitをかけたり$2005にスクロール値を書き込むなりして、 好きなようにライン毎に別々の速さの横スクロールを実行することができます。 どのような命令でどのくらいのwaitで何ライン飛ばせるのかは、私にははっきりわからないので、 wait時間を調整するなり、6502を詳しく調査してみるなりしてください。

 0番スプライト描画を待たずに0ライン目からいきなりラスタースクロールすることも可能です。 上の例だと、waitZeroSpriteHitに初めて来た時点ではスキャンラインは0ラインですから、 そこからウエイトをかければ0番スプライトを使う必要はありません。 とはいえ、画面の真ん中〜下からラスタースクロールさせるなら、 0番スプライトを使うほうがウエイトで調整しなくて済むのでやりやすいということです。

ラスタースクロールサンプル

 これをダウンロードして、nesasm giko015.asmしてください。 地面が三段に分かれて別々の速度でスクロールします。0番スプライトは普通は透明にして隠すはずですが、 わかりやすいようにわざと表示しています。

 どうでしょうか?奥行きがあるように見えませんか?・・見えませんね。木や建物を置かないとだめでしょうねえ。

 ラスタースクロール自体はこのように結構簡単にできるのですが、これをゲーム中にやるとなると、 wait時間の間にゲームの処理を毎回必ず同じ時間で実行しなきゃらならないでしょうし、かなりの困難を強いられますね。 その辺が、ラスタースクロールは凄い!ということになるんでしょう。

 なお、この章ではX方向のスクロールだけを操作しましたが、Y方向をいじると絵を縦に伸び縮みさせるような表現などができます。 そのうちこのサイトでもやってみる かもしれない。


トップページ 前のページ 次のページ
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送