HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
0604
ぺーぺー【手直し希望】キャラクター自動移動(マップ上)10解決


ぺーぺー

リンク

2016/6/4(Sat) 20:10:40|NO.75710

移動途中で移動方向設定のスクリプトが正常に作動しなくなります。
どこを載せていいのかわからなかったので全文載せます。すみません。

delete "hsptmp" delete "obj" #module ;モジュール作成 #deffunc dimmix array at ;ユーザー定義命令作成 ax = p ;変数の要素数を取得 repeat ax ;要素数の回数繰り返し randomize ;要素入れ替えをランダム化 q = cnt + rnd(ax - cnt) randomize temp = at(q) randomize at(q) = at(cnt) randomize at(cnt) = temp await 1 loop return #global ;モジュール作成終了 x = 32*10 : y = 32*16 : move = 16 gf = 0 : kai = 0 : mot = 0 //マップチップ読み込み buffer 9,32*3,32 width ,,32*22,0 color 0,0,128 boxf 0,0,31,31 color 128,0,0 boxf 32,0,63,31 color 0,128,0 boxf 64,0,95,31 //マップデータ作成 map = "111111111111111111111" map += "100000000010000000001" map += "101110111010111011101" map += "101110111010111011101" map += "100000000000000000001" map += "101110101111101011101" map += "100000100010001000001" map += "111110111010111011111" map += "000010100000001010000" map += "111110102202201011111" map += "000000002000200000000" map += "111110102222201011111" map += "000010100000001010000" map += "111110101111101011111" map += "100000000010000000001" map += "101110111010111011101" map += "100010000000000010001" map += "111010101111101010111" map += "100000100010001000001" map += "101111111010111111101" map += "100000000000000000001" map += "111111111111111111111" //mapを文字列型から数値型の配列変数に変換 dim mapdata,22,21 ;22*21の二次元変数作成 r = 0 ;0…マップ1段目、1…マップ2段目を指定するための変数 i = 0 ;抜き出す文字列のインデックスを指定 repeat 22 repeat 21 mapdata(r,cnt) = int(strmid(map,i,1)) ;mapdata(1,5)…マップ2段目6枚目を示す。 i += 1 await 1 loop r += 1 await 1 loop //mapから通路情報を作成 ;0 = 通路 ;1 = 非通路 ;2を含む = 左が空いた通路 ;4含む = 上が空いた通路 ;8を含む = 右が空いた通路 ;16を含む = 下が空いた通路 //=========================== dim maproad,22,21 ;通路情報調査用 repeat 22 r = cnt repeat 21 maproad(r,cnt) = 1 ;非通路 if mapdata(r,cnt) = 0{ maproad(r,cnt) = 0 ;通路 //調査位置の上下左右 lr = r : lc = cnt-1 ;左 ur = r-1 : uc = cnt ;上 rr = r : rc = cnt+1 ;右 dr = r+1 : dc = cnt ;下 if lc>0 : if mapdata(lr,lc) = 0 : maproad(r,cnt) |= 2 ;左 if ur>0 : if mapdata(ur,uc) = 0 : maproad(r,cnt) |= 4 ;上 if rc<21 : if mapdata(rr,rc) = 0 : maproad(r,cnt) |= 8 ;右 if dr<22 : if mapdata(dr,dc) = 0 : maproad(r,cnt) |= 16 ;下 } await 1 loop await 1 loop //マップ描画 screen 0,32*21,32*22 width ,,0,0 title "0" redraw 0 repeat 22 r = cnt repeat 21 dmap = mapdata(r,cnt) ;マップ情報取得 pos (cnt*32),(r*32) gmode 2,32,32 gcopy 9,(dmap*32),0 if maproad(r,cnt) = 1 : pos cnt*32+10,r*32+10 : mes "■" if maproad(r,cnt) & 2 : pos cnt*32+10,r*32+10 : mes "←" if maproad(r,cnt) & 4 : pos cnt*32+10,r*32+10 : mes "↑" if maproad(r,cnt) & 8 : pos cnt*32+10,r*32+10 : mes "→" if maproad(r,cnt) & 16 : pos cnt*32+10,r*32+10 : mes "↓" await 1 loop await 1 loop redraw 1 //キャラクター読み込み buffer 1 color 50,50,50 boxf 0,0,31,31 color 100,100,100 boxf 32,0,63,31 //キャラクター描画 gsel 0 repeat gosub *map_comp gosub *move_check pos x,y gmode 2,31,31 if gf = 0{ gcopy 1,0,0 gf = 1 }else{ gcopy 1,32,0 gf = 0 } await 100 loop //キャラクター移動とその判定 *move_check //行動方向検索・指定(最初のみ) if kai = 0{ mx = int(x/32) : my = int(y/32) ;現在マップ割り出し pat = 0,0,0,0 : p = 0 ;次処理の下準備 //マップデータ参照 if maproad(my,mx) & 2{ pat(p) = 2 p += 1 } if maproad(my,mx) & 4{ pat(p) = 4 p += 1 } if maproad(my,mx) & 8{ pat(p) = 8 p += 1 } if maproad(my,mx) & 16{ pat(p) = 16 p += 1 } dimmix pat ;変数内の要素をシャッフル repeat (p-1) if pat(cnt) ! 0{ mot = pat(cnt) break } loop kai = -1 } x = limit(x,0,ginfo_winx-31) y = limit(y,0,ginfo_winy-31) ;x,y範囲指定 mx = int(x/32) : my = int(y/32) ;マップ位置割り出し if mot = 2 : mx = int((x+16)/32) if mot = 4 : my = int((y+16)/32) ;移動方向によってデータ修正 pat = 0,0,0,0 : p = 0 if mot = 2 : bmot = 8 if mot = 4 : bmot = 16 if mot = 8 : bmot = 2 if mot = 16 : bmot = 4 ;引き返す向きを仮定 if maproad(my,mx) & 2{ pat(p) = 2 p += 1 } if maproad(my,mx) & 4{ pat(p) = 4 p += 1 } if maproad(my,mx) & 8{ pat(p) = 8 p += 1 } if maproad(my,mx) & 16{ pat(p) = 16 p += 1 } ;移動可能情報取得 *re_shuffle dimmix pat ;変数内の要素をシャッフル foreach pat if pat(cnt) = 0{ continue }else{ if pat(cnt) = bmap : continue ;引き返す向きを選択したら再選択 mot = pat(cnt) ;移動方向決定 break } await 1 loop if mot = 2 : x -= move if mot = 4 : y -= move if mot = 8 : x += move if mot = 16 : y += move ;移動方向によって座標修正 return //キャラクター周辺マップの再描画 *map_comp return



