ページ

2016年4月17日日曜日

ここまでのまとめ

ここまでのまとめです。
TEST02.BASにBGMを追加してみました。

・TEST03.BAS(MSX2,MSX2+,MSX turboR)
10 SCREEN 5,2
20 DEFINT A-Z:DIM B$(15),BG$(8)
30 FOR I=0 TO 8:READ BG$(I):NEXT
40 ON INTERVAL=80 GOSUB 490:BG=0
100 '
110 B$( 0)="000000AAE0000000"
120 B$( 1)="00000AAAEE000000"
130 B$( 2)="0000AAAAEEE00000"
140 B$( 3)="0000A11111E00000"
150 B$( 4)="0000AAA1EEEAEE00"
160 B$( 5)="00000AEEEAAC11EE"
170 B$( 6)="000AAAA66ACC111E"
180 B$( 7)="0099AA6A8ACC111E"
190 B$( 8)="0FF906688ACC111E"
200 B$( 9)="AAF00444B8AC11E0"
210 B$(10)="AA00AAAAE8AA1EE0"
220 B$(11)="000009909988E000"
230 B$(12)="00000990FF088000"
240 B$(13)="00000FF0AAA00000"
250 B$(14)="0000AAA0AAA11111"
260 B$(15)="0000AAA111111110"
270 FOR I=0 TO 15:FOR J=0 TO 15
280 C=VAL("&H"+MID$(B$(I),J+1,1))
290 PSET(J,I),C:NEXT:NEXT
300 '
310 SET PAGE 1,1:CLS:X=120:Y=104
320 INTERVAL ON
330 '
340 TIME=0:VX=0:VY=0
350 ST=STICK(0) OR STICK(1)
360 SR=STRIG(0) OR STRIG(1)
370 IF SR=-1 THEN 470
380 IF ST=0 THEN 450
390 IF ST=1 AND Y<>  0 THEN VY=-8
400 IF ST=3 AND X<>240 THEN VX= 8
410 IF ST=5 AND Y<>192 THEN VY= 8
420 IF ST=7 AND X<>  0 THEN VX=-8
430 COPY(16,0)-(31,15),0TO(X,Y),1
440 X=X+VX:Y=Y+VY
450 COPY(0,0)-(15,15),0TO(X,Y),1,TPSET
460 IF TIME<8 THEN 460 ELSE 340
470 END
480 '
490 PLAY BG$(BG)
500 BG=BGMOD8+1:RETURN
510 '
520 DATA T180L4o5s9m8500
530 DATA d2o4a2o5,eo4ar2
540 DATA o5e2o4a2o5,fdr4d8d8
550 DATA c+dr4d8d8,efd.d8
560 DATA gfed,dc+r2

・実行画面


・解説

10 スクリーンモード
20 文字列の定義
30 BGMデータの読み取り
40 一定の時間ごとに割り込み処理する行番号の指定

110~260 キャラクターデータ
270~290 キャラクターの描画

310 表示ページ、線画ページの切替
320 割り込み処理の開始

340~460 メインルーチン

490~500 割り込み処理(BGMの演奏)
520~560 BGMデータ

ちょっとした工夫でMSX BASICでもBGM付きのゲームをつくることができます。
そして、今はMSXでゲームを制作するのに便利なフリーソフトがたくさんあります。
次回からはそうしたソフトを活用した21世紀のMSX BASICのゲームのつくり方(ちょっと大げさですが・・・)などを紹介していきたいと思います。

・動画
https://youtu.be/jyF28Kx9MTM
 

2016年4月10日日曜日

BGMを鳴らそう!

今回は、BGMの演奏です。
プログラムはこんな感じです。

・BGM01.BAS(MSX2,MSX2+,MSX turboR)
10 DEFINT A-Z:DIM BG$(8)
20 FOR I=0 TO 8: READ BG$(I):NEXT
30 ON INTERVAL=80 GOSUB 90:BG=0
40 INTERVAL ON
50 '
60 PRINT BG;
70 IF INKEY$="" THEN 60 ELSE END
80 '
90 PLAY BG$(BG)
100 BG=BGMOD8+1:RETURN
110 '
120 DATA T180L4o5s9m8500
130 DATA d2o4a2o5,eo4ar2
140 DATA o5e2o4a2o5,fdr4d8d8
150 DATA c+dr4d8d8,efd.d8
160 DATA gfed,dc+r2

・実行画面(SCREEN0で実行)


・解説
10 文字列の定義
20 BGMデータの読み取り
30 一定の時間ごとに割り込み処理する行番号の指定
40 割り込み処理の開始
60~70 メインルーチン
90~100 割り込み処理(BGMの演奏)
120~160 BGMデータ

・BGMデータのつくり方
T<テンポ>は1分間に演奏する4分音符の数です。T180の場合、4分音符一つは60秒/180つまり20/60秒となります。このプログラムでは、T180の4分音符4個分のデータで区切っていますので、PLAY命令が1回で演奏する時間は80/60秒となります。


・割り込み処理について
ON INTERVAL GOSUB命令は、一定の時間ごとに実行する行番号を指定します。時間は1/60秒単位で指定できます。このプログラムでは、PLAY命令の1回の演奏時間が80/60秒なので、

ON INTERVAL=80 GOSUB 90

としています。
INTERVAL ON命令で、割り込み処理を開始しています。

・割り込み処理(BGMの演奏)
行番号90で、PLAY命令を実行し演奏しています。
行番号100では、次に演奏するデータを計算しています。
BG$(0)にはMMLの初期設定が入っていますので、BG=8を演奏した後はBG=1にします。

このプログラムでは、

IF BG=8 THEN BG=1 ELSE BG=BG+1

