Chapter.15 敵と自機弾の当たり判定、高速化
[Chapter15 制作物]
今回は、敵と自機弾の当たり判定処理を作ります。ついでに自機のあたり判定も作りますが、まだメインループに組み込みません。
ついでに処理の高速化もやります。
■敵と自機弾の当たり判定
工事中
■高速化1
sca_sprite.asm の sprite_update を見てください。
最初に「2枚重ねスプライトの2枚目の座標を1枚目と重ねる」というコメントが記入されている部分です。
プログラム1 にその部分を示します。
プログラム1 二枚重ねスプライトの二枚目の処理
sprite_update::
; 2枚重ねスプライトの2枚目の座標を1枚目と重ねる
ld de, #SCA_INFO_SIZE
push ix
ld b, #7 ; 自機、敵6機で、合計 7機
sprite_update_adjust:
ld a, SCA_INFO_XL(ix)
ld SCA_INFO_XL2(ix), a
ld a, SCA_INFO_XH(ix)
ld SCA_INFO_XH2(ix), a
ld a, SCA_INFO_YL(ix)
ld SCA_INFO_YL2(ix), a
ld a, SCA_INFO_YH(ix)
ld SCA_INFO_YH2(ix), a
add ix, de
add ix, de
djnz sprite_update_adjust
pop ix
|
各キャラクタ(自機とか敵とか弾とか)の情報を集めているメモリを SCA_INFO と呼んでますが、
2枚重ね表示をするスプライト(自機、敵)は、それを2つ分持ってます。
この2つ目の方の座標を、1つ目の方の座標と同じにする処理です。
わざわざ1つ目の座標を読み出して、2つ目に書き出してます。
しかし、1つ目の座標を書き込むとき、座標はレジスタにあるはずです。
従って、1つ目の座標を書き込むときに、ついでに2つ目にも書いてしまえば、「コピーするために読み出す」という処理
が不要になります。
しかも、プログラム1の処理が不要になります。
de レジスタの値は次以降でも使っているので、ld de, #SCA_INFO_SIZE の部分を残して、プログラム1 の部分は削除してしまいます。
次に、「1つ目の座標を書き込むときに、ついでに2つ目にも書いてしまう処理」を、自機と、全種類の敵にたいして記述
していかなければなりません。
自機なら、sca_player.asm の player_move にある SCA_INFO_XH(ix), SCA_INFO_YH(ix) への LD 命令の次の行に
SCA_INFO_XH2(ix), SCA_INFO_YH2(ix) に同じ値を LD するように追記します。
敵も同様です。
■高速化2
sca_background.asm の background_scroll を見てください。
call SETWRT は、VDP に対して「これから書き込む VRAMアドレスをセットする」という BIOSエントリですが、
background_scroll_loop2 のループの内側に記述されています。
background_scroll_loop2 のループは、
1回目は 40,41,42,43 のキャラクタフォントを書き換える処理、
2回目は 44,45,46,47 のキャラクタフォントを書き換える処理、
3回目は 48,49,50,51 のキャラクタフォントを書き換える処理、
4回目は 52,53,54,55 のキャラクタフォントを書き換える処理、
になっています。
1回目の最後の次が、2回目の最初になっているので、キャラクタフォントの VRAMアドレスは連続しています。
従って、background_scroll_loop2 の前に1度だけ call SETWRT すれば、問題ないわけです。
ということで、call SETWRT を background_scroll_loop3 の pop bc の下へ移動します。
■高速化3
またスクロールです。
background_scroll は、背景を1ドットスクロールさせる処理ですが、呼ばれるたびに必ずスクロールしてます。
試しに、background_scroll の入り口で ret して、ビルド・実行してみてください。
動作が爆速になるのを確認出来たと思います。
つまり、動作が遅い原因は、このスクロール処理に時間がかかっているからだと言えるわけです。
ここの処理を間引くことで高速化できます。
背景は4回に1度だけ1ドットスクロールするように変更します。
background_scroll の入り口に、プログラム2 を挿入します。
さらに、スクロールカウンタのところに、プログラム3 を挿入します。
プログラム2 4回に1回を判断する処理
; スクロールするタイミングか?
ld a, (background_scroll_timing)
dec a
and #3
ld (background_scroll_timing), a ; ※フラグ不変
ret nz
|
プログラム3 4回に1回を判断する処理用のワーク変数
background_scroll_timing:
.db #0 ; 0〜3, デクリメントカウンタ
|
プログラム2 は、ワーク変数 background_scroll_timing に対して、次のような計算をしてます。
background_scroll_timing = (background_scroll_timing - 1) AND 3
これは、3,2,1,0,3,2,1,0 ・・・ という値を繰り返すようになってます。
and #3 のところで、ゼロになったときだけ Zフラグが立つので、4回に1回であるかの判断に Zフラグが使えるわけです。
ret nz は、Zフラグが立っていない場合だけ呼び出し元へ戻る命令です。
ここまでで、だいぶ速くなりました。
速くなりすぎる分には、あとでどうにでも調節できます。
そのあたりは、次回に。
[▲トップページへ]