この記事に返信する


暇人

リンク

2016/6/5(Sun) 18:25:55|NO.75729

とりあえず
> if pat(cnt) = bmap : continue ;引き返す向きを選択したら再選択
の変数名が間違ってる

他の問題として
半端な座標でも方向を変えるようにしてるので
半分壁にめり込んで進んでしまう



ぺーぺー

リンク

2016/6/5(Sun) 21:18:17|NO.75738

>>暇人
あ、本当ですね。ありがとうございます。
修正したところ発生していたエラーは見られなくなりました。
ただ、
>>半端な座標でも方向を変えるようにしてるので半分壁にめり込んで進んでしまう
これに関しては、mx,myの指定のあとのif群で調整できていると思うのですが。
原因が思いつかないのですが…



暇人

リンク

2016/6/5(Sun) 21:59:16|NO.75740

角から下に移動した場合
次のフレームでも角のマップを参照してしまってずれた状態で進む
(32+16)/32は1で次の場所には移動してないため起こる現象
逆に上移動は(32-16)/32で0になるので角から抜ける


> x = limit(x,0,ginfo_winx-31)
の上野行に

if (x\32)=0 and (y\32)=0 {
挿入して

> if mot = 2 : x -= move
の上に

}
を挿入すると
とりあえず問題無くなる

後関係ないけどrandomizeは最初に一回実行すれば良い



ぺーぺー

リンク

2016/6/5(Sun) 22:36:37|NO.75741

>>暇人
ありがとうございます。やってみます。

> if mot = 2 : x -= moveの上に
の下のコードが
}
しかなくどうすればいいのか…
申し訳ないのですが、再投稿していただけると助かります。



暇人

リンク

2016/6/5(Sun) 22:42:20|NO.75742

いや
そのままだけど・・・
(x\32)=0 and (y\32)=0 の時だけ{}間のスクリプトを実行するのが目的



ぺーぺー

リンク

2016/6/5(Sun) 23:20:32|NO.75743

>>if (x\32)=0 and (y\32)=0 {
ここの
}
を見逃してました。すみません
迷路内をきちんと移動するようにはなりましたが、同じルートを周回してしまいます。 もし可能ならこちらについてもヒントを頂けませんか?



暇人

リンク

2016/6/6(Mon) 00:02:08|NO.75744

それはdimmixが機能して無いから
モジュール内でモジュール外の変数から代入しようとしてる
変数pをパラメータとして渡すか p@ として直接利用するか



ぺーぺー

リンク

2016/6/6(Mon) 20:34:16|NO.75749

>>暇人
ありがとうございます。おかげさまで問題なく動くようになりました。
ただ、敵の数を4体に増やそうとしたところ
>>配列の要素が無効です。
と表示され、走らなくなりました。
他のサイトなどでも調べ、いろいろと解決策を試してはみたのですが、直りませんでした。