という処理をMOD(割り算の余り)を使って、

BG=BG MOD 8 +1

で計算しています。この方が処理が速く、メモリの節約にもなります。

F-BASICにも、ON INTERVAL GOSUB命令はあるのですが、1秒単位での指定だったため、BGMデータを作る際、音楽のテンポなどを考慮しなければなりませんでした。
MSX-BASICは1/60秒単位なので、かなり使いやすいと思います。

また、一定の間隔で演奏するため、BGMデータの最後がR<休止>の時は省略できます。

"eo4ar2" → "eo4a"

実際に、BASICでゲームなどにBGMを組み込むと、PLAY命令のバッファが溜まってきて、他のプログラムが動かなくなる場合が多々あります。休止の部分を削除してPLAY命令のバッファが溜まらないように工夫したり、INTERVALの間隔を少し増やして調整してみましょう。


・動画
https://youtu.be/eZv3y_suIdk

2016年4月3日日曜日

キャラクターを動かしてみよう!

次にキャラクターを動かしてみましょう。
前回のプログラム”TEST01.BAS”から、行番号300以降を変更しています。

・TEST02.BAS(MSX2,MSX2+,MSX turboR)
100 SCREEN 5,2:DEFINT A-Z:DIM B$(15)
110 B$( 0)="000000AAE0000000"
120 B$( 1)="00000AAAEE000000"
130 B$( 2)="0000AAAAEEE00000"
140 B$( 3)="0000A11111E00000"
150 B$( 4)="0000AAA1EEEAEE00"
160 B$( 5)="00000AEEEAAC11EE"
170 B$( 6)="000AAAA66ACC111E"
180 B$( 7)="0099AA6A8ACC111E"
190 B$( 8)="0FF906688ACC111E"
200 B$( 9)="AAF00444B8AC11E0"
210 B$(10)="AA00AAAAE8AA1EE0"
220 B$(11)="000009909988E000"
230 B$(12)="00000990FF088000"
240 B$(13)="00000FF0AAA00000"
250 B$(14)="0000AAA0AAA11111"
260 B$(15)="0000AAA111111110"
270 FOR I=0 TO 15:FOR J=0 TO 15
280 C=VAL("&H"+MID$(B$(I),J+1,1))
290 PSET(J,I),C:NEXT:NEXT
300 '
310 SET PAGE 1,1:CLS
320 X=120:Y=104
330 '
340 TIME=0:VX=0:VY=0
350 ST=STICK(0) OR STICK(1)
360 SR=STRIG(0) OR STRIG(1)
370 IF SR=-1 THEN 470
380 IF ST=0 THEN 450
390 IF ST=1 AND Y<>  0 THEN VY=-8
400 IF ST=3 AND X<>240 THEN VX= 8
410 IF ST=5 AND Y<>192 THEN VY= 8
420 IF ST=7 AND X<>  0 THEN VX=-8
430 COPY(16,0)-(31,15),0TO(X,Y),1
440 X=X+VX:Y=Y+VY
450 COPY(0,0)-(15,15),0TO(X,Y),1,TPSET
460 IF TIME<8 THEN 460 ELSE 340
470 END

・実行画面(PAGE 1)


・解説
310 表示ページ、線画ページの切替
340~460 メインルーチン
350 カーソルキー・ジョイスティックの状態を取得
360 スペースキー・ジョイスティックのボタンの状態を取得
430 キャラクターの消去
440 キャラクターの座標を計算
450 キャラクターの描画
460 ウェイト処理

VRAM 128KBのMSX2は、256×212ドット・512色中16色のグラフィックモードで、ページを4枚切り替えて使うことができます(VRAM64KBの場合2枚)。
最初に、表示・線画の初期設定ページ0にキャラクターを描画し,その後、SET PAGE命令でページ1に切り替えています。


・実行画面(PAGE 0)

STICK命令ですが、STICK(0)でカーソルキー、STICK(1)でジョイスティックポート1の状態を取得します。、押した方向によって対応した値が返ってきます。押されていない時は0の値を返します。
このプログラムでは、上下左右の4方向に対応しています。

MSX-BASICにも、F-BASICなどにあるINKEY$命令でキーボードからの入力を取得できますが、STICK命令を使うことで、キーボードとジョイスティック両対応のプログラムが簡単に作ることができます。

・STICK命令の返り値


STRIG命令ですが、STRIG(0)でスペースキー、STRIG(1)でジョイスティックポート1のAボタンの状態を取得しています。押されていない時は0の値を、押されていれば-1の値を返します。
このプログラムでは、スペースキーかジョイスティックポート1のAボタンを押すとプログラムが終了します。

COPY命令は、ページ間の転送ができるのでとても便利です。このプログラムでは、ページ0に描いたキャラクターを、ページ1に転送して描画しています。
 
F-BASICなどでは、ページに描いたキャラクターを一旦GET@命令で配列に入れた後、PUT@命令でキャラクターを描いていました。MSX-BASICでは同じことを、配列不要でCOPY命令ひとつで行なえます。さらに配列を使って描画するよりも高速で、メモリの節約にもなります。
 
TIEM命令は、1/60秒ごとに+1されるシステム変数です。このプログラムでは、ウエイト処理に使用しています。メインルーチンの最初でTIMEの値を0にして、ルーチンの終わりにTIMEの値が8(8/60秒)になるまで待機しています。
 
MSX2とturboRの高速モードでは処理速度が異なりますが、ウエイト処理を入れることで両対応のプログラムを作ることができます(もっともMSX2の処理速度に合わせた場合ですが・・・)
 
次はBGMの鳴らし方を紹介したいと思います。
 
・動画