プラットフォーマーゲームでスイングを簡単に実装するにはどうすればよいですか?


9

プレイヤーがロープを使ってスイングできるゲームを開発していて(スパイダーマンやバイオニックコマンドーのように)、この動作の実装に問題があります。誰かが私にこれを行う方法を手伝ってくれる?物理学の公式などを意味します。これまで、私は3つのアイデアを考え出しました。1つは春を使用していますが、それは多くの時間を消費し、時々びくびくしています。他の2つは次のステップを計算しようとしています(1つはポテンシャルエネルギーの計算によるもので、もう1つはトルクの計算によるものです)。両方とも、俳優がスイングしようとするたびにほとんどクラッシュします。

トルクを計算するために私が書いたコードは次のとおりです。

float dx = Runner->getPosition().x - ancher.x; 
float dy = Runner->getPosition().y - ancher.y;
float t0 = atan2(dy,dx); //my current angle
float k = ((dy) *vx - (dx) * vy) / (dx * dx+dy * dy); //previus angular velocity
k -= gravity * cos(t0) *dt; // new angular velocity (gravity is positive)
t0 += k * dt - acc * cos(t0) *dt * dt / 2; // rotate the rope
float dx1 = r0 * cos(t0); // new position (r0 is rope length)
float dy1 = r0 * sin(t0);
vx = (dx1 - dx) / dt; //calculate velocity
vy = (dy1 - dy) / dt;

関連
事項

@JonathanHobbsその質問の答えは、1つの例外を除いてロープを実装しようとする方法です。私の場合、衝突は望ましくないので、ロープの各部分をセンサーとして設定し、互いに引っかかることなく自由に移動できるようにします。
Ali1S232 2011

ロープ用の単純な振り子+ロープっぽく見えるアニメーションについてはどうですか?私はBionic Commandoのような古いゲームに振り子以外のものがあるとは思いません。
user712092 2011年

振子のアイデアがうまく機能するはずの@ユーザー。しかし私の場合、プレイヤーの動きが速いか実装が悪いため、良い結果は得られませんでした。
Ali1S232 2010年

@Gajetは正しく理解できるまでデバッグ描画を試みますか?この振り子の線は、衝突を得るために十分に薄いBox2Dのボックスとして作成されている可能性があります(そして、物理学から除外して、手で動かしますか?)。
user712092 2011年

回答:


6

リジッドスイングが必要で、回転ポイントまでの距離が一定である場合は、キャラクターを回転ポイントを中心とする円上のポイントとして扱います。彼に(円に沿った)1次元の角速度を与えます。各フレームの角加速度はaccelerationDueToGravity * cos(angleOfPlayerOnCircle)(0度が右向き)でなければなりません。

ロープを長くしたり短くしたい場合は、上記のスキームを使用して、各フレームの半径を変えるだけです。


あなたの答えは私の2番目の試みでしたが、質問を編集してコードを追加するよりもはるかに高速で移動します。問題がどこにあるかを見つけることができます。
Ali1S232 2011年

3

多くの試みの後、私はbox2dを使いました。

このシミュレーションには一般的に2つのアプローチがあります。少なくとも2つ見つかりました。

  1. 1つは、いくつかの円形状を使用し、それらを離れた関節を使用して接続することです。
  2. もう1つはチェーン自体の長方形で、回転ジョイントを使用してそれらを接続します。

各シナリオでは、アンカー(私の場合は静的ボックス)が必要です。ロープパーツの重量を下げると(たとえば、円形または長方形のいずれかを使用して)、より現実的な物理学を実現するために密度を0.1に設定し、ロープの端に接続されたボックスには密度10を使用します。

ロープセグメントが互いにどのように反応するかについて心配する必要があるもう1つのこと。ロープがシーン内を自由に動くようにしたかったので、すべてのロープ固定具をセンサーとしてマークしました。異なるアプローチが必要な場合があります。

次に心配する必要があるのは、世界の更新にパスする反復の数です。ロープの低いセグメント(おそらく最大8)では、高い反復値を使用する必要はありません。十分ですが、たとえば30セグメントを試してセグメント数を増やした場合、反復の数が少ないと、ロープの長さが必要以上に長くなるように思われるため、これらの状況を解決するには、40/40反復する必要があります。

