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


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
0607
ぺーぺー【手直し希望】自キャラが壁に半分埋まる4解決


ぺーぺー

リンク

2016/6/7(Tue) 22:00:59|NO.75780

お世話になります。
パックマンを作成しているのですが、自キャラの下と右半分が壁に半分重なった状態で進むと、めり込んだまま進んでしまいます。
*move_check_tekiを参考にして編集したのですが、今度は全く動かなくなりました。
どうしてでしょうか?
	delete "hsptmp"
delete "obj" #module ;モジュール作成 #deffunc dimmix array at ;ユーザー定義命令作成 mx = length(at) ;変数の要素数を取得 randomize ;要素入れ替えをランダム化 repeat mx ;要素数の回数繰り返し r = cnt + rnd(mx - cnt) temp = at(r) at(r) = at(cnt) at(cnt) = temp loop return #global x = 320 : y = 512 : move = 16 : muki = 1 xt = 32*4,32*13,32*1,32*5 : yt = 32*1,32*6,32*15,32*17 gf = 0 : kai = 0,0,0,0 : mot = 0,0,0,0 ;要素で指定し、repeat管理を簡易化 sdim map,462 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,672,704 width ,,((ginfo(20)-672)/2),0 *main cls celload "hidari.bmp",1 celload "ue.bmp",2 celload "migi.bmp",3 celload "shita.bmp",4 //キャラクター画像読み込み celload "teki.bmp",5 //敵キャラクター画像読み込み celload "maptip.jpg",6 gosub *map_draw repeat ifx = x : ify = y redraw 0 stick key,15 if (key = 1) or (key = 2) or (key = 4) or (key = 8) : gosub *move_check gosub *map_comp repeat 4 ccnt = cnt ;複数キャラクター管理用変数 gosub *move_check_teki gosub *map_comp_teki await 1 loop repeat 4 ccnt = cnt pos xt(ccnt),yt(ccnt) gmode 2,31,31 gcopy 5,(32*ccnt),0 loop pos x,y gmode 2,31,31 if gf = 0 { gcopy muki,0,0;画像コピー gf = 1 }else{ gcopy muki,32,0;画像コピー gf = 0 } redraw 1 await 100 loop stop *move_check if key = 1 : muki = 1 : check = 2 if key = 2 : muki = 2 : check = 4 if key = 4 : muki = 3 : check = 8 if key = 8 : muki = 4 : check = 16 mx = int(x/32) : my = int(y/32) cx = int((x+31)/32) : cy = int((y+31)/32) if muki = 2 : mx = int((x+16)/32) if muki = 4 : my = int((y+16)/32) if (maproad(my,mx) & check) and (maproad(cx,cy) & 0){ if muki = 1 : x -= move if muki = 2 : y -= move if muki = 3 : x += move if muki = 4 : y += move } return *map_draw i = 0 redraw 0 repeat 22 my = cnt repeat 21 maps = peek(map,i) if maps = '0' : dmap = 0 if maps = '1' : dmap = 1 if maps = '2' : dmap = 2 pos cnt*32,my*32 gmode 2,32,32 gcopy 6,dmap*32,0 i += 1 await 1 loop await 1 loop redraw 1 return *map_comp bmx = int(x/32) : bmy = int(y/32) bmapnum = bmx + (bmy*21) bmapcode = peek(map,bmapnum) pos (bmx*32),(bmy*32) gmode 2,32,32 gcopy 6,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 6,0+(bdmap*32),0 loop return *move_check_teki //行動方向検索・指定(最初のみ) if kai(ccnt) = 0{ mxt = int(xt(ccnt)/32) : myt = int(yt(ccnt)/32) ;現在マップ割り出し pat = 0,0,0,0 : p = 0 ;次処理の下準備 //マップデータ参照 if maproad(myt,mxt) & 2{ pat(p) = 2 p += 1 } if maproad(myt,mxt) & 4{ pat(p) = 4 p += 1 } if maproad(myt,mxt) & 8{ pat(p) = 8 p += 1 } if maproad(myt,mxt) & 16{ pat(p) = 16 p += 1 } dimmix pat ;変数内の要素をシャッフル repeat p if pat(cnt) ! 0{ mot(ccnt) = pat(cnt) break } await 1 loop kai(ccnt) = -1 } if (xt(ccnt)\32)=0 and (yt(ccnt)\32)=0 { xt(ccnt) = limit(xt(ccnt),0,ginfo_winx-31) yt(ccnt) = limit(yt(ccnt),0,ginfo_winy-31) ;x,y範囲指定 mxt = int(xt(ccnt)/32) : myt = int(yt(ccnt)/32) ;マップ位置割り出し if mot(ccnt) = 2 : mxt = int((xt(ccnt)+16)/32) if mot(ccnt) = 4 : myt = int((yt(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(myt,mxt) & 2{ pat(p) = 2 p += 1 } if maproad(myt,mxt) & 4{ pat(p) = 4 p += 1 } if maproad(myt,mxt) & 8{ pat(p) = 8 p += 1 } if maproad(myt,mxt) & 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 : xt(ccnt) -= move if mot(ccnt) = 4 : yt(ccnt) -= move if mot(ccnt) = 8 : xt(ccnt) += move if mot(ccnt) = 16 : yt(ccnt) += move ;移動方向によって座標修正 return //キャラクター周辺マップの再描画 *map_comp_teki bmxt = int(xt(ccnt)/32) : bmyt = int(yt(ccnt)/32) bmapnumt = bmxt + (bmyt*21) bmapcodet = int(peek(map,bmapnumt)) pos (bmxt*32),(bmyt*32) gmode 2,32,32 gcopy 6,0,0 repeat 4 if cnt = 0 : bmapnumt = (bmxt-1) + (bmyt*21) if cnt = 1 : bmapnumt = bmxt + ((bmyt-1)*21) if cnt = 2 : bmapnumt = (bmxt+1) + (bmyt*21) if cnt = 3 : bmapnumt = bmxt + ((bmyt+1)*21) bmapcodet = peek(map,bmapnumt) if cnt = 0 : pos ((bmxt-1)*32),(bmyt*32) if cnt = 1 : pos (bmxt*32),((bmyt-1)*32) if cnt = 2 : pos ((bmxt+1)*32),(bmyt*32) if cnt = 3 : pos (bmxt*32),((bmyt+1)*32) gmode 2,32,32 if bmapcodet = '0' : bdmapt = 0 if bmapcodet = '1' : bdmapt = 1 if bmapcodet = '2' : bdmapt = 2 gcopy 6,0+(bdmapt*32),0 loop return
どこを乗せればいいかわからなかったので、全文になってます。本当にすみません。



