参考資料
§ 基本マップ(仮想スクリーン) §
側面(サイドビュー)マップ2
仮想スクリーンの利用
ロールプレイングゲームやアクションゲーム等に於いて、キャラクタ(スプライト)の進める処、進めない処を判別するのに、仮想スクリーンを用いるのが一般的で有る。
下記のプログラムでは、マップデータを表すDATA文で、進める処(0)、進めない処(1)を定義し、マップデータ用の配列MAPに格納し、此の値が1の時は壁を表示して進めない処とし、0の時は何も表示せず進める処として居る。
RESTORE @MAPDATA FOR I=0 TO 14 FOR J=0 TO 24 READ MAP[J,I] NEXT NEXT @MAPDATA DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1 DATA 1,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,0,0,0,1 DATA 1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1 DATA 1,0,0,0,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 DATA 1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 DATA 1,0,0,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 DATA 1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
キャラクタの進行方向の配列MAPの値を調べ、0ならば進め、其れ以外なら何もしない(即ち、進めない)で居ます。
側面マップ(サイドビュー)では、上下移動には、梯子を使用するか、ジャンプを行う事に成ります。梯子の場合は、基本的に平面マップ(バードビュー)と同じなので、此処では、ジャンプに依る方法を採用しました。
キャラクタ(スプライト)を1ドット(ピクセル)単位で移動させる場合、進める処、進めない処を判別するのに、2箇所のチェックが必要と成ります。
ドット座標よりグリッド座標を求めるには、グリッドの幅、高さで整数除算(DIV演算子)を行います。例えば、キャラクタが右に移動する時のコードは、下記の通りです。
'RIGHT MOVE IF B AND 8 THEN SPCHR 0,596+N:DR=1 U=MAP[(X+16) DIV 16 ,Y DIV 16] D=MAP[(X+16) DIV 16 ,(Y+15) DIV 16] IF U==0 && D==0 THEN INC X ENDIF ENDIF
キャラクタの進行方向の配列MAPの値を調べ、0ならば進め、其れ以外なら何もしない(即ち、進めない)で居ます。
※ マップを表示する迄のコードは、マップエディタ(公開キー:D23P4PD)で生成されます。
0000001 | OPTION STRICT |
0000002 | ACLS |
0000003 | DIM I,J,B,C=0,N=0,L,R,U,D |
0000004 | DIM X=16,Y=192,AC=0,DR=1,ST=0 |
0000005 | DIM CHIP[2] |
0000006 | DIM MAP[25,15] |
0000007 | |
0000008 | BGSCREEN 0,25,15 |
0000009 | RESTORE @CHIPDATA |
0000010 | FOR I=0 TO 1 |
0000011 | READ CHIP[I] |
0000012 | NEXT |
0000013 | RESTORE @MAPDATA |
0000014 | FOR I=0 TO 14 |
0000015 | FOR J=0 TO 24 |
0000016 | READ MAP[J,I] |
0000017 | NEXT |
0000018 | NEXT |
0000019 | |
0000020 | @CHIPDATA |
0000021 | DATA 0,491 |
0000022 | @MAPDATA |
0000023 | DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 |
0000024 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 |
0000025 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 |
0000026 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1 |
0000027 | DATA 1,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 |
0000028 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 |
0000029 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,0,0,0,1 |
0000030 | DATA 1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,1 |
0000031 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 |
0000032 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1 |
0000033 | DATA 1,0,0,0,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 |
0000034 | DATA 1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 |
0000035 | DATA 1,0,0,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 |
0000036 | DATA 1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 |
0000037 | DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 |
0000038 | |
0000039 | FOR I=0 TO 14 |
0000040 | FOR J=0 TO 24 |
0000041 | BGPUT 0,J,I,CHIP[MAP[J,I]] |
0000042 | NEXT |
0000043 | NEXT |
0000044 | |
0000045 | SPSET 0,596 |
0000046 | SPOFS 0,X,Y |
0000047 | |
0000048 | GPRIO -128 |
0000049 | GPUTCHR 136,4,"PUSH X TO FINISH",1,1,#WHITE |
0000050 | |
0000051 | C=0:N=0 |
0000052 | WHILE TRUE |
0000053 | B=BUTTON(0) |
0000054 | |
0000055 | 'QUIT |
0000056 | IF B AND 64 THEN BREAK |
0000057 | |
0000058 | 'LEFT MOVE |
0000059 | IF B AND 4 THEN |
0000060 | SPCHR 0,604+N:DR=-1 |
0000061 | U=MAP[(X-1) DIV 16,Y DIV 16] |
0000062 | D=MAP[(X-1) DIV 16,(Y+15) DIV 16] |
0000063 | IF U==0 && D==0 THEN |
0000064 | DEC X: |
0000065 | ENDIF |
0000066 | ENDIF |
0000067 | |
0000068 | 'RIGHT MOVE |
0000069 | IF B AND 8 THEN |
0000070 | SPCHR 0,596+N:DR=1 |
0000071 | U=MAP[(X+16) DIV 16 ,Y DIV 16] |
0000072 | D=MAP[(X+16) DIV 16 ,(Y+15) DIV 16] |
0000073 | IF U==0 && D==0 THEN |
0000074 | INC X |
0000075 | ENDIF |
0000076 | ENDIF |
0000077 | |
0000078 | 'NEUTRAL |
0000079 | IF (B AND 12)==0 THEN |
0000080 | SPCHR 0,600:DR=0 |
0000081 | ENDIF |
0000082 | |
0000083 | 'JUMP |
0000084 | IF B AND 16 THEN |
0000085 | IF ST<2 THEN |
0000086 | ST=1:INC AC,1.8:IF AC>5.5 THEN AC=5.5:ST=2 |
0000087 | ENDIF |
0000088 | ELSE |
0000089 | IF ST==1 THEN ST=2 |
0000090 | ENDIF |
0000091 | |
0000092 | 'CHECK BELOW |
0000093 | IF ST==0 THEN |
0000094 | L=MAP[(X+ 2) DIV 16,(Y+16) DIV 16) |
0000095 | R=MAP[(X+13) DIV 16,(Y+16) DIV 16) |
0000096 | IF (L==0) && (R==0) THEN |
0000097 | AC=0:ST=2 |
0000098 | ENDIF |
0000099 | ENDIF |
0000100 | |
0000101 | 'FALL DOWN |
0000102 | IF ST>0 THEN |
0000103 | DEC AC,0.32 |
0000104 | DEC Y,AC |
0000105 | 'HEAD CHECK |
0000106 | L=MAP[(X+ 2) DIV 16,(Y-1) DIV 16) |
0000107 | R=MAP[(X+13) DIV 16,(Y-1) DIV 16) |
0000108 | IF (L!=0) || (R!=0) THEN |
0000109 | AC=0 |
0000110 | ENDIF |
0000111 | 'FOOT CHECK |
0000112 | L=MAP[X DIV 16,(Y+16) DIV 16) |
0000113 | R=MAP[(X+15) DIV 16,(Y+16) DIV 16) |
0000114 | IF (L!=0) || (R!=0) THEN |
0000115 | Y=((Y+16) DIV 16-1)*16:ST=0 |
0000116 | ENDIF |
0000117 | ENDIF |
0000118 | |
0000119 | 'LOOP COUNTER |
0000120 | INC C |
0000121 | IF (C DIV 10)==1 THEN |
0000122 | C=0:INC N:IF N>3 THEN N=0 |
0000123 | ENDIF |
0000124 | |
0000125 | SPOFS 0,X,Y |
0000126 | |
0000127 | VSYNC 1 |
0000128 | WEND |
0000129 | ACLS:END |
プログラムの説明
下記のプログラムでは、スプライトが、 ボタンで左右にアニメーションしながら動き、
ボタンで最大3キャラクタ分ジャンプします。壁の部分には進めません。
BGGET関数の利用
プチコン3号(Smile BASIC)では、BGGET関数に依り、BGキャラの情報を取得出来るので、仮想スクリーンを用いなくても、BG画面の情報で、マップ情報を知る事が出来る。
下記のプログラムでは、BGGET関数で取得したBG画面のBGキャラ情報が、0(空白)の時は、進める処と判別して居る。猶、BGGET関数の第4引数は、座標系フラグで、0の時(又は省略時)はキャラクタ(グリッド)単位で、1の時はドット(ピクセル)単位と成ります。
0000001 | OPTION STRICT |
0000002 | ACLS |
0000003 | DIM I,J,B,C=0,N=0,L,R,U,D |
0000004 | DIM X=16,Y=192,AC=0,DR=1,ST=0 |
0000005 | DIM CHIP[2] |
0000006 | DIM MAP[25,15] |
0000007 | |
0000008 | BGSCREEN 0,25,15 |
0000009 | RESTORE @CHIPDATA |
0000010 | FOR I=0 TO 1 |
0000011 | READ CHIP[I] |
0000012 | NEXT |
0000013 | RESTORE @MAPDATA |
0000014 | FOR I=0 TO 14 |
0000015 | FOR J=0 TO 24 |
0000016 | READ N |
0000017 | BGPUT 0,J,I,CHIP[N] |
0000018 | NEXT |
0000019 | NEXT |
0000020 | |
0000021 | @CHIPDATA |
0000022 | DATA 0,491 |
0000023 | @MAPDATA |
0000024 | DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 |
0000025 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 |
0000026 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 |
0000027 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1 |
0000028 | DATA 1,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 |
0000029 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1 |
0000030 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,0,0,0,1 |
0000031 | DATA 1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,1 |
0000032 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 |
0000033 | DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1 |
0000034 | DATA 1,0,0,0,1,0,0,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 |
0000035 | DATA 1,0,0,0,0,0,0,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 |
0000036 | DATA 1,0,0,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 |
0000037 | DATA 1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1 |
0000038 | DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 |
0000039 | |
0000040 | SPSET 0,596 |
0000041 | SPOFS 0,X,Y |
0000042 | |
0000043 | GPRIO -128 |
0000044 | GPUTCHR 136,4,"PUSH X TO FINISH",1,1,#WHITE |
0000045 | |
0000046 | C=0:N=0 |
0000047 | WHILE TRUE |
0000048 | B=BUTTON(0) |
0000049 | |
0000050 | 'QUIT |
0000051 | IF B AND 64 THEN BREAK |
0000052 | |
0000053 | 'LEFT MOVE |
0000054 | IF B AND 4 THEN |
0000055 | SPCHR 0,604+N:DR=-1 |
0000056 | U=BGGET80,X-1,Y,1) |
0000057 | D=BGGET80,X-1,Y+15,1) |
0000058 | IF U==0 && D==0 THEN |
0000059 | DEC X: |
0000060 | ENDIF |
0000061 | ENDIF |
0000062 | |
0000063 | 'RIGHT MOVE |
0000064 | IF B AND 8 THEN |
0000065 | SPCHR 0,596+N:DR=1 |
0000066 | U=BGGET(0,X+16,Y,1) |
0000067 | D=BGGET(0,X+16,Y+15,1) |
0000068 | IF U==0 && D==0 THEN |
0000069 | INC X |
0000070 | ENDIF |
0000071 | ENDIF |
0000072 | |
0000073 | 'NEUTRAL |
0000074 | IF (B AND 12)==0 THEN |
0000075 | SPCHR 0,600:DR=0 |
0000076 | ENDIF |
0000077 | |
0000078 | 'JUMP |
0000079 | IF B AND 16 THEN |
0000080 | IF ST<2 THEN |
0000081 | ST=1:INC AC,1.8:IF AC>5.5 THEN AC=5.5:ST=2 |
0000082 | ENDIF |
0000083 | ELSE |
0000084 | IF ST==1 THEN ST=2 |
0000085 | ENDIF |
0000086 | |
0000087 | 'CHECK BELOW |
0000088 | IF ST==0 THEN |
0000089 | L=BGGET(0,X+ 2,Y+16,1) |
0000090 | R=BGGET(0,X+13,Y+16,1) |
0000091 | IF (L==0) && (R==0) THEN |
0000092 | AC=0:ST=2 |
0000093 | ENDIF |
0000094 | ENDIF |
0000095 | |
0000096 | 'FALL DOWN |
0000097 | IF ST>0 THEN |
0000098 | DEC AC,0.32 |
0000099 | DEC Y,AC |
0000100 | 'HEAD CHECK |
0000101 | L=BGGET(0,X+ 2,Y-1,1) |
0000102 | R=BGGET(0,X+13,Y-1,1) |
0000103 | IF (L!=0) || (R!=0) THEN |
0000104 | AC=0 |
0000105 | ENDIF |
0000106 | 'FOOT CHECK |
0000107 | L=BGGET(0,X,Y+16,1) |
0000108 | R=BGGET(0,X+15,Y+16,1) |
0000109 | IF (L!=0) || (R!=0) THEN |
0000110 | Y=((Y+16) DIV 16-1)*16:ST=0 |
0000111 | ENDIF |
0000112 | ENDIF |
0000113 | |
0000114 | 'LOOP COUNTER |
0000115 | INC C |
0000116 | IF (C DIV 10)==1 THEN |
0000117 | C=0:INC N:IF N>3 THEN N=0 |
0000118 | ENDIF |
0000119 | |
0000120 | SPOFS 0,X,Y |
0000121 | |
0000122 | VSYNC 1 |
0000123 | WEND |
0000124 | ACLS:END |