プレイヤー以外のキャラを表示します。素材集サイトFirst Seed Materialのキャラクターチップをお借りします。
基本的には2.主人公を表示するで使った、キャラクターの座標などの変数を配列変数にしただけです。
キャラが移動する際に当たり判定などを行うルーチンをユーザー定義命令にしました。
ユーザー定義命令については、モジュール機能、ユーザー定義命令(関数)で説明しています。
定義命令、move p1,p2 はp1番目の要素番号をもつキャラをp2で指定した方向に移動させる命令です。
p2は(0:左 1:上 2:右 3:下に対応しています)
randomize buffer 1,96,32 picload "maptip.bmp" buffer 2,72,128 picload "charatip.bmp" screen 0,320,320 dim map,10,10 en = 5 //表示するキャラの人数 dim ex,en //キャラの座標 dim ey,en dim edir,en //キャラの向き dim walk,en //キャラの歩行制御 dim wdx,en //キャラの移動方向 dim wdy,en ex = 1,2,3,4,5 //キャラの初期位置 ey = 1,2,3,4,5 *main gosub *keyEvent //プレイヤーの操作 gosub *cpuMove //コンピュータの移動 gosub *draw_map //マップの描画 gosub *draw_chara //キャラクターの描画 redraw 1 wait 8 redraw 0 goto *main //ユーザー定義命令 #deffunc move int mi,int mdir edir(mi) = mdir //向きを変える wdx(mi) = 0: wdy(mi) = 0 if mdir = 0: wdx(mi)-- if mdir = 1: wdy(mi)-- if mdir = 2: wdx(mi)++ if mdir = 3: wdy(mi)++ x = ex(mi)+wdx(mi) : y = ey(mi)+wdy(mi) //(x,y)は移動先の座標 if (x < 0) | (x > 9) : return //移動先が画面外だったら移動しない if (y < 0) | (y > 9) : return if map(x,y) :return //移動先に障害物があれば移動しない walk(mi) = 1 //他のキャラと衝突判定をする repeat en if mi = cnt :continue if (x = ex(cnt)) & (y = ey(cnt)) :walk(mi) = 0 :break if (x = ex(cnt)+wdx(cnt)) & (y = ey(cnt)+wdy(cnt)) :walk(mi) = 0 :break loop return *keyEvent stick key,15 i = 0 if walk(0) = 0 { if (key = 1) | (key = 2) | (key = 4) | (key = 8) : move 0,logf(key)/logf(2) } return *cpuMove repeat en if cnt = 0 :continue //0番目の配列はプレイヤーなのでスキップ if walk(cnt) :continue i = rnd(10) if i <= 3 :move cnt,i loop 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 *draw_chara gmode 4,24,32,256 color 0,117,117 repeat en i = cnt pos ex(i)*32+walk(i)*wdx(i)*8+4,ey(i)*32+walk(i)*wdy(i)*8 if walk(i) = 0 : gcopy 2,24,(edir(i) * 32),24,32 if walk(i) = 1 : gcopy 2,0,(edir(i) * 32),24,32 if walk(i) = 2 : gcopy 2,24,(edir(i) * 32),24,32 if walk(i) = 3 : gcopy 2,48,(edir(i) * 32),24,32 if walk(i) = 4 { gcopy 2,24,(edir(i) * 32),24,32 walk(i) = 0 ex(i) += wdx(i) ey(i) += wdy(i) wdx(i) = 0 : wdy(i) = 0 } if walk(i):walk(i)++ loop return
下のソースはユーザー定義命令を使わないで書き直したものです。
randomize buffer 1,96,32 picload "maptip.bmp" buffer 2,72,128 picload "charatip.bmp" screen 0,320,320 dim map,10,10 en = 5 //表示するキャラの人数 dim ex,en //イベントの座標 dim ey,en dim edir,en //イベントの向き dim walk,en //イベントの歩行制御 dim wdx,en //イベントの移動方向 dim wdy,en ex = 1,2,3,4,5 //キャラの初期位置 ey = 1,2,3,4,5 *main gosub *moving //移動処理 gosub *draw_map //マップの描画 gosub *draw_chara //キャラクターの描画 redraw 1 wait 8 redraw 0 goto *main //移動処理 *moving repeat en if cnt = 0 { stick key,15 if walk(0) = 0 { if (key = 1)|(key = 2)|(key = 4)|(key = 8) { edir(0) = int(logf(key)/logf(2)) } else :continue }else :continue }else{ if walk(cnt) :continue //移動中ならスキップ i = rnd(10) if i <= 3 :edir(cnt) = i :else :continue } i = cnt wdx(i) = 0 :wdy(i) = 0 if edir(i) = 0: wdx(i)-- if edir(i) = 1: wdy(i)-- if edir(i) = 2: wdx(i)++ if edir(i) = 3: wdy(i)++ x = ex(i)+wdx(i) : y = ey(i)+wdy(i) //(x,y)は移動先の座標 if (x < 0) | (x > 9) : return //移動先が画面外だったら移動しない if (y < 0) | (y > 9) : return if map(x,y) :return //移動先に障害物があれば移動しない walk(i) = 1 repeat en if i = cnt :continue if (x = ex(cnt)) & (y = ey(cnt)) :walk(i) = 0 :break if (x = ex(cnt)+wdx(cnt)) & (y = ey(cnt)+wdy(cnt)) :walk(i) = 0 :break loop loop *draw_map gmode 0 x = 0 : y = 0 repeat 10 j = cnt repeat 10 i = cnt pos x,y gcopy 1,map(i,j)*32,0,32,32 x += 32 loop x = 0 : y += 32 loop return *draw_chara gmode 4,24,32,256 color 0,117,117 repeat en i = cnt pos ex(i)*32+walk(i)*wdx(i)*8+4,ey(i)*32+walk(i)*wdy(i)*8 if walk(i) = 0 : gcopy 2,24,(edir(i) * 32),24,32 if walk(i) = 1 : gcopy 2,0,(edir(i) * 32),24,32 if walk(i) = 2 : gcopy 2,24,(edir(i) * 32),24,32 if walk(i) = 3 : gcopy 2,48,(edir(i) * 32),24,32 if walk(i) = 4 { gcopy 2,24,(edir(i) * 32),24,32 walk(i) = 0 ex(i) += wdx(i) :ey(i) += wdy(i) wdx(i) = 0 : wdy(i) = 0 } if walk(i):walk(i)++ loop return