この記事に返信する


掘木

リンク

2016/6/8(Wed) 08:48:23|NO.75783

動けない主因
move_check内のifで0をand演算している。
結果、このifの中身は偽で確定し、実際に座標を変更する所に到達できない。

改善の為に
どういう条件が妥当なのかじっくり考える、テストケースを用意して試行錯誤など。
末端の0を変えれば確かに動きはするが、意図した動きにはきっとならないと思う。
「なにを判定したいのか」をコメントにしておいて損はないんじゃないかな。
(壁に阻まれていないなら とかだと大雑把すぎて後から困る)

その他
今はプレイヤーの動きの段階なので敵の処理部分はバッサリカットできるはず。

相変わらずこうすればいいを具体的に提示しない方針。



ぺーぺー

リンク

2016/6/8(Wed) 14:45:06|NO.75787

>>堀木
助言ありがとうございます。
現在のスクリプトではmaproadに移動可能方向や壁判定などが格納されており、それを元にキャラの移動判定をしたいと考えています。



掘木

リンク

2016/6/8(Wed) 21:25:43|NO.75789

ちなみに、件のifの左側のカッコ内は次のように解釈出来る

左、右キー入力時:プレイヤーの位置を示す矩形の左上が含まれているマス目に対して、
上キー入力時:プレイヤーの矩形の上端の中央が含まれているマス目に対して、
下キー入力時:プレイヤーの矩形の左端の中央が含まれているマス目に対して、

そのマス目が移動しようとしている向きに通路が空いているか

を判定しています。(実際にはビット演算結果のためこの後にビット演算結果が絡むと難しいが)

…なんだこの複雑怪奇な判定内容は。


よく見ると敵の移動処理の部分もなかなかに世紀末な処理してますなあ。



ぺーぺー

リンク

2016/6/8(Wed) 21:52:40|NO.75790

>>堀木
ご指摘を参考にして作りなおしたところ問題なく作動しました。
どうもお世話になりました。



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