スプライトの移動で、
右を押したら右を向き、
左を押したら左を向くetc
というBASICのサンプルプログラムを書きます^^
今まではドラクエ1のようなキャラ移動だったのでw
スプライトのアニメーションにはちょっとしたテクニックがいります。
その他、MSX BASICの基本のページについての
目次はこちら
キャラクターの向きを変える
仕組み自体は簡単です。
キャラの向きを変えたり、アニメーションするのは、
基本的にスプライトパターンを切り替えてやります。
PUT SPRITE 0,(100,100),1,0
この0の位置の数字が、スプライトパターンです。
以前、スプライトについて書いたページで、
スプライトパターンの定義をしたのを覚えているでしょうか?
その時に、スプライトパターン番号を設定しております。
普通に考えれば、
スプライトパターン0が、上の絵。
スプライトパターン1が、右の絵。
スプライトパターン2が、下の絵。
スプライトパターン3が、左の絵。
などと定義しておいて、
押されたカーソルキーに合わせて、その番号をいれてやればOKです。
1000 S=STICK(0) OR STICK(1)
1010 TX=X:TY=Y
上移動
1020 IF S=1 THEN Y=Y-8:H=0
右移動
1040 IF S=3 THEN X=X+8:H=1
下移動
1060 IF S=5 THEN Y=Y+8:H=2
左移動
1080 IF S=7 THEN X=X-8:H=3
Hは方向の意味で名付けてみました。
(僕が勝手に作った変数です)
1180 PUT SPRITE 0,(X ,Y),15,H
そしてスプライトパターンをHとしておけば、
押されたカーソルキーによって
上向きの絵が出たり、右が出たりさせることができます。
(スプライトの定義で、0の時は上向きの絵というふうに、
ご自分で定義してくださいね^^)
歩行アニメーション
これだけなら、とても簡単なのですが、
少し問題があります。
それは歩行アニメーションです!
例えば、上を押したら、
上方向に歩行している絵のスプライト(右足前、左足前)を、
交互に表示しないといけません。
とりあえずサンプルプログラムをみてください。
サンプルソースコード
10 SCREEN1,2:COLOR15,1,1:WIDTH32:DEFINTA-Z:KEYOFF
20 DEFUSR=&H7E:A=USR(0)
30 KEY1,"SCREEN1"+CHR$(13)
40 X=96:Y=80
50 'SPRITE TEIGI
60 RESTORE 2000
70 FOR J=0 TO 7
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
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
1190 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
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
キャラクターを変えてみました^^
盾と剣の持つ手がおかしいのはご容赦ください^^
今度直します(><)
MAPのデータもおかしくなっています。ブログではスペースが省略されてしまって(~~;)
プログラムのソースコードですが、
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
これはどうなっているかといいますと、
1020 上を押すと H=1が入り、
2回目にこの行に来た時は、H=0が入り、
(1190 GOTO1000で、1000行に戻ってからの2回目)
そして、3回目でH=1に戻ります。
(スプライトパターンの0、1に上向きの歩行の絵を定義しています)
1040 右を押すと H=3、
2回目は、H=2、
3回目で、H=3。
(スプライトパターンの2、3に右向きの歩行の絵を定義しています)
1060 下を押すと H=5、
2回目は、H=4、
3回目で、H=5。
(スプライトパターンの4、5に下向きの歩行の絵を定義しています)
1080 左を押すと H=7
2回目は、H=6、
3回目で、H=7。
(スプライトパターンの6、7に左向きの歩行の絵を定義しています)
説明:
H=(H+1)MOD 2
MODは、割った余りをだす算術演算子です。
初めて見るかたもいらっしゃると思います。
僕も知ったのは最近なんですよねぇ〜。
いや、見たことはあったかもしれないですけど、算術演算子なんて知らなかったです。
ちなみに算術演算子とは+、ー、*、/ などの計算するやつです。
プログラムですが、
H=(H+1)MOD 2
MOD 2ですので、余りは0か、1になります。
Hには、0か1が入ります。
H=0の時、(0+1)MOD 2は、1を返します。
H=1の時、(1+1)MOD 2は、0を返します。
プログラムの流れを考えて見ることにします。
1000行 S=STICK(0) OR STICK(1)
でカーソルキー押されたキーが、Sに入ります。
そして
カーソルの上キー(S=1)だった場合、
1020行 IF S=1 THEN Y=Y-8:H=(H+1)MOD 2
初期値がH=0だったら、
1回目はH=1になります。
そしてそのまま、
1190行 GOTO1000
一旦、1000行へ戻り(ループし)
この時は、 H=1です。
カーソル上キーがまだ押されていれば
1020行 IF S=1 THEN Y=Y-8:H=(H+1)MOD 2
H=0となります。
こうやって、0と1を交互に値を変えているのです!
とてもよくできていますよね^^
こんなのは知らないと分からないです〜。
こういうテクニックを使ってプログラムを書いていきます。
非常にスマートにできます。
難しく考えることはなくて、
こういうパターンを覚えて(コピペ)して、使ってやるだけですので...
こういうのは、最新のハードでゲームを作っているときにも
使えると思います。
unityなんかは、ツールみたいなのを使って、
アニメーションを設定してやりますが、
ちょっとしたアニメーションなら、MSX BASICの方法を応用してやる方が
早いと思うのは僕だけでしょうか?w
unityで、スプライト同士を矢印で繋げたり、あれこれやるのって結構面倒です。
やり方を忘れてしまうので、毎回手順を見ながらやるのが、ねぇ(~~;)
手順を覚えてしまえば早いのかもしれませんが...
サンプルプログラムを試す
ハイドライド もどきも、
こんな感じになってきました^^
うーん、ハイドライド が作りたい!
BASICでどこまでいけるのかなぁ〜?
ハイドライドオマージュを作ろう!というブログになりつつありますw
(最初に10数秒お待ちください。文字を絵に書き換えています)
森の中は歩けません(^^;)
3x3のマップ+小さいダンジョンくらいならできるのかなぁ。
ハイドライド オマージュは、みんなの夢ですよね!^^
まとめ
そろそろ、このサンプルプログラムの
スプライトの絵のデータを16進数にしないといけないですね〜。
8枚描いただけでも、DATA文が長い長い;
2進数で8桁のものが、16進数なら2桁なんですよね^^
1/4のDATA量になるのでやらないといけません。
でもスプライトをささっと修正するのは2進数で描いてあると楽なので、
絵を固定するまでは2進数で。
EDIOをただいま直しています。
DATA部分の吐き出しと、
PCGの定義をするためのサブルーチンを吐き出す、
両方を実装できるようにしています。
どうも無駄の多いプログラムでメモリが足りなくなってしまって...
ちょっとその辺りの修正もしなくてはいけなくて難航しております。
しばらくお待ちくださいm(_ _)m
(ハイドライド もどきもEDIOで絵を作っています^^)
次回は、敵をいれてみたいと思います。
そこまでいったら、ゲームらしいものはほぼ完成ですね!
なぜこのMSX BASICの基本を書いているかと言いますと、
みなさんが作ったゲームがやりたいのです〜。
もっと自作ゲームが盛り上がるといいなぁと思いまして^^
次世代MSXに向けて、いろいろとやっていけたらなぁ〜なんて思っています。
みなさんも、このブログのサンプルプログラムの
マップと絵を変えるだけでもOKなので、ぜひやってみてください!
続き