いくつかのテストの後、ボックス2dはオブジェクトサイズが0.1mから10mのシーン用に設計されているようで、大きなシーンに推奨される最大サイズは約50mx50mです。したがって、基本的には、これらのパラメーターに一致するようにオブジェクトを縮小する必要があります。私の場合、最初にピクセルの位置を直接box2dに渡そうとしましたが、速度が制限されているため、ワールドをできるだけ速く動かすことができなかったため、最良の結果を得るためにシーンを64倍にスケーリングする必要がありました。私自身はテストしていませんが、box2dにはいくつかの制限があるため、より大きなシーンを使用できません。たとえば、box2d設定を変更できるb2Setting.hファイルに定義された値があり#define b2_maxTranslation 2.0fますが、それはお勧めできません。


私が反対票を獲得するためにbox2dが間違っているのはなぜですか?
Ali1S232 2011

これは質問の答えにはなりません。少なくとも、Box2Dを使用してどのように機能させるを記述してください。
bummzack

@bummzack:わかりました、それを私の答えに追加します
Ali1S232

これを回答として受け入れた場合、質問に欠陥がある場合。セグメント化されたロープの物理学は、あなたが説明したものとは大きく異なります。
AttackingHobo

@attackingHobo:quesitonは当時は正しかったが、コードをbox2dに変換したところ、それほど労力をかけずにセグメント化されたロープの物理を実装できることがわかりました。そして、それはそれほど違いはありません、私の質問をセグメント化されたロープの1つのセグメントとして考えてください。そして私のほとんどすべての解決策は、box2dなしでサークルスタイルのロープを実装する方法でした。
Ali1S232 2011年

2

ロープが垂直線(中央)からどれだけ離れているかに基づいて、スイング動作の速度を遅くすることを検討しましたか?


3つのアプローチすべてについて、ロープの長さは、スイング速度を計算するために使用したパラメータの1つです。しかし、私はそれを正しく使用したことを保証できません。私はいくつかの物理的な計算を行い、その解決バージョンをゲームに適用しました。
Ali1S232 2011年

中心から離れるほど、ロープスイングの次の動きまでの遅延が長くなります。また、遅延のABSolute値に0.28のような値を掛けることもできます(これを試す必要があります)。
ランドルフリチャードソン

次のステップを計算しているとき、delta_timeに一定の値があり、持っているすべてのパラメーター(以前の速度、プレビューの位置、ロープの長さなど)を使用して計算しようとしています。新しい速度、次にこの速度にdelta_timeを掛けた値を最後の位置に追加して、新しい位置を生成します。他に何か意味がある場合は、回答に詳細を記入してください。
Ali1S232 2010年

1

プレーヤーがロープの長さよりも離れている場合、プレーヤーは、通過した距離に等しい力ですぐに押し戻されます。これは弾力性を感じることなく機能し、プレーヤーにとって直感的に感じるはずです。ただし、ゲームの最良の結果を得るには、物理​​を微調整する必要がある場合があります。

ロープが付いている時。maxLength値を保存します。

更新ごとに、とのdistance間を確認playerしますattachPoint

が通常distancemaxLength更新より少ない場合、ロープの影響はありません。

距離がより大きい場合はmaxLengthnormalからattachPointプレーヤーまでを検索します。間の差を取得distanceし、をmaxLength。追加playerVelocitynormal違いを掛けました。

疑似コード:

dx = (attachPoint.x - player.x)
dy = (attachPoint.y - player.y)

distance = sqrt(dx*dx+dy*dy);

if (distance > maxDistance)
{
    float dx1 = dx / distance * maxDistance;
    float dy1 = dy / distance * maxDistance;
    v.x += (dx1 - dx) / dt;
    v.y += (dy1 - dy) / dt;
}

playerVel += v * dt;

だから私があなたの答えに編集したコード(それについて申し訳ありませんが、それを追加するのに適した場所が見つからなかった)はあなたが提案しているものですか?
Ali1S232

私は編集を承認しました、そして、はい、それはそれであるはずだと思います。私は以前にロープ物理学を使用して同じことを行うためにはるかに複雑な方法を使用しましたが、そのため、このコードが適切に機能するかどうかは完全にはわかりませんが、そうであるはずです。そこへの道の%。
AttackingHobo

何回か試した後、私はこの問題のためにbox2dを試すつもりだと思います。ところで、あなたはとになるようにそのコードを変更する必要がdx = player.x - attachpoint.xありdy = player.y - attachpoint.yます。
Ali1S232 2011年

1

http://www.cocos2d-iphone.org/archives/1112を見ると、ロープの端に剛体が取り付けられたロープの実装があります。物理エンジンにはBox2Dを使用します。ソースコードを見れば、好きな言語で実装できると思います。

また、ロープの質問への上記のリンクは私のものであり、上記のこのデモ(リンク提供)は本当に役に立ちました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.