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


HSPTV!掲示板


未解決 解決 停止 削除要請

2012
1123
HIJIKI2点間の障害物有無を調べる方法19解決


HIJIKI

リンク

2012/11/23(Fri) 10:20:20|NO.50805

まず具体的な用途を書きます。
[1]キャタクターに「攻撃範囲内の一番近い敵」をターゲットさせたい。
[2]ターゲットする敵と自分の間に障害物があってはならない。
[3]この処理は1ループにつき32回ほど行いたい。
(最低でも10回は処理落ち無く繰り返したい)

これが実現したい物なのですが、すでに[1]は実現できております。
ですがそれに[2]を組み込もうと思うと、自分の思いつく限りでは
満足な動作が得られません。(後述)
それでもとりあえず動いたのですが、[3]の通り32回処理させたところ、
スペックにもよるでしょうが、チェックだけに5msほどかかってしまいます。
作っているゲームは1ループの処理が16ms以内に収まるようにしたいので、
この処理だけに5msも使ってしまうと他をかなり削らないといけなくなってしまいます。
皆さんの思いつく障害物のチェック方法を教えて下されば幸いです。

スクリプトは以下の通りです。
やりたいこと、今とっている方法が分かっていただけると思います。
http://holyweb.dip.jp/tmpfiles/main.hsp

このスクリプトでは、画面端などをクリックすると配列の要素数エラーが出ますが、
今回は関係ない話なのでそれを回避するためのコードは余計だと判断し書いていません。

また、後述すると書いた「満足の動作が得られない状態」
というのは具体的にこのような状態を意味しています。
http://pckles.com/hijiki_seaweed/70f663.png
チェック間隔に隙間があるため、角にギリギリ触れている場合などに
ヒットしていないものと判断されてしまいます。
チェック間隔を1ピクセル単位などにすればこの問題は解決しますが、
[3]をクリアするためにはそういうわけにもいきません。
何でもよいのでアドバイスをよろしくお願いいたします。



この記事に返信する


HIJIKI

リンク

2012/11/23(Fri) 10:28:26|NO.50806

サンプルの操作方法を記述し忘れたため、追記させて頂きます。
左クリック:障害物を設置
右ドラッグ:ラインを描画
Ctrl:障害物およびラインをリセット
やりたいことは、ライン上に障害物があるかどうか です。
よろしくお願いいたします。



@key

リンク

2012/11/23(Fri) 13:58:35|NO.50809

当たり判定を調べたい線を配列に保存しておき、マップタイル一つごとに
「短形と線分の当たり判定を求める」モジュールで調べる、というのが一般的かと

