アクションゲームの当たり判定について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
オーカー

アクションゲームの当たり判定について

#1

投稿記事 by オーカー » 9年前

初めまして
最近アクションゲームにも手を出してみようと思い少しずつ作っていたのですが
マップとキャラの当たり判定がうまくいきません。

自分は二次元配列にデータを格納し、
自機の座標をマップチップの大きさで割ることでどの配列を参照すればいいかを求め、
四隅(左の当たり判定を知りたいときは左上、左下を調べる)がマップのオブジェクトとぶつかっているかどうかを知り、
もしぶつかっているならぶつからない位置まで戻すという手法をとっています。

しかしこの方法ですと衝突したとき、例えば落下中に左下の点がどこかに衝突したとき
「左に衝突した」という条件と「下に衝突した」という条件両方が成立するためキャラは右と上に動かされてしまいます。
本当ならブロックの上に乗るわけですから右には動かなくて良いんですけど・・・

どうすればいいんでしょうか?

本当はそのぶぶんのソースも貼ろうかと思ったんですが自分はVBで作っているのでここは少しちがうかなあと思いまして・・・
(でも理論自体は同じだから質問してもいいかなあと)

アバター
パコネコ
記事: 139
登録日時: 9年前
住所: 大阪

Re: アクションゲームの当たり判定について

#2

投稿記事 by パコネコ » 9年前

自分が落下中かどうかであたり判定を切り替えるのが、簡単かもしれません。
ですが、私の場合移動させるものをわける方法を使ってました。

コード:

y+=y_speed;
x+=x_speed;
if(check(x,y)){
     /*ブロックに上とか横に移動*/
}
おそらくこんな感じに書いてると思います。

y座標の移動後にあたり判定チェック。
あたっていれば上に乗るもしくは頭を打ちます。
x座標の移動後にあたり判定をチェック。
あたっていればぶつからない位置まで移動します。
簡単に書くと

コード:

y+=y_speed;
if(check(x,y)){
     /*ブロックの上に移動*/
}
x+=x_speed;
if(check(x,y)){
     /*ブロックの横に移動*/
}
簡単にいえばこんな感じです。

===
checkを書き換えました。
*注意*
check(x,y)はあたり判定を確認する関数です。
ニャン!!\(゜ロ\)(/ロ゜)/

アバター
GRAM
記事: 164
登録日時: 9年前
住所: 大阪

Re: アクションゲームの当たり判定について

#3

投稿記事 by GRAM » 9年前

やりたいこととロジックが対応していない気がします。

実際問題として「もしぶつかっているならぶつからない位置まで戻す」という事が正確に実現できているなら当たり判定の不自然さは解消されるのではないかと。
つまるところ現在の「戻す先」の決定を「現在の4隅の座標のみ」にゆだねていることが問題かと
実際の例を図示しますが、おっしゃったような例によらず戻すべき方向は「現在の速度」に完全に依存するでしょう。
(図だと、現在のフレームで青い位置にいるキャラクターはその時の速度によってオレンジ、緑、茶の方向へそれぞれ戻すのが自然)

かといって速度方向にオブジェクトを戻していく実装は多少なりめんどくさいので、例えば戻す方向を8方向にするなどはいかがでしょうか?
つまり落下時にはxの移動量がyの移動量よりも十分小さい時には単純にy方向へ、そうでないときにはx方向にも戻すなどが考えられると思います

例えば図のように赤い境界で区切り、速度がオレンジの時には上へ、速度が青い時には上へ1、左へ1戻すなどというような感じです。
添付ファイル
ex.png
ex.png (10.2 KiB) 閲覧数: 1780 回
ex2.png
ex2.png (3.51 KiB) 閲覧数: 1780 回

ISLe
記事: 2645
登録日時: 9年前
連絡を取る:

Re: アクションゲームの当たり判定について

#4

投稿記事 by ISLe » 9年前

パコネコさんのおっしゃるようにY座標の補正をしたらX座標は補正しない(補正後にめり込んでも次のフレームに回す)ようにすれば良いと思います。
ただ、見るからに横からぶつかったのにぴょこんと上に乗ってしまうと不自然なので、前回の座標と比較して縦に引っ掛かったか横に引っ掛かったかを区別してY座標補正をスキップさせてください。

下から当たったときに下に戻すようにすると少しでも壁や床に触れると跳び上がる勢いが無くなります。
壁に沿って跳び上がって乗り越えたり高い位置の床に跳び乗ったりすることがとても難しくなります。
摩擦で跳べない仕様だと主張しても良いですけど不評を買うでしょう。

Y→Xと補正処理を分けると壁にぶつかった段階で横移動しなくなっても勢いはそのまま最高到達点まで跳び上がるようにできます。

閉鎖

“C言語何でも質問掲示板” へ戻る