開始する
タイプ3:ビットマスク
これはタイル(スムーズ)メソッドに似ていますが、大きなタイルを使用する代わりに、画像を使用して各ピクセルの衝突をチェックします。 これにより、ゲームをよりうまく動作させることができますが、複雑さを大幅に増加させ、より多くのメモリを使用し、レベルを作成するためにグラフィカルエディターに似たものを必要とします。 通常、このようなマスクは視覚化に直接使用されないため、追加のツールが必要です。たとえば、各レベルに個別に大きなグラフィックイメージ(素材)が必要です。 このような問題があるため、この手法の使用は非常にまれですが、タイルに基づくオプションよりも優れた結果を達成できます。 この方法は、動的な環境を作成するのに便利です。破壊をビットマスクで単純に「ペイント」してレベルを変更できます。 良い例は、ワームゲームです。
破壊的な地形を持つワーム世界党
例:ワーム、タルボットのオデッセイ
仕組み
基本的な考え方は、タイル(スムーズ)アルゴリズムに非常に近い-各ピクセルがタイルであると判断し、まったく同じアルゴリズムを実装します。 すべてが1つの小さな例外で機能します-バイアス。 勾配は2つの最も近いタイルの位置の相対性によって完全に決定されるため、以前の手法は機能せず、代わりにはるかに複雑なアルゴリズムを使用する必要があります。 階段のような他の要素もトリッキーになります。
バイアス
タルボットのオデッセイ、ゲームの上に衝突マスクがオーバーレイされています。
バイアスは、この実装を正しく行うことが非常に難しい主な理由です。 残念ながら、バイアスなしでこの実装を使用しても意味がないため、通常はバインディングです。 レベルジオメトリをスムーズに変更することが、このシステムを使用せざるを得ない主な理由です。
TalbotのOdysseyが使用する粗いアルゴリズムは次のとおりです。
- 加速度と移動方向を組み合わせて、位置変更ベクトル(各軸に沿って移動する量)を計算します
- 各軸を個別に処理し、最大の差がある軸から始めます。
- 水平方向の動きについては、プレイヤーが斜面を登れるように、プレイヤーのAABB長方形を3ピクセル上に移動します。
- すべての障害物とビットマスク自体を確認してさらにスキャンし、障害物と衝突する前に移動できるピクセル数を決定します。 新しいポジションを掘ります。
- 水平方向の動きである場合、斜面を登るのに必要なだけピクセルを上に移動します(一般に、3を超えないようにします)。
- 動きの終わりにキャラクターのピクセルが障害物と交差する場合、この軸に沿った動きを取り除きます。
- 最後の条件の結果に従って、他の軸についても同じことを行います。
このシステムには動きに違いはないため、キャラクターが下に移動したり倒れたりするため、キャラクターが床に触れていないフレームの数をカウントして、ジャンプしてアニメーションを変更できるかどうかを判断する必要があります。 Talbotゲームでは、この値は10フレームです。
ここでのもう1つのトリックは、何と衝突する前にシフトできるピクセル数を効率的に計算することです。 片側のプラットフォーム(タイルアプローチとまったく同じように動作する)や、プレイヤーが滑り落ちるが登ることができない急な勾配など、他の複雑な要因が発生する可能性があります(非常に複雑で、この記事の範囲外です) 。 一般に、この手法では大量の値を微調整する必要があり、実際にはグリッドを使用したタイルアプローチよりも安定性が低くなります。 非常に詳細な領域が必要な場合にのみお勧めします。
タイプ4:ベクトル
この手法では、ベクターデータ(ラインまたはポリゴン)を使用して、衝突ゾーンの面を決定します。 正しい開発は非常に困難ですが、Box2Dなどの物理エンジンが豊富であるため、この手法の実装に適しているため、より一般的になっています。 ビットマスクの技術のすべての魅力を提供しますが、膨大なメモリのオーバーロードがなく、まったく異なるレベルの編集方法を使用します。
ブレード(レベルエディター)、可視レイヤー(上)および衝突ポリゴン(下)
例:三つ編み、リンボ
仕組み
以下に2つの基本的な実装アプローチを示します。
- ビットマスクに似ていますが、オブジェクトとモーションの交差を計算するためにポリゴンを使用して、モーションと衝突を自分で処理します。
- 物理エンジン(例:Box2D)を使用する
明らかに、2番目のオプションははるかに人気があります(Braidの作成者が最初の方法を選んだと思いますが)-それははるかに単純で、ゲーム内の物理学で他の多くの興味深いことを行うことができます。 しかし、私の意見では、この方法を使用する場合は非常に注意する必要があります。なぜなら、ゲームをあまりにも普通で面白くない物理プラットフォーマーにすることができるからです(このエンジンでのゲームの動作の類似性。
複雑なオブジェクト
このアプローチには独自の問題もあります。 たとえば、プレイヤーが床の上に立っているか(丸め誤差のため)、壁に寄りかかっているか、下り坂を滑っているのかを判断するのが難しい場合があります。 物理的なエンジンを使用する場合、摩擦は大きな問題になる可能性があります。摩擦は床では大きく、タイルの側面では小さくする必要があるためです。
彼らはこれをさまざまな方法で解決しますが、最も一般的な解決策は、キャラクターをいくつかの異なるポリゴンに分割することです。それぞれが異なる役割を持ちます:これは、本体の外観(オプション)、次に脚用の細い長方形、側面用の2つの細い長方形、および頭部用の別の長方形です。 障害物に引っかかることのないように狭められていることもあります。 それらは異なる物理設定を使用することができ、衝突に対する応答反応(コールバック)はキャラクターの状態を決定するのに役立ちます。 詳細については、センサーが使用されます(交差しないことを確認するために使用される非衝突オブジェクト)。 基本的なケースには、キャラクターがジャンプするのに床に十分に近いか、壁を押すかなどの決定が含まれます。
主な考慮事項
選択した移動のタイプに応じて(おそらく、タイプ番号1を除く)、いくつかの考慮事項を作成できます。
加速
スーパーマリオワールド(低加速)、スーパーメトロイド(中加速)、メガマン7(高加速)
プラットフォーマーの感触に影響を与える要因の1つは、キャラクターの加速です。 加速は速度変化の尺度です。 低い場合、キャラクターは最大速度に達するまでに時間がかかるか、プレーヤーがコントローラーを離すと停止します。 正しく実装されていないと、キャラクターが「つるつるした」感じになり、適切なコントロールができなくなります。 この動きは、しばしばスーパーマリオのゲームに関連付けられています。 加速が大きい場合、キャラクターはゼロから最大速度まで、またはその逆に加速するのにほとんど時間を必要としません(またはまったく必要としません)。これにより、Mega Manシリーズで見られるように、非常に迅速な応答、「けいれん」制御が発生します(Mega Manフルスピードで停止するため、実際には無限の加速が適用されます)。
ゲームに水平面での加速の概念がない場合でも、ほとんどの場合、円弧でのジャンプにそれを使用します。 それ以外の場合、ジャンプの形状は三角形になります。
仕組み
加速は実際には非常に簡単ですが、いくつかの落とし穴があります。
- xTargetSpeedを定義します。 プレーヤーがコントロールに触れない場合は0、左を押す場合は-maxSpeed、右を押す場合は+ maxSpeedである必要があります。
- yTargetSpeedを定義します。 プレーヤーがプラットフォームに立っている場合は0、そうでない場合は+ terminalSpeedになります。
- 各軸について、加重平均または増分加速度を使用して、目標速度の方向に現在の速度を上げます。
2つの加速方法:
- 加重平均:加速は、0(変化しない)から1(瞬間的な加速)までの数字(「a」)です。 ターゲットと現在の速度の間の線形補間にこの値を使用し、結果を現在の速度として設定します。
vector2f curSpeed = a * targetSpeed + (1-a) * curSpeed; if (fabs(curSpeed.x) < threshold) curSpeed.x = 0; if (fabs(curSpeed.y) < threshold) curSpeed.y = 0;
- 追加の加速:加速を追加する方向を決定し(0より大きい数に1を返し、0より小さい数に-1を返す関数を使用)、それらが逃したかどうかを確認します。
vector2f direction = vector2f(sign(targetSpeed.x - curSpeed.x), sign(targetSpeed.y - curSpeed.y)); curSpeed += acceleration * direction; if (sign(targetSpeed.x - curSpeed.x) != direction.x) curSpeed.x = targetSpeed.x; if (sign(targetSpeed.y - curSpeed.y) != direction.y) curSpeed.y = targetSpeed.y;
キャラクターを移動する前に速度に加速を追加することが重要です。そうしないと、コントロールで1フレームの遅延(ラグ)が発生します。
キャラクターが障害物に衝突した場合、この軸に沿って速度をリセットすることをお勧めしますが、これでは不十分な場合があります。 速度はオブジェクトまでの距離よりも大きい場合があります。 いくつかの実装では、高速での衝突の結果として、キャラクターが障害物を貫通できます。 この場合、補正値(交差の深さ)を見つけてキャラクターをこの値に移動するか、交差する前にフレームごとに別の速度を見つける必要があります。 (約あたり)
ジャンプ制御
スーパーメトロイド、サムスが「スペースジャンプ」を実行(「ネジ攻撃」ボーナス付き)
ゲームでのジャンプは、プレイヤーが地面にいるかどうかを確認するのと同じくらい簡単です(最後のnフレームで地面にいる場合はより頻繁に)、もしそうなら、y軸に沿って負の開始速度(物理的には運動量)を与えます。 そして、重力に任せてください。
プレーヤーがジャンプを制御できる4つのオプションを次に示します。
- インパルス:スーパーマリオワールドやソニックザヘッジホッグなどのゲームで見ることができます。 ジャンプは、キャラクターがジャンプする前に持っていた慣性を(速度に関して)保持します。 一部のゲームでは、これが実際のジャンプアークに影響を与える唯一のオプションです。 ここでは何もすることがありません。それを止めるために何かをするまではそうなります。
- 空中の加速:つまり、空中にいるときに水平方向の動きを制御できます。 物理的に不可能であるにもかかわらず、これはキャラクターをより扱いやすくするので、非常に人気のある機能です。 プリンスオブペルシャに類似したゲームを除き、ほぼすべてのプラットフォーマーにこの機能があります。 基本的に、空気中で得られる加速度は大幅に減少するため、運動量は依然として重要です。 ただし、一部のゲーム(Mega Manなど)では、空中で完全に制御できます。
- リフトコントロール:物理的に不可能な別のアクションですが、キャラクターをさらにコントロールできるため、人気があります。 ジャンプボタンを長く押すほど、キャラクターが高く飛びます。 これは通常、ボタンが押されている間、重力を抑制するか、キャラクターに勢いを追加し続けます(ただし、追加された勢いを減らします)。 キャラクターが際限なくジャンプできるようにしたくない場合、アクションには制限時間があります。 この実装は、ジェットパックの非常に短い作業として想像できます-より長く遅延し、より高く飛行しました(約Per。)。
- 複数のジャンプ:既に空中で、一部のゲームではプレイヤーが再びジャンプできる場合があります(スーパーメトロイドのスペースジャンプやタルボットのオデッセイでの飛行など)、または地面に触れる前の限られた数のジャンプ(「ダブルジャンプ」が最も一般的な選択です)。 これはカウンターを維持することで達成できます。カウンターはジャンプごとに増加し、地上では減少します(この値を更新するように注意してください。そうでない場合は、最初のジャンプの直後にリセットできます)。カウンターの値が小さい場合はさらにジャンプできます。 時々、2番目のジャンプは最初のジャンプよりも短いか、登山時にのみ機能します。落下し始めた場合、2番目のジャンプを行うことはできません。 他の制限を有効にすることができます-スペースジャンプは、既にスピンジャンプを行っており、落下し始めた場合にのみ機能します。
アニメーション
ブラックソーン、キャラクターは発射する前に長いアニメーションを実行します
多くのゲームでは、キャラクターは実際にアクションを実行する前にアニメーションを再生します。 ただし、けいれん的なアクションゲームでは、これはプレーヤーを混乱させます。「DO N'T DO IT!」スムーズにするために、ジャンプと実行のためにプロアクティブなアニメーションが必要ですが、ゲームの反応に注意する必要があります。 そのようなアニメーションは純粋に装飾的なものにでき、アクション自体はすぐに解決できます。