「短形と(略」モジュールのヒントはこれ(ヒントだけですが結構簡単に作れます)
http://hspdev-wiki.net/?%BE%D7%C6%CD%C8%BD%C4%EA#md52a044

あとは自分で頑張って下さい(めんどくさい)



@key

リンク

2012/11/23(Fri) 14:15:06|NO.50810

あとできれば自力でこういう論理問題を解いて欲しいので
他の人はさっさとモジュール化しないで下さい・・・
質問で要望がでたら教えてあげて下さい(めんどくさい)

短形と線分の当たり判定を出の時少くとも(自分の方法だと)計算6回必要なので軽くなるかはわかりません



暇人

リンク

2012/11/23(Fri) 18:37:44|NO.50816

>他の人はさっさとモジュール化しないで下さい・・・
余計なお世話
そんな事を制限する権限は貴方には無い

掲示板の回答は質問者だけが利用してる訳じゃない
答えが分かってる人でも他人のやり方が参考になる場合もある



晩御飯

リンク

2012/11/23(Fri) 19:18:46|NO.50819

実際に制限しているわけでもないのにわざわざ噛み付いてくる人って・・・



ANTARES

リンク

2012/11/23(Fri) 22:05:48|NO.50823

 それにまたかみつく人がいるのと同じこと。



@key

リンク

2012/11/23(Fri) 23:23:27|NO.50827

いたちごっこはやめようや



kanahiron

リンク

2012/11/24(Sat) 00:30:48|NO.50833

荒れていますがなんとなく考えたので投下
すべての座標を25x25として考えたやり方です
若干誤差が大きいですが、二倍くらい早いです
そのままでは(誤差が大きくて)使えないと思うので参考程度に

//スクリプトの最初に #uselib "winmm.dll" #cfunc msec "timeGetTime" //を追加 //サブルーチンだけ抜き出し *__hit ///↓速度計測に100回ループ st = msec() repeat 100 ///↑ repeat 25 //マウス座標を0〜24に変換 if (line_x1 >= (cnt*24)) & (line_x1 < ((cnt+1)*24)):x1 = double(cnt) if (line_x2 >= (cnt*24)) & (line_x2 < ((cnt+1)*24)):x2 = double(cnt) if (line_y1 >= (cnt*24)) & (line_y1 < ((cnt+1)*24)):y1 = double(cnt) if (line_y2 >= (cnt*24)) & (line_y2 < ((cnt+1)*24)):y2 = double(cnt) loop ax = (x2-x1) ay = (y2-y1) bx = ax/37 //37は25*√2の数 by = ay/37 cx = x1 cy = y1 line_col = 0 repeat 37 cx += bx cy += by //↓ 0〜24を超えるとエラーになるので丸めて座標にする if map_data.(limit(cx,0,24)).(limit(cy,0,24)):line_col = 255 loop ///↓ loop en = msec() ms = (en-st) title "100回ループに"+ms+"msかかりました" ///↑ return

HIJIKIさんの100回ループで大体1〜22ms(近いほど小さい)
自分の100回ループで6ms(均一)です



HIJIKI

リンク

2012/11/24(Sat) 02:34:35|NO.50843

>@keyさん
返答ありがとうございます。
せっかく頂いた返答に、組んでみもせずにこんなことを
言うのはなんですが、今回制作するゲームでは、
線分(最大32本)と矩形(最大300個ほど)が登場します。
全て行うとなるとかなり動作速度が心配です…。
それ以前に線分と矩形の当たり判定をやったことがなかったので、
すぐに制作できる自信がなく、先に返答させて頂くことにしました。
とりあえず案を頂いたことに感謝いたします。
ありがとうございました。



HIJIKI

リンク

2012/11/24(Sat) 02:43:33|NO.50844

>kanahironさん
返答ありがとうございます。
頂いたスクリプトを拝見しました。
分かりやすく書いて頂いたのでしょうが、
何を(どういう処理を)やっているのか
あまり理解できませんでした…;
挙動としては素晴らしいです。
が、今回使用したいゲームではこの誤差が致命的なので、
仰る通りこのまま使わせて頂くのではなく、
参考にさせて頂きます。ありがとうございました。

ここまでで頂いた案をもとに、アルゴリズムを構築してみますが、
他のアルゴリズムも引き続き募集させて頂きます。



てれてれ

リンク

2012/11/24(Sat) 11:46:34|NO.50846

短形と線分の比較方式。
速度は微妙かな。
チェック不必要な部分判定の条件をより細かくして無駄なチェックを省いていけばもっと高速になると思うんだけれども。


//スクリプトの最初に #uselib "winmm.dll" #cfunc msec "timeGetTime" //を追加 //サブルーチンだけ抜き出し *__hit st = msec() //時間計測スタート repeat 32 //32回繰り返す dim hit, MapSize+1, MapSize+1 //同じ座標を何度もチェックするのを防止するための変数 x1 = double(line_x1) : x2 = double(line_x2) y1 = double(line_y1) : y2 = double(line_y2) if (x1-x2) = 0 : continue //除算エラー回避 ic = (y1-y2)/(x1-x2) //ラインの切片を求める line_col = 0 repeat MapSize : x = cnt repeat MapSize : y = cnt if map_data(x, y) = 1 { ConFlag = 1,1 //明らかにチェック不要なマスをスキップ if (x+1)*TileSize >= x1 and x*TileSize <= x2 : ConFlag(0) = 0 if (x+1)*TileSize >= x2 and x*TileSize <= x1 : ConFlag(0) = 0 if (y+1)*TileSize >= y1 and y*TileSize <= y2 : ConFlag(1) = 0 if (y+1)*TileSize >= y2 and y*TileSize <= y1 : ConFlag(1) = 0 if ConFlag(0) = 1 or ConFlag(1) = 1 : continue repeat 4 //1マスの端の4点をチェック // h = p1,p2,p3,p4 // p1 : チェックする点のx座標 // p2 : チェックする点のy座標 // p3,p4 : チェック抜け防止のために1px余分にチェックする為の補正値 if cnt = 0 : h = x,y,-1,-1 if cnt = 1 : h = x+1,y,1,-1 if cnt = 2 : h = x,y+1,-1,1 if cnt = 3 : h = x+1,y+1,1,1 if hit(h(0),h(1)) = 0{//まだチェックしていない座標だったらチェック if h(1)*TileSize+h(3) < y1+ic*(h(0)*TileSize-x1+h(2)) : hit(h(0),h(1)) = 1 //チェックする点がラインより上にある時 if h(1)*TileSize+h(3) >= y1+ic*(h(0)*TileSize-x1+h(2)) : hit(h(0),h(1)) = 2 //チェックする点がラインより下にある時 } if hit(x,y) != hit(h(0),h(1)) : line_col = 255 : break //チェックした点の比較により、ラインが障害物の上にある事が確定した時 loop if line_col = 255 : break } loop if line_col = 255 : break loop loop en = msec() //時間計測ストップ title "32回ループに"+(en-st)+"msかかりました" return



月1で来る人

リンク

2012/11/25(Sun) 09:56:06|NO.50858

1. 自キャラと敵キャラとの角度を ang_my_enemy に代入
2. 自キャラと障害物との距離を dist_my_obst に代入
3. 以下で求める座標 (x, y) と障害物とのあたり判定を行う
x = dist_my_obst * cos(ang_my_enemy);
y = dist_my_obst * sin(ang_my_enemy);

上記の処理をすべての障害物について適用する。
最終的には、C/C++言語とかで当たり判定のモジュールをこさえればよいと思うよ。



暇人

リンク

2012/11/25(Sun) 22:01:07|NO.50876

これは線分と矩形の判定を使わないでNO.50805のを
ライン上に有る全てのグリッドに対して判定するようにしたスクリプト(ちょっと修正して再掲載)

障害物の数が増えても判定処理の負荷は変わらない
理論上障害物が多い方が判定途中で当たる確率が高くなるので軽くなる

#uselib "winmm.dll" #cfunc msec "timeGetTime" #define TileSize 24 ;タイル1枚のサイズ(ピクセル) #define MapSize 25 ;マップの縦横タイル枚数(w=h) dim map_data, MapSize, MapSize ;地形データ2次元配列(x,y) screen 0, TileSize*MapSize, TileSize*MapSize randomize #define LineMax 32 repeat LineMax-1,1 line_x1(cnt)=rnd(TileSize*MapSize) line_y1(cnt)=rnd(TileSize*MapSize) line_x2(cnt)=rnd(TileSize*MapSize) line_y2(cnt)=rnd(TileSize*MapSize) loop dim line_col,LineMax ;--------------------------------------------------------------------------------------------------- ;/ メインループ ;--------------------------------------------------------------------------------------------------- *__main ;----------------------------------------------------------------------------------------------- ;* 処理 ;----------------------------------------------------------------------------------------------- cursor_x = mousex/TileSize cursor_y = mousey/TileSize stick ky, 256+512+64 ;障害物を設置(左クリック) if ky & 256 { if map_data(cursor_x, cursor_y)=0 and (cursor_x_old=cursor_x and cursor_y_old=cursor_y)=0{ map_data(cursor_x, cursor_y) = 1 }else{//既に障害物が置かれてたら削除(クリックした時の一回だけ) if lc=0{map_data(cursor_x, cursor_y) = 0 } cursor_x_old=cursor_x cursor_y_old=cursor_y } lc=1 }else{ cursor_x_old=-1 cursor_y_old=-1 lc=0 } ;ラインを設置(右ドラッグ) if ky & 512 { if i = 0 { line_x1 = mousex line_y1 = mousey line_x2 = mousex line_y2 = mousey } else { line_x2 = mousex line_y2 = mousey } i = 1 } else { i = 0 } ;リセット(Ctrl) if ky & 64 { line_x1 = 0 : line_y1 = 0 : line_x2 = 0 : line_y2 = 0 dim map_data, MapSize, MapSize } startTime = msec() gosub *__hit endTime = msec() title ""+(endTime-startTime)+"ms" ;----------------------------------------------------------------------------------------------- ;* 描画 ;----------------------------------------------------------------------------------------------- redraw 0 color 255,255,255:boxf:color ;グリッド repeat MapSize x = cnt line x*TileSize, 0, x*TileSize, ginfo_winy repeat MapSize y = cnt line 0, y*TileSize, ginfo_winx, y*TileSize loop loop ;カーソル x = cursor_x*TileSize y = cursor_y*TileSize color 255, 200, 200 boxf x+1, y+1, x+TileSize-1, y+TileSize-1 ;障害物 color repeat MapSize x = cnt repeat MapSize y = cnt if map_data(x, y) = 1 { boxf x*TileSize+1, y*TileSize+1, x*TileSize+TileSize-1, y*TileSize+TileSize-1 } loop loop ;ライン repeat LineMax color line_col(cnt),,255-line_col(cnt) line line_x1(cnt), line_y1(cnt), line_x2(cnt), line_y2(cnt) loop await 17 redraw 1 goto *__main ;--------------------------------------------------------------------------------------------------- ;/ 以下サブルーチン ;--------------------------------------------------------------------------------------------------- ;ラインが障害物にヒットしているかチェックするサブルーチン ;やっていることは、xy1からxy2のライン上に存在するグリッドを全て判定 ;縦横どちらのグリッドラインを先(近いかでは無い)に通過するかで処理を分けてる *__hit repeat LineMax x1 = double(line_x1(cnt)) : x2 = double(line_x2(cnt)) y1 = double(line_y1(cnt)) : y2 = double(line_y2(cnt)) line_col(cnt) = 0 VectorX=(x2-x1) VectorY=(y2-y1) Distance=sqrt(VectorX*VectorX+VectorY*VectorY) if Distance>0 {//Distance=0だったら距離が0なので判定しない if VectorX<0{//←側に進んでる line_EndX=double((line_x2(cnt)/TileSize)*TileSize-TileSize) //Xの最終地点(グリッドの座標) line_NextX=double((line_x1(cnt)/TileSize)*TileSize)//Xの次に通過するグリッドライン TileSizeX=-TileSize }else{//右側に進んでる line_EndX=double((line_x2(cnt)/TileSize)*TileSize+TileSize*2) line_NextX=double((line_x1(cnt)/TileSize)*TileSize+TileSize) TileSizeX=TileSize } if VectorY<0{//上側に進んでる line_EndY=double((line_y2(cnt)/TileSize)*TileSize-TileSize) line_NextY=double((line_y1(cnt)/TileSize)*TileSize) TileSizeY=-TileSize }else{//↓側に進んでる line_EndY=double((line_y2(cnt)/TileSize)*TileSize+TileSize*2) line_NextY=double((line_y1(cnt)/TileSize)*TileSize+TileSize) TileSizeY=TileSize } vx=VectorX/Distance //Xの速度 vy=VectorY/Distance //Yの速度 if map_data(int(x1)/TileSize, int(y1)/TileSize) = 1 {//開始地点の判定 ;ヒットしている line_col(cnt) = 255 }else{ ZeroF=0//XかYが0だった時のフラグXなら2、Yなら1 if VectorX=0{ZeroF=2} if VectorY=0{ZeroF=1} _cnt=cnt repeat RangeX=line_NextX-x1 //次のグリッドラインまでの距離 RangeY=line_NextY-y1 if ZeroF=0{//フラグ0なので斜めに進んでる PassTimeX=(RangeX/vx) //グリッドラインまでの通過カウント(少ないほど早い) PassTimeY=(RangeY/vy) if PassTimeX < PassTimeY {PassXY=1}else{PassXY=2}//通過時間フラグXの方が早いなら1、Yなら2 }else{ PassXY=ZeroF//0フラグを通過時間フラグに使用 if ZeroF=2{//2ならXが0なのでXの通過カウントを0に PassTimeX=0.0 PassTimeY=(RangeY/vy) }else{ PassTimeX=(RangeX/vx) PassTimeY=0.0 } } if PassXY=1 {//縦ライン(X方向)の方を先に通過する x1=line_NextX //今回使ったグリッドラインを現在のX座標に line_NextX+TileSizeX //次回グリッドライン座標を設定 if line_NextX = line_EndX {break} //次のグリッドラインが最終グリッドラインに到達してたら判定終了 if line_NextY = line_EndY {break} y1+=PassTimeX*vy //Xがグリッドラインに到達した時間でYが進めた距離を加算 x=(int(x1))/TileSize xx=(int(x1)-1)/TileSize //グリッドの縦横ライン交差部分用の対策 y=(int(y1))/TileSize if map_data(x, y) = 1 or map_data(xx, y) = 1{ ;ヒットしている line_col(_cnt) = 255 break } if (line_NextY-y1)=0 {//グリッドの交差部分用の対策(無くてもいけるかもしれない) line_NextY+TileSizeY } }else{//横ライン(Y方向)の方を先に通過する(同時でもこちら) y1=line_NextY line_NextY+TileSizeY if line_NextX = line_EndX {break} if line_NextY = line_EndY {break} x1+=PassTimeY*vx x=(int(x1))/TileSize y=(int(y1))/TileSize yy=(int(y1)-1)/TileSize if map_data(x, y) = 1 or map_data(x, yy) = 1{ ;ヒットしている line_col(_cnt) = 255 break } if (line_NextX-x1)=0 {//グリッドの交差部分用の対策(無いと同じグリッドを2回判定してしまう) line_NextX+TileSizeX } } loop } }//距離が0なら判定しない loop return
自分で確かめた限りでは出来てるけどバグが無いかは分からない

質問の後半しか頭に無くて使えるか分からないけど
NO.50805のよりは軽く正確になってると思う・・・



HIJIKI

リンク

2012/11/25(Sun) 22:03:45|NO.50877

>てれてれさん
返答ありがとうございます。
そして素晴らしいサブルーチンを組んで頂いたことに感謝します。
//明らかにチェック不要なマスをスキップ
あたりが何をやっているのか全く理解できませんでしたが、
とても読みやすいコードで大変助かりました。
理解できない部分をそのまま使うのもどうかと思うので、
これを参考にして自分なりに組ませていただきたいと思います。
ありがとうございました。



HIJIKI

リンク

2012/11/25(Sun) 22:12:04|NO.50878

>月1で来る人さん
返答ありがとうございます。
これは想像もしていない回答でした!

「敵へのアングル上に障害物が存在するか」
を調べるのではなく、
「敵へのアングル上の"障害物の距離"に障害物が存在するか」
を調べればよいということですね。

C/C++は最近始めたばかりで、
プラグインを組むのは現状難しいので、
hspで出来ることならhspでやってしまいたいというのが本音です。

大変助かりました。ありがとうございました。



HIJIKI

リンク

2012/11/25(Sun) 22:15:13|NO.50879

>暇人さん
返答ありがとうございます。
こんな考え方もあるのだなと驚かされてしまいました。
計算式が自分から見ると高度で、読むのに少し時間がかかりそうですが、
これはかなり高速化が期待できそうです。
とても参考になりました。ありがとうございます。

---

ここまでで出ている回答で、私の要求は満たされているはずなので、
あとは読み返して理解し、自分なりに組んでいきたいと思います。
ここまで回答頂いた方、ありがとうございました。
これで解決とさせて頂きます。



月1で来る人

リンク

2012/11/27(Tue) 01:49:56|NO.50906

月2で来ました。
以前に作成したモジュールをうpしておきます。自分でもどのような処理をしていたか忘れました。
ただし、以下の処理よりも No.50858 で示した処理の方が速いと思います。

#module /* | 【概要】 | 直線上に円状の障害物が存在するか調べる. | 【引数】 | HitLine array lp, int bx, int by, int R | lp : 直線の始点と終点が代入された配列変数 | 始点(lp.0, lp.1), 終点(lp.2, lp.3) | bx, by : 障害物の座標 | R : 障害物の半径 | 【戻り値】 | 直線上に障害物が存在したら 1 を返し, そうでないなら 0 を返す. */ #defcfunc HitLine array lp, double bx, double by, int R // 障害物と直線の始点との残差を求める x1 = bx - lp(0) y1 = by - lp(1) // 障害物と直線の終点との残差を求める x2 = bx - lp(2) y2 = by - lp(3) // 直線の始点と終点との残差を求める x3 = lp(2) - lp(0) y3 = lp(3) - lp(1) // 障害物と重なっていいるか a = x2*x2 + y2*y2 R2 = R * R if( a < R2 ) { return 1 } b = x3*by-y3*bx + lp(0)*lp(3)-lp(1)*lp(2) c = x3*x3 + y3*y3 // 直線付近に障害物が存在するか if( b*b < R2*c ) { // 2点間に障害物が存在するか if( (x1*x1+y1*y1)<c && a<c ) { return 1 } } return 0 #global R = 30 ; 障害物の半径 obx = 320 ; 障害物の x 座標 oby = 240 ; 障害物の y 座標 ddim linepos, 4 linepos(0) = 320.0, 240.0 ; 直線の原点 *main linepos(2) = double(mousex), double(mousey) ; 直線の終点 if( HitLine(linepos, obx, oby, R) == 0 ) { a = atan( linepos(3)-linepos(1), linepos(2)-linepos(0) ) linepos(0) += 4.0*cos(a) linepos(1) += 4.0*sin(a) } redraw 0 color 255, 255, 255 : boxf color circle obx-R, oby-R, obx+R, oby+R line linepos(0), linepos(1), linepos(2), linepos(3) redraw 1 await 10 goto *main



暇人

リンク

2012/11/27(Tue) 02:32:42|NO.50908

pre/preを忘れてたので再掲載・・・

NO.50876に特には問題見つからなかったけど
処理のやり方や順序とか、無くても良い変数が気になったので修正

*__hit memset line_col,0,LineMax*4 repeat LineMax if map_data(line_x1(cnt)/TileSize, line_y1(cnt)/TileSize) = 1 {//開始地点の判定 ;ヒットしている line_col(cnt) = 255 }else{ x1 = double(line_x1(cnt)) y1 = double(line_y1(cnt)) VectorX=(double(line_x2(cnt))-x1) VectorY=(double(line_y2(cnt))-y1) Distance=sqrt(VectorX*VectorX+VectorY*VectorY) if Distance {//Distance=0だったら距離が0なので判定しない vx=VectorX/Distance //Xの速度 vy=VectorY/Distance //Yの速度 ZeroF=1//斜めに進んでるフラグ(0なら縦か横どりらかに直進) if VectorX{ if VectorX<0{//左側に進んでる line_EndX=double((line_x2(cnt)/TileSize)*TileSize-TileSize) //Xの最終地点(グリッドの座標) line_NextX=double((line_x1(cnt)/TileSize)*TileSize)//Xの次に通過するグリッドライン TileSizeX=-TileSize }else{//右側に進んでる line_EndX=double((line_x2(cnt)/TileSize)*TileSize+TileSize*2) line_NextX=double((line_x1(cnt)/TileSize)*TileSize+TileSize) TileSizeX=TileSize } }else{ ZeroF=0 PassTimeX=99999999999.999 //PassTimeYより大きくなるように適当な数値 } if VectorY { if VectorY<0{//上側に進んでる line_EndY=double((line_y2(cnt)/TileSize)*TileSize-TileSize) line_NextY=double((line_y1(cnt)/TileSize)*TileSize) TileSizeY=-TileSize }else{//下側に進んでる line_EndY=double((line_y2(cnt)/TileSize)*TileSize+TileSize*2) line_NextY=double((line_y1(cnt)/TileSize)*TileSize+TileSize) TileSizeY=TileSize } }else{ ZeroF=0 PassTimeY=99999999999.999 //PassTimeXより大きくなるように適当な数値 } _cnt=cnt repeat RangeX=line_NextX-x1 //次のグリッドラインまでの距離 RangeY=line_NextY-y1 if ZeroF {//フラグ1なので斜めに進んでる PassTimeX=(RangeX/vx) //グリッドラインまでの通過カウント(少ないほど早い) PassTimeY=(RangeY/vy) }else{//縦横どちらかに進んでる if VectorX {//横に進んでるのでPassTimeXだけ設定 PassTimeX=(RangeX/vx) }else{//縦に進んでるのでPassTimeYだけ設定 PassTimeY=(RangeY/vy) } } if (PassTimeX < PassTimeY) {//縦ライン(X方向)の方を先に通過する x1=line_NextX //今回使ったグリッドラインを現在のX座標に line_NextX+TileSizeX //次回グリッドライン座標を設定 if line_NextX = line_EndX {break} //次のグリッドラインが最終グリッドラインに到達してたら判定終了 y1+=PassTimeX*vy //Xがグリッドラインに到達した時間でYが進めた距離を加算 x=(int(x1))/TileSize xx=(int(x1)-1)/TileSize //グリッドの縦横ライン交差部分用の対策 y=(int(y1))/TileSize if map_data(x, y) = 1 or map_data(xx, y) = 1{ ;ヒットしている line_col(_cnt) = 255 break } if (line_NextY=y1) {//グリッドの交差部分用の対策(無くてもいけるかもしれない) line_NextY+TileSizeY } }else{//横ライン(Y方向)の方を先に通過する(同時でもこちら) y1=line_NextY line_NextY+TileSizeY if line_NextY = line_EndY {break} x1+=PassTimeY*vx x=(int(x1))/TileSize y=(int(y1))/TileSize yy=(int(y1)-1)/TileSize if map_data(x, y) = 1 or map_data(x, yy) = 1{ ;ヒットしている line_col(_cnt) = 255 break } if (line_NextX=x1) {//グリッドの交差部分用の対策(無いと同じグリッドを2回判定してしまう) line_NextX+TileSizeX } } loop }//距離が0なら判定しない }//開始地点の判定でヒット loop return
NO.50876のより1割りぐらい軽くなってるかも・・・
距離の長い判定が少ないと1割も変わらないけど・・・



HIJIKI

リンク

2012/11/28(Wed) 10:17:35|NO.50933

解決としたのにわざわざ投稿していただき有り難うございます。
今まで投稿頂いたスクリプトの理解精一杯で、まだそちらに手をつけられていませんが、
お礼だけ言いたくてコメントさせていただきました。
ありがとうございます。



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