ニャオニャオ21世紀

レトロゲーム(MSX、PCエンジン、セガサターン)と、MSXぽいアプリ開発と、最新ゲーム(PS4、SWITCH)、身体(身体意識など)、ライフハック、電子工作ほか雑記を綴っています

MSX BASICの基礎 その7 敵キャラをたくさん出す!BASICだと遅くなってしまうのですが、そこをなんとかする方法です^^






MSX BASICでは、スプライトを何枚か表示するだけで

スピードが極端に遅くなってしまいます(~~;)

 

そうですね〜、5,6枚も表示したらゲームにならないかも。

(正確にはわかりませんが^^)

 

そのため、BASICでゲームを作ることは難しく、

マシン語の勉強をされる方が多かったと聞きます。

 

当時の僕の場合は、2枚くらい表示させて喜んでいたレベルなので、

遅くなるなんて知らなかったですけどw

 

 

でもアクションゲームやシューティングなどでは、敵キャラがたくさん欲しいところですよね〜。

そうですね〜、最低でも2、3体、

多くて5、6体といったところですか。

 

今回、敵の数(スプライトの表示枚数)を増やす方法は、

スプライトを同時に表示するのではなくて、

1ループつき1枚表示し、それを順番に表示していく方法をとります!

 

この方法を知った時、頭がいいなぁと思いましたw

確かに同時表示ではないので、動きにズレが生じるのですが、

複数の敵が規則正しい動きを強いられるシューティングでなければ、

デメリットはほぼないと言えると思います。

 

どのくらいの速度になるか、動画をみてください。

youtu.be

 

敵キャラを6体表示していますので、

すべての敵を動かすのに、6ループ要します。

全体的にスライムの動きが遅いのですが、プレイヤーキャラの動きは軽快です^^

 

スライムの数を減らせば、その分速くなります。

 

 

それではソースコードを。

複数のスプライト表示のソースコード

 

