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


HSPTV!掲示板


未解決 解決 停止 削除要請

2008
0810
ぴよきちあたり判定12未解決


ぴよきち

リンク

2008/8/10(Sun) 15:34:59|NO.18036

皆さんはゲームのあたり判定をどのようにしていますか?
私のやり方はとてもここにのせられるようなやり方ではなく、
ごちゃごちゃしているので簡単なやり方を教えてください。



この記事に返信する


Elfizm

リンク

2008/8/10(Sun) 15:50:33|NO.18038

どのような当たり判定を行いたいのか、によって変わります。
ゲームのジャンルによって当たり判定のアルゴリズムも違いますから、
まずはジャンルや、当たり判定のターゲットを絞るとよいです。

また、ごちゃごちゃしているとしても、回答のヒントにはなりますから
ぴよきちさんの行ったあたり判定のスクリプトを一部示していただけるとうれしいです。



ぴよきち

リンク

2008/8/10(Sun) 16:11:14|NO.18039

私は今までシューティングゲームのあたり判定しか作ったことがなく、
いまつくっいる物は横スクロールゲームで、
配置したとげに当たってはいけないというようなあたり判定が作りたかったのですが、
シューティングゲームの判定を応用しようとして失敗してしまったのでうまく行く方法を教えてください。



K

リンク

2008/8/10(Sun) 16:35:25|NO.18041

(ax1,ay1)を自キャラの左上、(ax2,ay2)を自キャラの右下
(bx1,by1)をトゲの左上、(bx2,by2)をトゲの右下
の座標として、


if ax1>bx2 & ax2<bx1 & ay1>by2 & ay2<by1{ ;当たった }

こんなもんでしょうか?

ソースを示していただけると質問の意味がより分かりやすくなると思います。



K

リンク

2008/8/10(Sun) 16:37:43|NO.18042

すみません。
逆でした。

if ax1<bx2 & ax2>bx1 & ay1<by2 & ay2>by1{ ;当たった }
です。



さとう

リンク

2008/8/10(Sun) 16:56:23|NO.18043

とげの形や大きさ、どのくらいの判定精度を
要求するかにもよりますが私は
座標判定
距離判定
色判定の3つの方法を多用してます
座標判定では一番単純で4つの方向から、あたっているかどうかを絞り込みます
例えば
とげのx座標が300以上340以内かつy座標が220以上260以内
ならあたっていると認識するようなアルゴリズムです
しかし精度を要求する場合や斜めに長いオブジェクトの判
定には向きません
次に距離判定ですが、これはオブジェクトから自分までの距離を計算し
その値がいくつ以内だったら当たっていると認識する方法です
距離はピタゴラスの定理ででます
最後に色判定ですがこれは条件がかぎられます
例えば背景が青でとげが赤なら、今自分の立っている座標
の色をpgetで読み出しそれが赤なら当たっていると考える方法です
しかし刺の色や背景の色もまさか1色ではないでしょうから
使用用途は白黒ゲームなどに限られます

ちなみに私は距離判定と座標判定を組み合せて使ってます



名無し

リンク

2008/8/10(Sun) 17:10:17|NO.18045

マップデータをどのようにしてますか?
文字列型1次元配列に突っ込んでるとか2次元整数型に入れてるとか全部スプライトだとか…
ソースがあると分かりやすいかと



ぴよきち

リンク

2008/8/10(Sun) 17:36:43|NO.18046

ようするに、他力本願ながら横スクロールゲームを作るために
配置するだけでそこに当たり判定ができるようにしたいのですが
やったことがないからわからないので教えてほしいのです・・・
あと、さとうさんのいっている
とげの先の位置をを計算したりする?ところまで精密じゃなくていいです。



てすと

リンク

2008/8/10(Sun) 18:29:52|NO.18047

自機かなんか知りませんが、プレイヤーの当たり判定が点なのでよければ
、なおかつとげが動かない(マップに固定されている)のであれば
単純にマップ座標を計算すればいいだけです。

