プチコン3号 6日目 迷路を背景グラフィックスにしてスクロールさせる

前回、迷路を生成しましたので、今度は迷路をBGに表示させて、4日目のようにスライドパッドでスクロールさせてみたいと思います。
こんな感じの表示で、スライドパッドで迷路をスクロールさせます。
いずれは画面中央にキャラクターを置いて、迷路の中を歩けるようにしたいと思いますが、今日はまだスクロールさせるだけです。

pc6-1.jpg

前回はPRINT文で罫線を使って迷路を表示しましたが、今回はBGPUTでBGに描画します。
使用する絵は、「291,292,256,257」の組を選びました。
291が状態3の部屋、292が状態1の部屋、256は右下隅の表示欠けの埋め、257は空白です。
他にもSmileツールで探せば、迷路の表示に使える絵がいろいろと用意されています。

pc6-2.jpg
pc5-4.jpg

状態2の部屋に使う絵は、用意されてません。
これは状態1の部屋に使う292番のキャラクタを、270度回転して使います。
270度回転するには、キャラクタ番号に12288を足します。
12288+292=12580が、状態2の部屋の画像になります。

BGキャラクタの回転に関しては、プチコン3号のマニュアルにも現時点ではあまり詳しく書かれていなかったので、ここでちょっと補足しておきます。
キャラ番号は16ビットで指定しますが、上位4ビットが図のように回転・横反転・縦反転の指定に使われます。
簡単には、
・回転: 回転の状態(0~3)に4096を掛けた数
・横反転: 16384
・縦反転: 32768
をキャラ番号に加算すれば、回転・反転したキャラクタを表示できます。

ちなみにキャラ番号を16進数3桁で表現すれば、頭に1桁の16進数を付加するだけなので、足し算を計算しなくて済みます。
たとえば、292番は16進数で&H124ですので、270度回転したキャラクタは&H3124になります。
このへんの話になると、プログラミング初心者の方には難しいかもしれませんね・・・

pc6-3.jpg

さて、プログラムに戻ります。
BGもスプライトも16×16ピクセルですので、迷路の各部屋をBG1枚に割り当てると、壁の厚みがあるために窮屈な感じになりそうです。
そこで、各部屋をBG4枚で表現することにしました。
具体的には、下図のような具合です。
太い青線が1部屋分、細い青線がBG1枚です。
たとえば左上の部屋を表現するには、以下のように4回BGに書き込みます。
(0,0)→ 291
(1,0)→ 292
(0,1)→ 12580
(1,1)→ 257

pc6-4.jpg

また、一番右の列には125800、一番下の部屋の下部には292番のキャラクタを描きます。
これだけだと、右下の壁が少し欠けてしまいますので、そこに256番のキャラクタを描きます。

スクロール操作は、BGの大きさが違うことを除けば、基本的には4日目の記事のままです。

以上をプログラムにしたものが以下になります。
画面は、迷路の部分(1行~20行)は前回と同じですので省略しました。

pc6-5.jpg
M_W=49:M_H=24
DIM R[M_W+2,M_H+2]
FOR J=0 TO M_H+1
FOR I=0 TO M_W+1
IF I==0 || I==M_W+1 || J==0 || J==M_H+1 THEN
R[I,J]=0
ELSE
R[I,J]=3
ENDIF
NEXT
NEXT
FOR J=1 TO M_H
FOR I=1 TO M_W
R_N=R[I,J-1]
R_W=R[I-1,J]
IF R_N==0 && R_W>0 THEN R[I,J]=1
IF R_N>0 && R_W==0 THEN R[I,J]=2
IF R_N>0 && R_W>0 THEN R[I,J]=1+RND(2)
NEXT
NEXT
ACLS
BGSCREEN 0,M_W*2+1,M_H*2+1
W1=292:W2=12580:W3=291:WE=257
FOR J=1 TO M_H
FOR I=1 TO M_W
IF R[I,J]==3 THEN C1=W3:C2=W1:C3=W2
IF R[I,J]==2 THEN C1=W2:C2=WE:C3=W2
IF R[I,J]==1 THEN C1=W1:C2=W1:C3=WE
BGPUT 0,I*2-2,J*2-2,C1
BGPUT 0,I*2-1,J*2-2,C2
BGPUT 0,I*2-2,J*2-1,C3
BGPUT 0,I*2-1,J*2-1,WE
NEXT
BGPUT 0,M_W*2,(J-1)*2,W2
BGPUT 0,M_W*2,J*2-1,W2
NEXT
BGFILL 0,0,M_H*2,M_W*2-1,M_H*2,292
BGPUT 0,M_W*2,M_H*2,256
X=0:Y=0:XMIN=-200:YMIN=-120
XMAX=16*(M_W*2)-200:YMAX=16*(M_H*2)-120
@LOOP
STICK OUT DX ,DY
X=MAX(XMIN,X+DX*8)
X=MIN(X,XMAX)
Y=MAX(YMIN,Y-DY*8)
Y=MIN(Y,YMAX)
BGOFS 0,X,Y,500
VSYNC 1
GOTO @LOOP

今回の追加部分はACLS以降の部分です。
BGのサイズは、迷路一部屋あたり2×2のBGを使いますので、迷路のサイズ(M_W、M_H)の2倍、それに右端の1列と最下行の1行を追加したものになります。
W1、W2、W3、WEは、3種類の壁および壁が無い状態のキャラ番号です。

C1~C3は、1つの部屋に対するBGのキャラ番号を代入します。
C1が左上、C2が右上、C3が左下です。右下は常に壁無しです。
各部屋の状態R[I,J]に応じて、C1~C3にW1~WEを代入します。
そのあと、BGPUTでBGにキャラクタを書き込んでいます。

39行目以降は、スライドパッドでスクロールするためのコードです。
画面の中央のポイント(200,120)が迷路からはみ出さないようにXとYの最大値・最小値を決めています。
また、端までスクロールしたときの判定を以前はIF文で行っていたところを、MINとMAXを使って書き換えてみました。

これで迷路をスクロールさせることができました。
キャラクターを迷路の中で移動させる場合は、壁があるかどうか判定を追加する必要があります。
それはまた次回に作りたいと思います。

コメント