delete "hsptmp" delete "obj" #module ;モジュール作成 #deffunc dimmix array at ;ユーザー定義命令作成 mx = length(at) ;変数の要素数を取得 repeat mx ;要素数の回数繰り返し randomize ;要素入れ替えをランダム化 r = cnt + rnd(mx - cnt) temp = at(r) at(r) = at(cnt) at(cnt) = temp loop return #global x = 32*4,32*14,32*15,32*5 : y = 32*2,32*7,32*15,32*17 gf = 0,0,0,0 : kai = 0,0,0,0 : mot = 0,0,0,0 ;要素で指定し、repeat管理を簡易化 move = 16 //マップチップ読み込み buffer 1,32*3,32 color 0,0,128 boxf 0,0,31,31 color 128,0,0 boxf 32,0,63,31 color 0,128,0 boxf 64,0,95,31 //マップデータ作成 map = "111111111111111111111" map += "100000000010000000001" map += "101110111010111011101" map += "101110111010111011101" map += "100000000000000000001" map += "101110101111101011101" map += "100000100010001000001" map += "111110111010111011111" map += "000010100000001010000" map += "111110102202201011111" map += "000000002000200000000" map += "111110102222201011111" map += "000010100000001010000" map += "111110101111101011111" map += "100000000010000000001" map += "101110111010111011101" map += "100010000000000010001" map += "111010101111101010111" map += "100000100010001000001" map += "101111111010111111101" map += "100000000000000000001" map += "111111111111111111111" //mapを文字列型から数値型の配列変数に変換 dim mapdata,22,21 ;22*21の二次元変数作成 r = 0 ;0…マップ1段目、1…マップ2段目を指定するための変数 i = 0 ;抜き出す文字列のインデックスを指定 repeat 22 repeat 21 mapdata(r,cnt) = int(strmid(map,i,1)) ;mapdata(1,5)…マップ2段目6枚目を示す。 i += 1 await 1 loop r += 1 await 1 loop //mapから通路情報を作成 ;0 = 通路 ;1 = 非通路 ;2を含む = 左が空いた通路 ;4含む = 上が空いた通路 ;8を含む = 右が空いた通路 ;16を含む = 下が空いた通路 //=========================== dim maproad,22,21 ;通路情報調査用 repeat 22 r = cnt repeat 21 maproad(r,cnt) = 1 ;非通路 if mapdata(r,cnt) = 0{ maproad(r,cnt) = 0 ;通路 //調査位置の上下左右 lr = r : lc = cnt-1 ;左 ur = r-1 : uc = cnt ;上 rr = r : rc = cnt+1 ;右 dr = r+1 : dc = cnt ;下 if lc>0 : if mapdata(lr,lc) = 0 : maproad(r,cnt) |= 2 ;左 if ur>0 : if mapdata(ur,uc) = 0 : maproad(r,cnt) |= 4 ;上 if rc<21 : if mapdata(rr,rc) = 0 : maproad(r,cnt) |= 8 ;右 if dr<22 : if mapdata(dr,dc) = 0 : maproad(r,cnt) |= 16 ;下 } await 1 loop await 1 loop //マップ描画 screen 0,32*21,32*22 width ,,((ginfo(20)-(32*21))/2),((ginfo(21)-(32*22))/2) title "0" redraw 0 repeat 22 r = cnt repeat 21 dmap = mapdata(r,cnt) ;マップ情報取得 pos (cnt*32),(r*32) gmode 2,32,32 gcopy 1,(dmap*32),0 if maproad(r,cnt) = 1 : pos cnt*32+10,r*32+10 : mes "■" if maproad(r,cnt) & 2 : pos cnt*32+10,r*32+10 : mes "←" if maproad(r,cnt) & 4 : pos cnt*32+10,r*32+10 : mes "↑" if maproad(r,cnt) & 8 : pos cnt*32+10,r*32+10 : mes "→" if maproad(r,cnt) & 16 : pos cnt*32+10,r*32+10 : mes "↓" await 1 loop await 1 loop redraw 1 //キャラクター読み込み buffer 2 color 50,50,50 boxf 0,0,31,31 color 100,100,100 boxf 32,0,63,31 buffer 3 color 100,100,100 boxf 0,0,31,31 color 150,150,150 boxf 32,0,63,31 buffer 4 color 150,150,150 boxf 0,0,31,31 color 200,200,200 boxf 32,0,63,31 buffer 5 color 200,200,200 boxf 0,0,31,31 color 240,240,240 boxf 32,0,63,31 //キャラクター描画 gsel 0 repeat repeat 4 ccnt = cnt ;複数キャラクター管理用変数 gosub *map_comp gosub *move_check pos x(ccnt),y(ccnt) gmode 2,31,31 if gf(ccnt) = 0{ gcopy (2+ccnt),0,0 gf(ccnt) = 1 }else{ gcopy (2+ccnt),32,0 gf(ccnt) = 0 } await 100 loop await 1 loop //キャラクター移動とその判定 *move_check //行動方向検索・指定(最初のみ) if kai(ccnt) = 0{ mx = int(x(ccnt)/32) : my = int(y(ccnt)/32) ;現在マップ割り出し pat = 0,0,0,0 : p = 0 ;次処理の下準備 //マップデータ参照 if maproad(my,mx) & 2{ pat(p) = 2 p += 1 } if maproad(my,mx) & 4{ pat(p) = 4 p += 1 } if maproad(my,mx) & 8{ pat(p) = 8 p += 1 } if maproad(my,mx) & 16{ pat(p) = 16 p += 1 } dimmix pat ;変数内の要素をシャッフル repeat (p-1) if pat(cnt) ! 0{ mot(ccnt) = pat(cnt) break } await 1 loop kai(ccnt) = -1 } if (x(ccnt)\32)=0 and (y(ccnt)\32)=0 { x(ccnt) = limit(x(ccnt),0,ginfo_winx-31) y(ccnt) = limit(y(ccnt),0,ginfo_winy-31) ;x,y範囲指定 mx = int(x(ccnt)/32) : my = int(y(ccnt)/32) ;マップ位置割り出し if mot(ccnt) = 2 : mx = int((x(ccnt)+16)/32) if mot(ccnt) = 4 : my = int((y(ccnt)+16)/32) ;移動方向によってデータ修正 pat = 0,0,0,0 : p = 0 if mot(ccnt) = 2 : bmot = 8 if mot(ccnt) = 4 : bmot = 16 if mot(ccnt) = 8 : bmot = 2 if mot(ccnt) = 16 : bmot = 4 ;引き返す向きを仮定 if maproad(my,mx) & 2{ pat(p) = 2 p += 1 } if maproad(my,mx) & 4{ pat(p) = 4 p += 1 } if maproad(my,mx) & 8{ pat(p) = 8 p += 1 } if maproad(my,mx) & 16{ pat(p) = 16 p += 1 } ;移動可能情報取得 dimmix pat ;変数内の要素をシャッフル foreach pat if pat(cnt) = 0{ continue }else{ if pat(cnt) = bmot : continue ;引き返す向きを選択したら再選択 mot(ccnt) = pat(cnt) ;移動方向決定 break } await 1 loop } if mot(ccnt) = 2 : x(ccnt) -= move if mot(ccnt) = 4 : y(ccnt) -= move if mot(ccnt) = 8 : x(ccnt) += move if mot(ccnt) = 16 : y(ccnt) += move ;移動方向によって座標修正 return //キャラクター周辺マップの再描画 *map_comp bmx = int(x(ccnt)/32) : bmy = int(y(ccnt)/32) bmapnum = bmx + (bmy*21) bmapcode = int(peek(map,bmapnum)) pos (bmx*32),(bmy*32) gmode 2,32,32 gcopy 1,0,0 repeat 4 if cnt = 0 : bmapnum = (bmx-1) + (bmy*21) if cnt = 1 : bmapnum = bmx + ((bmy-1)*21) if cnt = 2 : bmapnum = (bmx+1) + (bmy*21) if cnt = 3 : bmapnum = bmx + ((bmy+1)*21) bmapcode = peek(map,bmapnum) if cnt = 0 : pos ((bmx-1)*32),(bmy*32) if cnt = 1 : pos (bmx*32),((bmy-1)*32) if cnt = 2 : pos ((bmx+1)*32),(bmy*32) if cnt = 3 : pos (bmx*32),((bmy+1)*32) gmode 2,32,32 if bmapcode = '0' : bdmap = 0 if bmapcode = '1' : bdmap = 1 if bmapcode = '2' : bdmap = 2 gcopy 1,0+(bdmap*32),0 loop return
またしてもすみません。全文掲載です。
「変数の型が…」というようなことだったのでいろいろと触ってみたのですが…
ヒントをいただけると助かります。何度もすみません。



暇人

リンク

2016/6/6(Mon) 21:08:07|NO.75750

エラーになったらその周辺で使われてる変数等を表示したり
logmes等つかって見えるようにした方が良い
> repeat (p-1)
> if pat(cnt) ! 0{
pが0の時にループ回数が-1で無限になってしまって
cntが4の時にエラーが出る

pが0になってる原因は
> x = 32*4,32*14,32*15,32*5 : y = 32*2,32*7,32*15,32*17
の位置が道以外を指してるから

後randomizeはループ内じゃなくメインループ前に一回だけ実行すれば良い



ぺーぺー

リンク

2016/6/6(Mon) 22:04:55|NO.75751

>>暇人
ありがとうございます。おかげさまで完成しました。
これからもお願いします。



ONION software Copyright 1997-2021(c) All rights reserved.