いま自機がマップ番号何番にいるのかさえ計算すればいいだけです。
あとは、そのマップブロックの属性(0番なら空間、1番ならとげ、2番ならふつうの壁とか)
にしたがって処理を入れればよいかと。

プレイヤーの当たり判定を四角形にしたかったら、上の座標計算を4回(四角形の四隅)で計算すればいいだけです。




とげが動いているのであれば皆さんが出している普通の当たり判定(四角形)が一番処理が早いです。
あと、普通の四角形の当たり判定計算は、ifを入り弧にした方が早いときもあります。

横スクロールという事なので、最も成立しにくいY座標のifを最初にしておけば無駄な処理が
省けるかもしれません。



ash

リンク

2008/8/10(Sun) 18:47:49|NO.18049

>皆さんはゲームのあたり判定をどのようにしていますか?
>私のやり方はとてもここにのせられるようなやり方ではなく、
>ごちゃごちゃしているので簡単なやり方を教えてください。
単純なものなら、私は、以下の4つの方法を使う.

\喫形の当たり判定

emx = ginfo_winx >> 1 emy = ginfo_winy >> 1 s = 20 *main boxf emx-s, emy-s, emx+s, emy+s if( (emx-mousex)/s==0 && (emy-mousey)/s==0 ) { dialog "hit" } await 10 goto *main
円のあたり判定

emx = ginfo_winx >> 1 emy = ginfo_winy >> 1 r = 20 *main circle emx-r, emy-r, emx+r, emy+r x = emx - mousex y = emy - mousey if( (x*x + y*y) < r*r ) { dialog "hit" } await 10 goto *main
四角形の当たり判定

bsx = 128 ; ブロックの幅 bsy = 64 ; ブロックの高さ bxc = 2 byc = 3 *main x = bsx*bxc y = bsy*byc boxf x, y, x+bsx, y+bsy ;title ""+mousex/bsx+" "+mousey/bsy if( mousex/bsx==bxc && mousey/bsy==byc ) { dialog "hit" } await 10 goto *main
たГ播たり判定

boxf 280, 200, 360, 280 *main pget mousex, mousey if( (ginfo_r | ginfo_g | ginfo_r) == 0 ) { ; 黒 dialog "hit" } await 10 goto *main



ash

リンク

2008/8/10(Sun) 22:55:13|NO.18050