10 SCREEN1,2:COLOR15,1,1:WIDTH32:DEFINTA-Z:KEYOFF
20 DEFUSR=&H7E:A=USR(0)
30 KEY1,"SCREEN1"+CHR$(13)
40 X=160:Y=120:H=0
42 'EN<TEKI NO NUMBER>,EK<TEKI NO KAZU>,EX( )<TEKI X ZAHYOU>,EY( )<TEKI Y ZAHYOU>,EM( )<TEKI NO MOVE RYOU>
45 EN=0:EK=6:DIMEX(6):DIMEY(6):DIMEM(6)
46EX(0)=16:EY(0)=8:EX(1)=96:EY(1)=32:EX(2)=16:EY(2)=56:EX(3)=96:EY(3)=104:EX(4)=160:EY(4)=120:EX(5)=160:EY(5)=144
47 EM(0)=-8:EM(1)=8:EM(2)=-8:EM(3)=8:EM(4)=-8:EM(5)=8
50 'SPRITE TEIGI
60 RESTORE 2000
70 FOR J=0 TO 8
80 FOR I=0 TO 15
90 READ DT$
100 L$=L$+CHR$(VAL("&B"+LEFT$(DT$,8)))
110 R$=R$+CHR$(VAL("&B"+RIGHT$(DT$,8)))
120 NEXT
130 SPRITE$(J) =L$+R$
140 L$="":R$=""
150 NEXT
160 'BLOCK TEIGI
170 M=ASC("a")
175 RESTORE 4000
180 FOR I=0 TO 7
190 READ BG$
200 VPOKE M*8+I,VAL("&B"+BG$)
210 VPOKE &H800+M*8+I,VAL("&B"+BG$)
220 VPOKE &H1000+M*8+I,VAL("&B"+BG$)
230 NEXT
240 FOR I=0 TO 7
250 READ CR$
260 VPOKE &H2000+M*8+I,VAL("&H"+CR$)
270 VPOKE &H2800+M*8+I,VAL("&H"+CR$)
280 VPOKE &H3000+M*8+I,VAL("&H"+CR$)
290 NEXT
490 'MAP
500 LOCATE 0,0:PRINT "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
510 LOCATE 0,1:PRINT "a a"
520 LOCATE 0,2:PRINT "a a"
530 LOCATE 0,3:PRINT "a a aaaaaaaaa aaaaaaaaaaaa a"
540 LOCATE 0,4:PRINT "a a a a"
550 LOCATE 0,5:PRINT "a a a a"
560 LOCATE 0,6:PRINT "a aaaaaaaaa a aaaaaaaaaaaa a"
570 LOCATE 0,7:PRINT "a a a a a"
580 LOCATE 0,8:PRINT "a a a a a"
590 LOCATE 0,9:PRINT "a aa aaaaa a a aaa a a"
600 LOCATE 0,10:PRINT"a aa aaaaa a a aaa a a"
610 LOCATE 0,11:PRINT"a aa aaaaa a a a aaa a a"
620 LOCATE 0,12:PRINT"a aa aaaaa a a a a"
630 LOCATE 0,13:PRINT"a a a a a"
640 LOCATE 0,14:PRINT"a a a aaaaaaaaa a"
650 LOCATE 0,15:PRINT"a aa aaaaaaaa a a"
660 LOCATE 0,16:PRINT"a aa a a a a"
670 LOCATE 0,17:PRINT"a aa a a aaaaaaaaaaaa a"
680 LOCATE 0,18:PRINT"a a a"
690 LOCATE 0,19:PRINT"a a a"
700 LOCATE 0,20:PRINT"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
995 'MAIN LOOP
996 'PLAYER
1000 S=STICK(0) OR STICK(1)
1010 TX=X:TY=Y
1020 IF S=1 THEN Y=Y-8:H=(H+1)MOD 2
1040 IF S=3 THEN X=X+8:H=( (H+1)MOD 2)+2
1060 IF S=5 THEN Y=Y+8:H=( (H+1)MOD 2)+4
1080 IF S=7 THEN X=X-8:H=( (H+1)MOD 2)+6
1100 A$=CHR$(VPEEK(&H1800+(X\8)+(Y\8)*32))
1110 B$=CHR$(VPEEK(&H1800+(X\8)+1+(Y\8)*32))
1120 C$=CHR$(VPEEK(&H1800+(X\8)+(Y\8+1)*32))
1130 D$=CHR$(VPEEK(&H1800+(X\8)+1+(Y\8+1)*32))
1140 IF ASC(A$)=ASC("a") THEN X=TX:Y=TY
1150 IF ASC(B$)=ASC("a") THEN X=TX:Y=TY
1160 IF ASC(C$)=ASC("a") THEN X=TX:Y=TY
1170 IF ASC(D$)=ASC("a") THEN X=TX:Y=TY
1180 PUT SPRITE 0,(X ,Y-1),15,H
1210 'ENEMY
1220 UX=EX(EN):UY=EY(EN)
1230 EX(EN)=EX(EN)+EM(EN)
1240 AE$="#":BE$="#":CE$="#":DE$="#"
1250 AE$=CHR$(VPEEK(&H1800+(EX(EN)\8)+(EY(EN)\8)*32))
1260 BE$=CHR$(VPEEK(&H1800+(EX(EN)\8)+1+(EY(EN)\8)*32))
1270 CE$=CHR$(VPEEK(&H1800+(EX(EN)\8)+(EY(EN)\8+1)*32))
1280 DE$=CHR$(VPEEK(&H1800+(EX(EN)\8)+1+(EY(EN)\8+1)*32))
1290 IF ASC(AE$)=ASC("a") THEN EX(EN)=UX:EY(EN)=UY
1300 IF ASC(BE$)=ASC("a") THEN EX(EN)=UX:EY(EN)=UY
1310 IF ASC(CE$)=ASC("a") THEN EX(EN)=UX:EY(EN)=UY:EM(EN)=-EM(EN)
1320 IF ASC(DE$)=ASC("a") THEN EX(EN)=UX:EY(EN)=UY:EM(EN)=-EM(EN)
1330 PUT SPRITE EN+1,(EX(EN),EY(EN)-1),7,8
1340 EN=EN+1:IF EN>EK-1 THEN EN=0
1350 GOTO1000
1995 'SPRITE UP0 DATA
2000 DATA1000000000000000
2010 DATA1000000000000000
2020 DATA1010011111110010
2030 DATA1010111111111010
2040 DATA1011111111111110
2050 DATA1001111111111100
2060 DATA1001111111111100
2070 DATA1001111111111100
2080 DATA1001111111111100
2090 DATA1110111111111000
2100 DATA1110011111110111
2110 DATA1110000000001111
2120 DATA1000011101111111
2130 DATA0000000111001111
2140 DATA0000011000110110
2150 DATA0000011000000000
2155 'SPRITE UP1 DATA
2160 DATA0000000000000000
2170 DATA0000000000000000
2180 DATA1010011111110010
2190 DATA1010111111111010
2200 DATA1011111111111110
2210 DATA1001111111111100
2220 DATA1001111111111100
2230 DATA1001111111111100
2240 DATA1001111111111100
2250 DATA1000111111111011
2260 DATA1000011111110111
2270 DATA1110000000011111
2280 DATA1110011101111111
2290 DATA1110000111001110
2300 DATA1000011000110000
2310 DATA0000000000110000
2315 'SPRITE RIGHT2 DATA
2320 DATA0000000000000000
2330 DATA0000000000000000
2340 DATA1001111111000000
2350 DATA1011111111101000
2360 DATA1101111111111000
2370 DATA0011111111110001
2380 DATA1111111011010001
2390 DATA1111111011010001
2400 DATA1111111111110010
2410 DATA0111001111110010
2420 DATA1111101111100100
2430 DATA1101100000000100
2440 DATA1000101101011000
2450 DATA1101101111011000
2460 DATA0111110000000000
2470 DATA0000111011000000
2475 'SPRITE RIGHT3 DATA
2480 DATA0000000000000000
2490 DATA0000000000000000
2500 DATA0100111111100010
2510 DATA0101111111110110
2520 DATA0110111111111110
2530 DATA0001111111111010
2540 DATA0111111101101010
2550 DATA0111111101101010
2560 DATA0111111111111010
2570 DATA0011100111111010
2580 DATA0111110111110010
2590 DATA0110110000000010
2600 DATA0100010110100111
2610 DATA0110110111000111
2620 DATA0011110000010010
2630 DATA0001110000011100
2635 'SPRITE DOWN4 DATA
2640 DATA0000000000000000
2650 DATA0000000000000000
2660 DATA1010011111110010
2670 DATA1010111111111010
2680 DATA1011111111111110
2690 DATA1001111111111100
2700 DATA1001110111011100
2710 DATA1001110111011100
2720 DATA1001111111111100
2730 DATA1000111111111111
2740 DATA1000011111111011
2750 DATA1000000000010001
2760 DATA1110011101111011
2770 DATA1110000111001110
2780 DATA1000011000110000
2790 DATA0000000000110000
2795 'SPRITE DOWN5 DATA
2800 DATA0000000000000000
2810 DATA1000000000000000
2820 DATA1010011111110010
2830 DATA1010111111111010
2840 DATA1011111111111110
2850 DATA1001111111111100
2860 DATA1001110111011100
2870 DATA1001110111011100
2880 DATA1001111111111100
2890 DATA1000111111111000
2900 DATA1110011111111111
2910 DATA1110000000011011
2920 DATA1110011101110001
2930 DATA1000000111011011
2940 DATA0000011000111110
2950 DATA0000011000000000
2955 'SPRITE LEFT6 DATA
2960 DATA0000000000000000
2970 DATA0000000000000000
2980 DATA0000001111111001
2990 DATA0001011111111101
3000 DATA0001111111111011
3010 DATA1000111111111100
3020 DATA1000101101111111
3030 DATA1000101101111111
3040 DATA0100111111111111
3050 DATA0100111111001110
3060 DATA0010011111011111
3070 DATA0010000000011011
3080 DATA0001101011010001
3090 DATA0001101111011011
3100 DATA0000000000111110
3110 DATA0000001101110000
3115 'SPRITE LEFT7 DATA
3120 DATA0000000000000000
3130 DATA0000000000000000
3140 DATA0100011111110010
3150 DATA0110111111111010
3160 DATA0111111111110110
3170 DATA0101111111111000
3180 DATA0101011011111110
3190 DATA0101011011111110
3200 DATA0101111111111110
3210 DATA0101111110011100
3220 DATA0100111110111110
3230 DATA0100000000110110
3240 DATA1110010110100010
3250 DATA1110001110110110
3260 DATA0100100000111100
3270 DATA0011100000111000
3275 'SPRITE SLIME DATA
3280 DATA0000000000000000
3290 DATA0000000000000000
3300 DATA0000000000000000
3310 DATA0000000000000000
3320 DATA0000000000000000
3330 DATA0000000000000000
3340 DATA0000000000000000
3350 DATA0000000000000000
3360 DATA0000111111110000
3370 DATA0011111111111100
3380 DATA0111111111111110
3390 DATA1111111111111111
3400 DATA1111111111111111
3410 DATA1111111111111111
3420 DATA1111111111111111
3430 DATA0111111001111110
3990 'YUKA
4000 DATA11100111
4010 DATA11100111
4020 DATA11100111
4030 DATA00000000
4040 DATA01111110
4050 DATA01111110
4060 DATA01111110
4070 DATA00000000
4990 'COLOR
5000 DATAF1,71,51,51,51,41,41,41

 

