このページでは、筆者が過去に制作したロックマン6の改造作品から、原作にはないスクロール処理の使い方をしたものの事例を紹介します。なお、その性質上、筆者の改造作品についてのネタバレが含まれます。
原作での事例については、スクロール処理を読み解いてみるのページをご参照ください。そちらは既に読んでいるものとして、話を進めますのでご了承ください。
Rockman 6 After Tournamentのヤマトマンステージは迷路構造となっており、間違ったルートに進むと戻される、いわゆるループ構造になっています。その中で、同じ方向で別の部屋へ分岐するという構造の場所があります。
通常、分岐構造は別方向でなければ出来ませんが、1つの方向での分岐を実現しています。
同方向分岐について解説する前に、通常のデータ列定義スクロールについて解説します。
スクロール処理を読み解いてみるのページに書いたように、データ列定義スクロールは常時処理と同じタイミングで行われます。
データ列定義スクロールの1方向分の処理は以下のようになっています。
このような処理を、定義されている方向の数だけ行います。
スクロール方向別のサブルーチンのアドレスは、バンク$39の$9A88-$9A8Eと$9A8F-9A95に定義されています。
下表にまとめておきます。
スクロール報告 | アドレス | |
---|---|---|
01 | 下(部屋番号増加) | $D587 |
02 | 上(部屋番号増加) | $D612 |
03 | 下(部屋番号減少) | $D540 |
04 | 上(部屋番号減少) | $D5D1 |
05 | 右(部屋番号増加) | $D653 |
06 | 左(部屋番号減少) | $D6B3 |
これを定義されている方向別にそれぞれ実行します。
また、同じことを常時処理として記述することで、データ列定義スクロールと同じことができます。
さて、ここで同方向分岐に話を戻しましょう。
上記の通り、データ列定義スクロールは常時処理として自分で書くこともできます。つまり、ここで座標によってスクロール元部屋番号を分けることで、同方向分岐が実現できます。
再掲になりますが、下図のような分岐の場合の処理を見ていきます。
上の場合は部屋番号$01に、下の場合は現在の部屋番号+1に移動します。
これを実現するためには、以下のような処理を行います。
実際のコードは以下のようになっています。
86DA:02855700 ;スクロール定義 8557:A900 lda #$00 ; 8559:8573 sta $73 ;スクロール時のパターンテーブル書き込み番号 855B:8572 sta $72 ;スクロール時のパレット変更番号 855D:8D8706 sta $0687 ;スクロール時のパレット変更番号($72と同じ?) 8560:8D9706 sta $0697 ;スクロール元部屋番号 8563:ADCB04 lda $04CB ;Y座標(low)(ロックマン) 8566:1005 bpl $856D ; 8568:A557 lda $57 ;Scroll X(high) 856A:8D9706 sta $0697 ;スクロール元部屋番号 856D:4C53D6 jmp $d653 ;右スクロール処理
次は別方向の分岐についても見ていきます。考え方自体は先程と同じです。
左の場合は部屋$06、右の場合は部屋$0Cに移動します。
コードは以下のようになっています。
86E5:00857000 ;スクロール定義 8570:A900 lda #$00 ; 8572:8573 sta $73 ;スクロール時のパターンテーブル書き込み番号 8574:8572 sta $72 ;スクロール時のパレット変更番号 8576:8D8706 sta $0687 ;スクロール時のパレット変更番号($72と同じ?) 8579:AD8604 lda $0486 ;X座標(low)(ロックマン) 857C:1003 bpl $8581 ; 857E:A90B lda #$0B ; 8580:2C bit $05A9 ; 8581:A905 lda #$05 ; 8583:8D9706 sta $0697 ;スクロール元部屋番号 8586:4C87D5 jmp $D587 ;下スクロール(部屋番号増加)処理
ここでは座標によって分岐していますが、他の条件によって分岐させる手法も考えられるでしょう。
同方向分岐スクロールと似たような考え方の活用法です。筆者は同方向分岐スクロールもまとめて条件付きスクロールとして考えています。
Rockman 6 After TournamentのMr.Xステージ3は往復構成になっており、往路は通常状態、復路は上昇気流によって空中制動が水中と同じになります。
この往復は実際に同じ部屋を行き来しますが、上下移動を除いて後戻りが出来ないようになっています。これは、被弾ノックバックによって後戻りさせられるのが鬱陶しいためと、プレイヤーが迷わないように進路を固定化するための2つの理由があります。
前提条件として、After Tournamentでは上昇気流発生フラグが存在しており、このフラグが立っている間は水中挙動になるという仕様になっています。このフラグは$FFを使用しています。
往路復路のどちらであるかは、このフラグを見て判断します。
下の場所は横長スクリーンの左端ですが、往路では右に進むため左スクロールは発生せず、復路では左に進むため左スクロールが発生します。
同方向分岐と似たような考え方で、以下のような処理となります。
実際のコードは以下のようになっています。
8504:0180C500 ;スクロール定義 80C5:A5FF lda $FF ;上昇気流フラグ 80C7:D001 bne $80CA ; 80C9:60 rts ; 80CA:20D080 jsr $80D0 ;現在部屋基準のスクロール事前設定 80CD:4CB3D6 jmp $D6B3 ;左スクロール処理 ;現在部屋基準のスクロール事前設定 80D0:A557 lda $57 ;Scroll X(high) 80D2:8D9706 sta $0697 ;スクロール元部屋番号 80D5:A900 lda #$00 ; 80D7:8573 sta $73 ;スクロール時のパターンテーブル書き込み番号 80D9:8572 sta $72 ;スクロール時のパレット変更番号 80DB:8D8706 sta $0687 ;スクロール時のパレット変更番号($72と同じ?) 80DE:60 rts ;
次は同じ横長スクリーンの右端で、往路では右に進むため右スクロールが発生し、復路では左に進むため右スクロールは発生しません。
コードは以下のようになっています。
8508:0280DF00 ;スクロール定義 80DF:A5FF lda $FF ;上昇気流フラグ 80E1:F001 beq $80E4 ; 80E3:60 rts ; 80E4:20D080 jsr $80D0 ;現在部屋基準のスクロール事前設定 80E7:4C53D6 jmp $D653 ;右スクロール処理
$80D0は先のものと共通のため省略します。
Rockman 6 After Tournamentでは、特殊武器とビートプレートの所持状況によって進めるルートが変わるようになっているところがあります。Dr.ワイリーステージ4が該当します。
特殊武器を8つ全て持っている場合は左に、プレートEとゲノムインスピレーション(ケンタウロスマン武器)を所持している場合は右に進めるようになっています。地形に対応した武器/プレートを所持していると青くなり通れるようになり、所持していないと灰色になり通れないという仕組みになっています。
この地形操作を1つ前の部屋でスクロールの生成時処理を利用して行っています。
特殊武器を所持しているかどうかは、武器エネルギーが#$80なら未所持、それ以外なら所持となります。プレートアイテムはエネルギーバランサーフラグ$0696の下位4ビットでそれぞれ判定します。
これらの所持状況を確認し、地形を変化させるためのフラグを立てます。
実際のコードは以下のようになっています。
8F8C:955400000001DF0000 ;スクロール定義 9554:A900 lda #$00 ; 9556:8D5E03 sta $035E ;Destroyed blocks 9559:8D5F03 sta $035F ;Destroyed blocks 955C:A008 ldy #$08 ; 955E:B98806 lda $0688,y ;Weapon energy 9561:C980 cmp #$80 ; 9563:F002 beq $9567 ; 9565:38 sec ; 9566:A9 lda #$18 ; 9567:18 clc ; 9568:2E5E03 rol $035E ;Destroyed blocks 956B:88 dey ; 956C:D0F0 bne $955E ; 956E:AD9606 lda $0696 ;エネルギーバランサーフラグ 9571:290F and #$0F ; 9573:8D5F03 sta $035F ;Destroyed blocks 9576:4C958F jmp $8F95 ;元々のスクロール$73生成時処理
また、分岐のある部屋では条件付きスクロールも利用しています。地形でルート分岐自体は成立しているため、条件付きスクロール自体は必須ではないのですが、何らかの不具合等で壁抜けが起きた場合に備えて、分岐条件を満たしている場合にのみスクロールするようになっています。こちらについては、特に詳細は紹介しません。
ロックマン6のブーンブロックは、1部屋でのみ使用される想定で作られているため、横長のスクリーンで使用すると出現タイミングがズレます。
Rockman 6 After Tournamentおよびロックマン6再(Ver.2)では、このタイミングのズレを無くして同期を取る対応をしています。この同期化対応は、管理オブジェクトを配置しておき、各ブロックオブジェクトから管理オブジェクトの状態を見て出現/消滅処理を行うという方法を採っています。
この管理オブジェクトの生成を、スクロールの生成時処理で行っています。なお、同期化対応そのものの解説はここでは行いません。
管理オブジェクトの生成をスクロールで行う理由は、生成するスロット番号を固定するため、そして複数の管理オブジェクトが生成されてしまうことを防ぐためです。
通常、オブジェクトは空きスロット番号の降順に生成されるため、最も重複の可能性が低い$08($00-$07はロックマン側で使用されます)に生成します。既に$08にオブジェクトが存在する場合は、管理オブジェクトの生成は行いません。これにより、複数生成を防ぎます。このようにすることで、スクリーンの左右どちらから入ってきた場合にも管理オブジェクトが1つだけ生成されるようになります。
実際のコードは以下のようになっています。
87E1:87E701000000 ;スクロール定義 87E7:A93C lda #$3C ;配置X座標(ブーンブロックの切替時間) 87E9:48 pha ; 87EA:A91F lda #$1F ;配置Y座標(ブーンブロックの効果音タイミング) 87EC:48 pha ; 87ED:4CF481 jmp $81F4 ;ブーンブロック同期用Obj生成 ;ブーンブロック同期用Obj生成 81F4:ADA803 lda $03A8 ;Object ID[8] 81F7:C9F4 cmp #$F4 ; 81F9:D003 bne $81FE ; 81FB:68 pla ; 81FC:68 pla ; 81FD:60 rts ; 81FE:A208 ldx #$08 ;オブジェクトスロット番号 8200:A0F4 ldy #$F4 ;オブジェクト:ブーンブロック同期用 8202:2028CB jsr $CB28 ;パラメータ毎に処理内容が変わる 8205:41 .db ;Yレジスタで指定した番号のオブジェクトを生成 8206:68 pla ; 8207:9DCB04 sta $04CB,x ; ;Y座標(low) 820A:68 pla ; 820B:9D8604 sta $0486,x ; ;X座標(low) 820E:60 rts ;
ロックマン6では、オブジェクトが配置されている座標を引数のように扱うことがあります。
この管理オブジェクトでは、X座標でブーンブロックの切替時間、Y座標でブーンブロックの効果音タイミングを設定出来るようにしてあります。切替時間は再では一定ですが、After Tournamentでは一部異常に早くなっている箇所があります。効果音タイミングを指定する理由は、ブロック側で鳴らしてしまうと切り替えではないタイミングでスポーンした場合に、効果音の同期が取れなくなってしまうからです。ですので、効果音は管理オブジェクト側で鳴らしています。
筆者の改造作品におけるスクロールの応用事例を紹介しました。
今後、他に使い方が増えた場合は追記することがあるかもしれません。