NO.18049の記事:
い諒法で
if( (ginfo_r | ginfo_g | ginfo_r) == 0 ) {	; 黒

if( (ginfo_r | ginfo_g | ginfo_b) == 0 ) {	; 黒
でした.ginfo_b が ginfo_r になっていたので、あしからず.


それから、何かの役に立つと思い、直線上に円状の障害物があるか調べる関数を作ってみた.

#module #defcfunc HitLine array lp, double bx, double by, int R /* | 【概要】 | 直線上に円状の障害物があるか調べる. | 【引数】 | HitLine array lp, int bx, int by, int R | lp : 直線の座標が代入された配列変数 | 始点(lp.0, lp.1), 終点(lp.2, lp.3) | bx, by : 障害物の座標 | R : 障害物の半径 | 【戻り値】 | 直線上に障害物があったら 1 返し, そうでないなら 0 を返す. */ 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 if( a < R*R ) { return 1 } b = x3*by-y3*bx+lp(0)*lp(3)-lp(1)*lp(2) c = x3*x3 + y3*y3 if( c ) { // 直線付近に障害物があるか if( b*b/c < R*R ) { // 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



GENKI

リンク

2008/8/10(Sun) 23:54:41|NO.18051

この辺の記事なんか参考にならないでしょうか。
http://hspdev-wiki.net/?%BE%D7%C6%CD%C8%BD%C4%EA
http://hspdev-wiki.net/?%C5%F6%A4%BF%A4%EA%C8%BD%C4%EA%A5%E2%A5%B8%A5%E5%A1%BC%A5%EB

他に横スクロール型ゲームやアクションゲーム、RPGなどの記事あたりが参考になりそうな気がします。



ash

リンク

2008/8/11(Mon) 19:51:36|NO.18057

ネット上に参考になりそうな文献があったのであげ
http://hikari-hinomoto.hp.infoseek.co.jp/PDF/DX7A02.pdf

正方形同士の当たり判定なら、NO.18049の,諒法で
 tekix : 敵の座標X
 tekiy : 敵の座標Y
 s : 敵のサイズ+見方のサイズ
 if ((tekix-mousex)/s | (tekiy-mousey)/s) == 0
とすると、HSPでは速く判定でる.
tekix = ginfo_winx >> 1		; 敵の座標
tekiy = ginfo_winy >> 1 ; tekis = 20 ; 敵のサイズ mikatas = 30 ; 見方のサイズ s = tekis + mikatas *main if( ((tekix-mousex)/s | (tekiy-mousey)/s) == 0 ) { dialog "hit" } redraw 0 color 255, 255, 255 : boxf : color boxf tekix-tekis, tekiy-tekis, tekix+tekis, tekiy+tekis boxf mousex-mikatas, mousey-mikatas, mousex+mikatas, mousey+mikatas redraw await 10 goto *main

それから、何かの役に立つと思い、矩形と点の当たり判断をする関数を作ってみた.
/*
|【ある点が矩形上にあるか調べる】 | onsquare array rect_x, array rect_y, int mx, int my | rect_x : 矩形の頂点が代入された配列変数 (X 座標) | rect_y : 矩形の頂点が代入された配列変数 (Y 座標) | 配列は、左上(0),右上(1),右下(2),左下(3)の順番 | mx : 調べる点 (X 座標) | my : 調べる点 (Y 座標) |【戻り値】 | 0 : (mx, my)が矩形上にない | 1 : (mx, my)が矩形上にある */ #module #defcfunc onsquare array rect_x, array rect_y, int mx, int my x1 = mx - rect_x(0) y2 = my - rect_y(3) x2 = rect_x(3) - mx y1 = rect_y(0) - my flg = 1 repeat 2, 1 a = rect_x(cnt) - rect_x(0) b = rect_y(cnt) - rect_y(0) // 線分と線分の重なりを調べる if( (a*y1+b*x1 ^ a*y2+b*x2) >> 31 ) { flg-- break } loop return flg #global
サンプル:
	CX = ginfo_winx >> 1	; 中心
CY = ginfo_winy >> 1 ; PI = 3.1415926535897932384627 bsx = 300 ; 矩形の幅 bsy = 150 ; 矩形の高さ ang = 0.0 x = -bsx/2, bsx/2, -bsx/2, bsx/2 y = -bsy/2, -bsy/2, bsy/2, bsy/2 *main ang += 0.005 // 矩形:4つの頂点の座標を代入する repeat 4 rect_x(cnt) = CX + cos(ang)*x(cnt) - sin(ang)*y(cnt) rect_y(cnt) = CY + cos(ang)*y(cnt) + sin(ang)*x(cnt) loop // ヒットチェック if( onsquare(rect_x, rect_y, mousex, mousey) ) { title "hit" } else : title "" redraw 0 color 255, 255, 255 : boxf color grect CX, CY, ang, bsx, bsy redraw await 10 goto *main

矩形と点の当たり判断をするアルゴリズムは次のよう.
 矩形を構成する線分の対象性を利用し
  (mx, my) : マウスの座標
  (gx, gy) : 矩形の重心
  (sx, sy) : (gx, gy) を中点とした (mx, my) の対称点
 として、矩形上の線分が(sx, sy)、(mx, my)内にあるか調べる.
 これは2本の線分について調べるだけでよい.
これを解いて、式変形をしていくとかなり簡略化できる.



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