解説

解説をします。

 

45 EN=0:EK=6:DIMEX(6):DIMEY(6):DIMEM(6)

 

1210 'ENEMY
1220 UX=EX(EN):UY=EY(EN)
1230 EX(EN)=EX(EN)+EM(EN)
1240 AE$="#":BE$="#":CE$="#":DE$="#"
1250 AE$=CHR$(VPEEK(&H1800+(EX(EN)\8)+(EY(EN)\8)*32))
1260 BE$=CHR$(VPEEK(&H1800+(EX(EN)\8)+1+(EY(EN)\8)*32))
1270 CE$=CHR$(VPEEK(&H1800+(EX(EN)\8)+(EY(EN)\8+1)*32))
1280 DE$=CHR$(VPEEK(&H1800+(EX(EN)\8)+1+(EY(EN)\8+1)*32))
1290 IF ASC(AE$)=ASC("a") THEN EX(EN)=UX:EY(EN)=UY
1300 IF ASC(BE$)=ASC("a") THEN EX(EN)=UX:EY(EN)=UY
1310 IF ASC(CE$)=ASC("a") THEN EX(EN)=UX:EY(EN)=UY:EM(EN)=-EM(EN)
1320 IF ASC(DE$)=ASC("a") THEN EX(EN)=UX:EY(EN)=UY:EM(EN)=-EM(EN)
1330 PUT SPRITE EN+1,(EX(EN),EY(EN)-1),7,8
1340 EN=EN+1:IF EN>EK-1 THEN EN=0

