今回は素材集サイトFirst Seed Materialのキャラクターチップをお借りします。
ソース内の変数について説明します。
ex,eyはマップチップ一個分を単位とするキャラクターの座標です。
exが1増えると、画面上では右に32ピクセル移動する事になります。
edirはキャラクターの向きを表しています。
上の画像に合わせて、0=左向き、1=上向き、2=右向き、3=下向きを表しています。
walkはキャラの歩行アニメーションの状態です。
まずカーソルキーが押されるとwalk = 1となって、
それに合わせて片足を出したキャラクターが表示されます。
1ループの処理が終わるとpwalkの値が1増えて、また次の状態の画像が表示されます。
walk = 4までいくと移動が終了し、exまたはeyの値が変化します。
gmode 4についての詳細はHSPの命令リファレンスを見てください。
モード4はcolor命令で指定されたRGB値を背景色とみなしてコピーしません。つまりそこだけ透明になります。
上の画像の背景色は(0,117,117)なのでコピー前にcolor 0,117,117が必要です。
最後にpos ex*32+walk*wdx*8+4,ey*32+walk*wdy*8について説明します。
ex,eyはキャラの移動前の座標です。これに32をかけて画面上の座標に変換します。
さらに1アニメーション毎にキャラを8ピクセル(1/4マップ分)ずつ動かすためにwalkに8をかけます。
その時、移動方向に合わせてキャラをずらすためにwdx,wdyをかけます。
下の表は(ex,ey)=(2,2)にいるときの座標の移動例です。
| pwalk | 右に移動 | 上に移動 |
| 0 | x = 2 * 32 = 64 | y = 2 * 32 = 64 |
| 1 | x = 64 + 8 | y = 64 - 8 |
| 2 | x = 64 + 16 | y = 64 - 16 |
| 3 | x = 64 + 24 | y = 64 - 24 |
| 4 | x = 64 + 32 | y = 64 - 32 |
buffer 1,96,32 picload "maptip.bmp" buffer 2,72,128 picload "charatip.bmp" screen 0,320,320 dim map,10,10 map(2,5) = 1 map(6,7) = 2 ex = 4 :ey = 4 //キャラの初期位置 *main gosub *move //キャラの移動 gosub *draw_map //マップの描画 gosub *draw_chara //キャラクターの描画 redraw 1 wait 8 redraw 0 goto *main *move stick key,15 if walk = 0 { wdx = 0 :wdy = 0 if key = 1: wdx-- //左移動 if key = 2: wdy-- //上移動 if key = 4: wdx++ //右移動 if key = 8: wdy++ //下移動 if (wdx ! 0) | (wdy ! 0){ walk = 1 edir = logf(key)/logf(2) //移動方向に合わせてキャラの向きを変える x = ex+wdx : y = ey+wdy //移動先の座標 if (x < 0) | (x > 9) : walk = 0 :x = 0 //移動先が画面外だったら移動しない if (y < 0) | (y > 9) : walk = 0 :y = 0 if map(x,y) :walk = 0 //移動先に障害物があれば移動しない } } return *draw_chara gmode 4,24,32,256 color 0,117,117 //透過したい背景色を指定 pos ex*32+walk*wdx*8+4,ey*32+walk*wdy*8 if walk = 0 : gcopy 2,24,(edir * 32),24,32 if walk = 1 : gcopy 2,0,(edir * 32),24,32 if walk = 2 : gcopy 2,24,(edir * 32),24,32 if walk = 3 : gcopy 2,48,(edir * 32),24,32 if walk = 4 { gcopy 2,24,(edir * 32),24,32 walk = 0 //移動終了 ex += wdx //現在の座標を移動後の位置にする ey += wdy wdx = 0 : wdy = 0 } if walk:walk++ return *draw_map gmode 0 x = 0 : y = 0 repeat 10 j = cnt repeat 10 i = cnt pos x,y if map(i,j) = 0:gcopy 1,0,0,32,32 //草の下地を表示 if map(i,j) = 1:gcopy 1,32,0,32,32 //ブロックを表示 if map(i,j) = 2:gcopy 1,64,0,32,32 //箱を表示 x += 32 loop x = 0 : y += 32 loop return