前回、マシン語でスプライトを動かすことができました。
今回はウォーキングのアニメーションをさせたいと思います。
カーソルキーの右を入れたら右を向き、そしてテクテクと歩く!
というものです。
僕が持っているマシン語の本には、スプライトの移動は書いて
あるのですが、
歩行アニメーションについては、全く書いてありません^^;
そのため、全部自分で考えました。
かなり効率が悪く、しょぼいプログラムになってしまいましたが、
ペコm(_ _;m)三(m;_ _)mペコ
参考程度に見ていただけると嬉しいです(^^;)
https://msxpen.com/codes/-LYwsb5uhSycnzHhWw-i
いつものようにMSXPENです^^
(ソースコード記述と実行ができて、サーバー要らず!便利!)
動画を。
速すぎます^^;
このプログラムは、
マシン語でスプライトを動かして、そのままマシン語内で
ループさせています。
これでもいいのですが、
僕が今、作っているゲームでは、BASIC + マシン語にしますので、
処理を一度BASICへ戻して、
またマシン語を呼び出すプログラムを
書きます。
こちらです。
https://msxpen.com/?code=-LXfXaZdHmEUsImtp4m8
動画はこちら。
BASICに一度戻すとかなり遅くなりますねぇ。
オールマシン語と
BASIC内にマシン語を書く場合では
ここまでスピードが違いますo(*・ω・)ノ
今回の歩行プログラムは、
・右を押したら右向きのスプライトを表示。
・右を押し続けたら、二枚のスプライトを交互に表示。
の2つの処理をやっています。
ですので、まず、
カーソルの右を押したら、右の絵のスプライトを表示、
カーソルの上を押したら、上の絵のスプライトを表示etcをやります。
(スプライトは、動かためのスプライト番号と、
スプライトの絵が入ったスプライトパターン番号があります。
今回はスプライト番号0に、様々なスプライトパターン番号を入れ替えてやることで、
アニメーションさせています。)
ちなみに同じような移動をオールBASICでやるとこんな感じです。
https://msxpen.com/codes/-LYxrwBTuE-lYwfp8UXK
動画はこちら。
もっと遅いです^^
パタパタアニメは速いですね〜。
おもしろいですw
BASICでゲームを作りたい方はこちらへ^^
方向キーでスプライトの絵が変わるプログラム
こちらを実行してみてください。
https://msxpen.com/codes/-LYxSmiuP_nz8FFHYITf
カーソル右で、右の絵のスプライト、
カーソル左で、左の絵のスプライトetc
になります。
まずBASIC部分を説明します。
10 CLEAR 300,&HCFFF
20 SCREEN1,2,0
30 KEY OFF
40 BLOAD"MOVE.BIN"
80 'SPRITE TEIGI======================
90 RESTORE 3000
100 FOR J=0 TO 7
110 S$=""
120 FOR I=0 TO31
130 READ DT$
140 S$=S$+CHR$(VAL("&H"+DT$))
150 NEXT
160 SPRITE$(J)=S$
170 NEXT
1000 'MAIN
1010 'SPRITE HYOUJI
1020 PUT SPRITE 0,(100,100),15,0
1030 DEFUSR=&HD000
1040 A=USR(0)
1045 GOTO 1040
1050 END
2995 'SPRITE DOWN0 * 4 DATA
3000DATA00,00,A7,AF,BF,9F,9D,9D,9F,8F,87,80,E7,E1,86,00,00,00,F2,FA,FE,FC,DC,DC,FC,FF,FB,11,7B,CE,30,30
3010 'SPRITE DOWN1 * 4 DATA
3020DATA00,80,A7,AF,BF,9F,9D,9D,9F,8F,E7,E0,E7,81,06,06,00,00,F2,FA,FE,FC,DC,DC,FC,F8,FF,1B,71,DB,3E,00
3030 'SPRITE RIGHT2 * 4 DATA
3040DATA00,00,47,4B,6B,0B,6B,6B,6B,2B,0B,1C,1B,03,1C,1C,00,00,E0,F4,FC,F8,68,68,F8,F8,FE,1A,B0,DA,3E,3C
3050 'SPRITE RIGHT3 * 4 DATA
3060DATA00,00,4F,5E,6D,1D,7D,7D,7A,3A,15,0C,1B,1B,24,0E,00,00,E0,F4,7C,78,58,58,F8,F0,FE,1A,50,DA,0E,E4
3070 'SPRITE UP4 * 4 DATA
3080DATA00,00,4F,5F,7F,3F,3F,3F,3F,1F,EF,F0,FE,F3,6C,00,01,01,E5,F5,FD,F9,F9,F9,F9,F7,E7,07,E1,80,60,60
3090 'SPRITE UP5 * 4 DATA
3100DATA00,00,4F,5F,7F,3F,3F,3F,3F,DF,EF,F8,FE,73,0C,0C,00,00,E5,F5,FD,F9,F9,F9,F9,F1,E1,07,E7,87,61,00
3110 'SPRITE LEFT6 * 4 DATA
3120DATA00,00,03,17,1F,8F,8B,8B,4F,4F,27,20,1A,1B,00,03,00,00,F9,FD,FB,FC,7F,7F,FF,CE,DF,1B,D1,DB,3E,70
3130 'SPRITE LEFT7 * 4 DATA
3140DATA00,00,47,6F,7F,5F,56,56,5F,5F,4F,40,E5,E3,48,38,00,00,F2,FA,F6,F8,FE,FE,FE,9C,BE,36,A2,B6,3C,38
スプライトを定義しています。
スプライトパターンの0番〜7番まで。
キャラクターの上向きとか左向きとか、です。
(方向キーで絵が変わるだけの場合は、
スプライトパターンの定義は4枚でいいのですが、
後で書く歩行アニメーションのプログラムのために8枚定義します。)
1040行でマシン語を呼び出して、
1050行で1040行に行き、ループさせています。
アセンブラの部分(マシン語)は、
BREAKX: EQU 0x00B7
GTSTCK: EQU 0x00D5
RDVRM: EQU 0x004A
WRTVRM: EQU 0x004D
KILBUF: EQU 0x0156
ORG 0xD000
START:
STCKLP:
CALL BREAKX
RET C
LD A,0
CALL KILBUF
CALL GTSTCK
OR A
JP Z,STCKLP
CP 8
JR NZ,STICK1
LD A,24
CALL SPWNUM
CALL MOVEL
CALL MOVEU
JP STCKLP1
STCKLP1:
RET
STICK1:
CP 7
JP NZ,STICK2
LD A,24
CALL SPWNUM
CALL MOVEL
JP STCKLP1
STICK2:
CP 6
JP NZ,STICK3
LD A,24
CALL SPWNUM
CALL MOVEL
CALL MOVED
JP STCKLP1
STICK3:
CP 5
JP NZ,STICK4
LD A,0
CALL SPWNUM
CALL MOVED
JP STCKLP1
STICK4:
CP 4
JP NZ,STICK5
LD A,8
CALL SPWNUM
CALL MOVED
CALL MOVER
JP STCKLP1
STICK5:
CP 3
JP NZ,STICK6
LD A,8
CALL SPWNUM
CALL MOVER
JP STCKLP1
STICK6:
CP 2
JP NZ,STICK7
LD A,8
CALL SPWNUM
CALL MOVER
CALL MOVEU
JP STCKLP1
STICK7:
CP 1
JP NZ,STCKLP1
LD A,16
CALL SPWNUM
CALL MOVEU
JP STCKLP1
MOVEU:
CALL SPYGET
CP 1
RET Z
SUB 1
LD HL,1B00H
CALL WRTVRM
RET
MOVEL:
CALL SPXGET
CP 1
RET Z
SUB 1
LD HL,1B01H
CALL WRTVRM
RET
MOVED:
CALL SPYGET
CP 176
RET Z
ADD A,1
LD HL,1B00H
CALL WRTVRM
RET
MOVER:
CALL SPXGET
CP 240
RET Z
ADD A,1
LD HL,1B01H
CALL WRTVRM
RET
SPYGET:
LD HL,0x1B00
CALL RDVRM
RET
SPXGET:
LD HL,0x1B01
CALL RDVRM
RET
SPWNUM:
LD HL,1B02H
CALL WRTVRM
RET
END START
マシン語の命令など、基本的な説明はこちらでしております。
わかりやすく書いたつもりです^^
MSXPENは、アセンブラのpasmoを使用していたはずなので、
このようなソースコードの書き方になります。
違うアセンブラを使えば、記述の仕方の細かいところが変わると思います。
BREAKX: EQU 0x00B7
GTSTCK: EQU 0x00D5
RDVRM: EQU 0x004A
WRTVRM: EQU 0x004D
KILBUF: EQU 0x0156
この部分は、宣言です。
ソースコードの中で、BREAKXと書いたものは、00B7ですよ!と
宣言します。
この00B7はアドレスです。
BIOSを呼び出すときはアドレスを書きますが、そのアドレスを宣言しておきます。
例えばこれなら、
CALL BREAKXなどと書くことができ、
BIOSの00B7のアドレスのものが呼び出せます。(最初の0xは16進数の意味)
BIOSにどのようなものがあるかは、MSXマガジンなどを御覧ください^^
永久保存版3にBIOSの一覧が載っています。
こちらにもあります。
駿河屋のほうが安い場合もあります^^
ORG 0xD000
は、メモリの、
D000番地からマシン語を書き始めますという意味です。
PEEK命令を使えば、
D000以降に16進数のデータ(マシン語)が
書き加えられているのが分かると思います。
(ちなみに今回の僕のプログラムでは、マシン語をMOVE.BINファイルとして保存
しています。
ASM Codeと書かれた横の歯車をクリックするとファイル名を変えることが出来ます。)
アセンブラで、スプライトを動かすところの解説はこちらへ。
第33回 マシン語でスプライトをカーソルキーで動かす!勉強レポート MSXマシン語入門(Z80 アセンブラ・機械語) - ニャオニャオ21世紀
今回の方向キーで絵が変わるプログラムとの違いを書いていきます。
---スプライトの移動のみ---
左上を押したとき
STCKLP:
CALL BREAKX
RET C
LD A,0
CALL KILBUF
CALL GTSTCK
OR A
JR Z,STCKLP
CP 8
JR NZ,STICK1
CALL MOVEL
CALL MOVEU
JP STCKLP
---方向キーでスプライトの絵が変わるプログラム---
左上を押したとき
STCKLP:
CALL BREAKX
RET C
LD A,0
CALL KILBUF
CALL GTSTCK
OR A
JP Z,STCKLP
CP 8
JR NZ,STICK1
LD A,24
CALL SPWNUM
CALL MOVEL
CALL MOVEU
JP STCKLP1
違いはこの赤字の部分です。
CALL SPWNUMで、自分で作ったサブルーチンを読んでいますので、
そちらも書きますと、
SPWNUM:
LD HL,1B02H
CALL WRTVRM
RET
これだけです^^
ざっと説明を。
まずVRAMにスプライトことが書かれていますが、
(MSX BASIC基礎 VRAMについて、やさしく説明します! - ニャオニャオ21世紀)
VRAMのアドレスの、1B02番地(16進数です)には、
スプライト0の、スプライトパターン番号が書かれています。
このアドレスのスプライトパターン番号を書き換えてやれば、
表示されているスプライトの絵を変えることが出来ます。
そこでちょっと注意が必要なのですが、
16x16ドットのスプライトは、スプライトパターンナンバー x4をしてやらないといけません。
(MSXは、8x8ドット単位で1スプライトと処理していますので^^;)
上のプログラムは、カーソルキーの左上を押したら、
スプライトパターンナンバー24 (6番x4ですね )を表示するだけです。
左上が押されたら、
LD A,24
と、Aレジスタにスプライトパターンナンバーの24を入れています。
(サブルーチン内で使用するため)
そしてVRAMに値を書き込むサブルーチンを呼びます。
CALL SPWNUM
サブルーチンの
SPWNUM:
LD HL,1B02H
CALL WRTVRM
RET
の中の
CALL WRTVRM
は、VRAMに値を書き込むBIOSです。
レジスタHLに、VRAMのアドレスを指定。
レジスタAに、書き込む数値です。
このプログラムをまとめると、
方向キーの判定の箇所で、
Aレジスタに値を入れて(出したい絵のスプライトパターンナンバーを)、
そして、
VRAMに値を書き込むサブルーチンを呼びます
(書き込むVRAMのアドレスはすべて共通)。
比較的簡単ですね٩(ˊᗜˋ*)و
(JP STCKLP1は、STCKLP1にジャンプします。
STCKLP1のサブルーチンは、
BASICに戻るためにRET命令が書いてあります)
カーソルキーで歩行アニメーション
BASIC部分は先程と同じです。
アセンブラ部分はこちら。
BREAKX: EQU 0x00B7
GTSTCK: EQU 0x00D5
RDVRM: EQU 0x004A
WRTVRM: EQU 0x004D
KILBUF: EQU 0x0156
ORG 0xD000
START:
STCKLP:
CALL BREAKX
RET C
LD A,0
CALL KILBUF
CALL GTSTCK
OR A
JP Z,STCKLP
CP 8
JR NZ,STICK1
LD B,24
CALL SPNUMGET
CP 24
CALL Z,SPLNUM2
LD A,B
CALL SPWNUM
CALL MOVEL
CALL MOVEU
JP STCKLP1
STCKLP1:
RET
STICK1:
CP 7
JP NZ,STICK2
LD B,24
CALL SPNUMGET
CP 24
CALL Z,SPLNUM2
LD A,B
CALL SPWNUM
CALL MOVEL
JP STCKLP1
STICK2:
CP 6
JP NZ,STICK3
LD B,24
CALL SPNUMGET
CP 24
CALL Z,SPLNUM2
LD A,B
CALL SPWNUM
CALL MOVEL
CALL MOVED
JP STCKLP1
STICK3:
CP 5
JP NZ,STICK4
LD B,0
CALL SPNUMGET
CP 0
CALL Z,SPDNUM2
LD A,B
CALL SPWNUM
CALL MOVED
JP STCKLP1
STICK4:
CP 4
JP NZ,STICK5
LD B,8
CALL SPNUMGET
CP 8
CALL Z,SPRNUM2
LD A,B
CALL SPWNUM
CALL MOVED
CALL MOVER
JP STCKLP1
STICK5:
CP 3
JP NZ,STICK6
LD B,8
CALL SPNUMGET
CP 8
CALL Z,SPRNUM2
LD A,B
CALL SPWNUM
CALL MOVER
JP STCKLP1
STICK6:
CP 2
JP NZ,STICK7
LD B,8
CALL SPNUMGET
CP 8
CALL Z,SPRNUM2
LD A,B
CALL SPWNUM
CALL MOVER
CALL MOVEU
JP STCKLP1
STICK7:
CP 1
JP NZ,STCKLP1
LD B,16
CALL SPNUMGET
CP 16
CALL Z,SPUNUM2
LD A,B
CALL SPWNUM
CALL MOVEU
JP STCKLP1
MOVEU:
CALL SPYGET
CP 1
RET Z
SUB 1
LD HL,1B00H
CALL WRTVRM
RET
MOVEL:
CALL SPXGET
CP 1
RET Z
SUB 1
LD HL,1B01H
CALL WRTVRM
RET
MOVED:
CALL SPYGET
CP 176
RET Z
ADD A,1
LD HL,1B00H
CALL WRTVRM
RET
MOVER:
CALL SPXGET
CP 240
RET Z
ADD A,1
LD HL,1B01H
CALL WRTVRM
RET
SPYGET:
LD HL,0x1B00 ;Y
CALL RDVRM
RET
SPXGET:
LD HL,0x1B01 ;X
CALL RDVRM
RET
SPNUMGET:
LD HL,0x1B02
CALL RDVRM
RET
SPWNUM:
LD HL,1B02H
CALL WRTVRM
RET
SPLNUM2:
LD B,28
RET
SPRNUM2:
LD B,12
RET
SPUNUM2:
LD B,20
RET
SPDNUM2:
LD B,4
RET
END START
かなり駄目なプログラムだと思います^^;
はじめて自分で書いたアセンブラということでお許しください。
もっと慣れてきてスキルが身についたら、
書き換えたいと思います^^
---方向キーでスプライトの絵が変わるプログラム---
左上を押したとき
STCKLP:
CALL BREAKX
RET C
LD A,0
CALL KILBUF
CALL GTSTCK
OR A
JP Z,STCKLP
CP 8
JR NZ,STICK1
LD A,24
CALL SPWNUM
CALL MOVEL
CALL MOVEU
JP STCKLP1
---歩行アニメーションこみのスプライト移動---
左上を押したとき
STCKLP:
CALL BREAKX
RET C
LD A,0
CALL KILBUF
CALL GTSTCK
OR A
JP Z,STCKLP
CP 8
JR NZ,STICK1
LD B,24
CALL SPNUMGET
CP 24
CALL Z,SPLNUM2
LD A,B
CALL SPWNUM
CALL MOVEL
CALL MOVEU
JP STCKLP1
方向キーで絵が変わるプログラムとの違いはこれだけです。
なにが違うのかといいますと、
キーボードの左上入力で、スプライトパターンナンバーの24(6番 x 4です)を設定しているのは、
同じです。
ただ、
現在のスプライトパターンナンバーが何番かを取得して、
スプライトパターンナンバーが24だったら、
スプライトパターンナンバーを28番に書き換えます。
もし現在表示されているスプライトパターンが、24番ではないのならば
24番に書き換えます。
プログラムではどうやったかといいますと、
まず
LD B , 24
Bレジスタに24を入れます。
次に現在のスプライトパターンナンバーが何か知るために、サブルーチンを呼びます。
CALL SPNUMGET
サブルーチンの中身はこちらです。
SPNUMGET:
LD HL,0x1B02
CALL RDVRM
RET
RDVRMは、BIOSで、VRAMのHLに指定されたアドレスの中身を、
Aレジスタに入れます。
そしてサブルーチンから戻って、
CP 24
Aレジスタの中身が24だったら、Zフラグが1に。
(CPは比較命令。この場合は、Aレジスタ - 24をします。
結果が0だとZ(ゼロ)フラグが1、立ちます。)
CALL Z , SPLNUM2
Zフラグが立っているなら、サブルーチンSPLNUM2へ。
(現在の表示スプライトパターンが24番だったらSPLNUM2へ)
現在のスプライトパターンが24番ではない場合、
(28番(2枚目の絵)かもしれないし、別の向きのスプライトパターン番号かもしれません)
LD A , B
レジスタBに入れてあったスプライトパターン番号24をレジスタAにいれます。
そして、VRAMにスプライトパターン番号を書き込みます。
なんかもっといい方法はないんでしょうか?^^;
今見直すと、CP 24のところを、CP Bにしたほうがいいのかもしれません。
あとサブルーチンでレジスタBにスプライトパターン番号を入れているところを
もっとスマートにした方がいいのかなぁ~^^;
う〜ん(´・ω・`)
でもなんとか動いていますし、もっと効率のいいものは、
アセンブラに慣れてきたら出来ると信じて続けていきます^^
今回はここまでにさせていただきます。では〜。
MSXのゲームも本体も雑誌も!
時々チェックしてみてください^^ 掘り出し物があるかも!