敵を動かすのにチェックするところは、

おもに紫の色をつけたプログラムのところでしょうか。

 

まず、変数の説明をします。

EX( ) とEY( )は、敵スプライトの座標です。

なぜ配列なのか?といいますと、

今回は敵を6体動かしますので、

EX(0) ~ EX(5)

EY(0) ~ EY(5)

に座標をいれるとなにかと使い勝手がいいのです^^

 

ENを今、動かしたい敵キャラの個体ナンバーとすると、

PUT SPRITE  スプライト番号 , (EX(EN) , EY(EN)) ,色 ,スプライトパターン番号

こんな感じで表示します。

 

EN=0の時、(1番目の敵キャラ)

PUT SPRITE スプライト番号 , (EX(0) , EY(0) ) , 色 , スプライトパターン番号

です。

敵スプライト0の座標を、(160 , 80)に表示したければ、

EX(0)=160:EY(0)=80

と設定してやります。

(46行目に設定しております^^)

 

 

1330 PUT SPRITE EN+1,(EX(EN),EY(EN)-1),7,8
1340 EN=EN+1:IF EN>EK-1 THEN EN=0

1330行はわかると思います。

1340行は、敵キャラを0 ~ 5までを順番に表示するためのものです。

(EKは敵の数の6、と設定してあります)

 

メインループは1000行~1350行で、1ループまわるごとに

EN(敵キャラクターの番号)を1づつ増やしています。

1ループ目で、敵キャラの0番(EN=0)を、

2ループ目で、敵キャラの1番(EN=1)を、

3ループ目で、敵キャラの2番(EN=2)を、

.....

EN(敵キャラ番号) > 5

敵キャラ番号が5より大きくなったら、ENを0に戻します。

 

プログラムのループを回していくと、ENはこのようになります。

0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5......

と回しています。

(前回のページのキャラクターのアニメーションの方法でもOKです。

1340 EN=(EN+1)MOD 6

でもいけます。)

 

 

1230 EX(EN)=EX(EN)+EM(EN)

これは敵キャラの移動です。

X=X+8

みたいなものです。

少しややこしくみえますが、よくみると簡単なのです^^

(配列を使っているのでややこしくみえますね)

 

他の赤文字のプログラムのところは、プレイヤーのところと

ほぼ同じなので説明は省略します。

説明はこちらへどうぞ。

www.nyaonyao21.com

 

まとめ

サンプルを試す(WebMSX)

 

ダウンロード

 

なんとか敵キャラクターを表示、移動ができました!

でもスピード的にこのあたりが限界みたいです。

効率は全く考えない、

ただただ分かりやすいプログラムを書いてきましたが

そろそろ速くなるプログラムにしないといけませんね〜。

 

どうすれば速くなるか?ですが、

まず第一にメインループの部分を短くすることです!

行数が少なければ少ないほど速いのです。

 

基本はこれです!

今現在、メインループは1000行~1350行で、

30行あります。

 

こういった高速化について、いずれ書いていきたいと思います。

 

恒例になりつつあるハイドライドもどきの方を。

f:id:nyaonyaokun:20181013051829p:plain

モドキを試す(Webmsx)

 

何気に画面切り替えもできます^^

4x4画面のマップです。

画面書き換えが遅いので、ゆくゆくはマシン語のお世話になると思います。

(BASICでもVDP(2)を使う方法もあるのですが、SCREEN1.5では使えず...)

 

次回は、敵キャラとのあたり判定をやりたいと思います。

画面切り替えは、もう少しあとに説明します。

 

MSX関係のお買い物はこちらでどうぞ^^

msx | 通販ショップの駿河屋

  

つづき

www.nyaonyao21.com

 

 

 


「ニャオニャオ21世紀は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。」

当サイトは第三者配信の広告サービス「Google Adsense グーグルアドセンス」を利用しています。 広告配信事業者は、ユーザーの興味に応じた広告を表示するためにCookie(クッキー)を使用することがあります。 Cookie(クッキー)を無効にする設定およびGoogleアドセンスに関する詳細は「広告 – ポリシーと規約 – Google」をご覧ください