第一章 操作感No.004
角の補正
Corner Correction
概要
ジャンプしたキャラクターの頭が天井の角に、足が段の角にわずかにかかったとき、止めずにかかった分だけ横か上にずらして通す補正。補正がないと、体のほとんどが穴の下にあっても頭の端が角にかかっただけで落ちる。補正する幅を広げすぎると、天井や段の角をすり抜けたように見える。
使われる場面
- 天井の穴を下から跳んで抜ける場面
- 穴の真下に立ったつもりでも、体の端が穴の縁の下に少し残っていることがある。補正があれば、頭が縁の角にかかっても横にずらして穴を通す。
- 足場や段に跳び乗る場面
- 跳ぶのが少し早いと、足が段の上面に届く前に段の側面に当たる。補正があれば、足が角にかかった分だけ上に押し上げて段に乗せる。
- 天井の低い所で跳びながら進む場面
- 頭上に足場やブロックが並んでいると、跳ぶたびに頭がその角の近くを通る。補正があれば、角にかすっても止まらずにすき間から上へ抜けられる。
- 低い段差が続く階段や坂
- 足元の角の補正を地上でも効かせると、補正の幅より低い段差は跳ばずに歩いて登れる。段差ごとに足が引っかかって止まることがなくなる。
判断基準
| こういうとき | こうする |
|---|---|
| 天井の穴の真下で跳んだのに、頭が穴の縁にぶつかって抜けられない | 頭上の角の補正を入れる。補正の幅はキャラクターの幅の 2 割前後から試し、半分より広くしない。 |
| 段に跳び乗ろうとすると、足が段の角に引っかかって落ちる | 足元の角の補正を入れる。足が段の上面より少し下で側面に当たったら、はみ出した高さだけ上に押し上げる。押し上げる高さの上限は頭上の角と同じ幅から試す。 |
| 補正を入れたら、天井や段の角をすり抜けたように見える | 補正の幅が広すぎる。キャラクターの幅の半分より狭くする。半分を超えると、体の中心が天井の下にあっても穴へずらされる。 |
| 穴から離れる向きに進みながら跳んだのに、穴の上へ吸い込まれる | 横の入力がずらす向きと逆のときは補正しない。入力がないときと、入力がずらす向きと同じときだけ補正する。 |
| 補正でずらした先で壁や別の足場にめり込む | ずらす前に、ずらした先でどの足場とも重ならないかを確かめる。重なるなら補正せず、そのまま頭をぶつけさせる。 |
| 低い段差に当たるたびに足が止まり、跳ばないと越えられない | 足元の角の補正を地上でも効かせる。段差を跳んで越えることを遊びに含めるなら、空中だけで効かせる。 |
遊んでこう感じたら
指示の例
天井の穴の真下で跳んでも、頭が穴の縁に引っかかって抜けられないことがある。角の補正を入れて、頭が天井の角にかかった幅がキャラクターの幅の 2 割以内なら横にずらして穴を通して
段に跳び乗るとき、足が段の角にかすっただけで乗れずに落ちる。足元にも角の補正を入れて、足が段の上面より 4 ピクセル以内の高さで側面に当たったら上に押し上げて乗せて
角の補正が強すぎて、天井の角をすり抜けたように見える。補正の幅を今の半分くらいに狭めて、キャラクターの幅の半分を超えないようにして
左へ進みながら跳んだのに、右の穴の上へ吸い込まれることがある。角の補正は横の入力がずらす向きと逆のときは効かないようにして
詳細
角にかかっただけで止まる理由
デモのキャラクターは足場とぶつかる判定を体と同じ大きさの四角で持ち、天井や足場に重なったら押し戻す。この作りでは四角の端が天井にわずかに重なっただけでも頭をぶつけたことになる。デモの 1 回目では体の幅 18 ピクセルのうち 15 ピクセルが穴の下にあり、残りの 3 ピクセルだけが穴の縁の下にある。画面では穴のほぼ真下から跳んだように見えるが、補正のない上の段は頭の端が縁の角にかかって落ちる。
段に跳び乗るときも同じことが起きる。足が段の上面より 3 ピクセル低いまま段の側面に当たると、上の段は側面で止まって床まで落ちる。
そこで、頭や足が角にわずかにかかったときは、止めずにかかった分だけずらして通す。この補正を角の補正と呼ぶ。頭が天井の角にかかったら横に、足が段の角にかかったら上にずらす。デモの下の段は、どちらの場面でも 1 回目に 3 ピクセルずらして角を越える。
補正の手順
頭上の角の補正は上に動いていて天井にめり込んだときに試す。天井と重なった横幅(角にかかった幅)が補正の幅以内なら、その幅だけ横にずらす。上向きの速さは残したまま進ませる。補正の幅を超えていれば、ずらさずに頭をぶつけさせる。
足元の角の補正は空中で横に動いて段の側面にめり込んだときに試す。足が段の上面より下にはみ出した高さが補正の幅以内なら、その高さだけ上に押し上げて段に乗せる。
// 縦に動かした後。上に動いていて、天井にめり込んでいたら
if (velocityY < 0 && overlapsCeiling(body)) {
const shift = shiftPastCorner(body); // 天井の角の外まで横にずらす量(左右のうち短いほう)
const ok =
Math.abs(shift) <= cornerWidth &&
inputX * shift >= 0 && // 横の入力がずらす向きと逆ではない
!overlapsAny(body.x + shift, body.y); // ずらした先でどこにもめり込まない
if (ok) {
body.x += shift; // 上向きの速さはそのまま残す
} else {
body.y = ceilingBottom; // 頭をぶつける
velocityY = 0;
}
}
// 横に動かした後。空中で、段の側面にめり込んでいたら
if (!grounded && overlapsWall(body)) {
const rise = body.y + body.height - wallTop; // 足が段の上面より下にはみ出した高さ
if (rise > 0 && rise <= cornerWidth && !overlapsAny(body.x, body.y - rise)) {
body.y -= rise; // 段の上面まで押し上げる
} else {
pushBackFromWall(body); // 側面まで押し戻す
}
}
補正の幅の目安
穴の幅を G、体の幅を W とすると、補正なしで真上に跳んで抜けられる立ち位置の範囲は G − W である。補正の幅を c にすると穴の左右の縁でそれぞれ c ずつ広がり、範囲は G − W + 2c になる。デモでは穴の幅が 24 ピクセル、体の幅が 18 ピクセルである。補正なしで抜けられる範囲は 6 ピクセルで、補正の幅を 4 ピクセルにすると 14 ピクセルに広がる。デモのキャラクターは走ると 1 フレームに 2.5 ピクセル進むので、止まれる位置もこの刻みになる。左から歩いてきて止まり真上に跳ぶと、補正なしで穴を抜けられる止まり方は 2 通りしかない。補正の幅を 4 ピクセルにすると 6 通りになる。
補正の幅を体の幅の半分にすると、抜けられる範囲は G − W + W = G で穴の幅と同じになる。このときは体の中心が穴の下にあれば抜けられる。半分より広くすると、体の中心が天井の下にあっても穴へずらされる。体の大半が天井の下から上へ抜けるので、天井をすり抜けたように見える。デモのスライダーの上限は体の幅の半分の 9 ピクセルにしている。
1 フレームでずらす距離も見え方に効く。補正の幅を 8 ピクセルにして 2 回目を見ると、走る 3 フレーム分を超える距離を 1 フレームで横に動く。体が横に飛び移ったように見える。
目安として、キャラクターの幅の 2 割前後から試し、半分より狭い範囲で調整する。デモの既定の 4 ピクセルは体の幅の 22% にあたる。足場とぶつかる判定が絵と違う大きさの作りでは、判定の幅を基準にする。
足元の角の補正は、跳ぶのが早すぎたときの猶予として働く。デモの段の場面の 2 回目は 1 回目より 2 フレーム早く跳ぶので、足は段の上面より 7.3 ピクセル下で側面に当たる。補正の幅が 4 ピクセルでは乗れず、8 ピクセル以上にすると乗れる。補正の幅を 4 ピクセルにすると、補正なしより 2 フレーム早く跳んでも乗れる。9 ピクセルなら 4 フレーム早く跳んでも乗れる。
補正を効かせる条件
頭上の角の補正では、横の入力がずらす向きと逆のときは補正しない。左へ進みながら跳んだのに右の穴へずらされると、行きたくない方へ吸い込まれる。入力がないときは、左右のどちらにずらしてもよい。
ずらした先で別の足場や壁にめり込まないかも確かめる。穴が体より狭いときはどちらにずらしても反対側の縁にかかるので、補正せずに頭をぶつけさせる。
足元の角の補正を地上でも効かせると、補正の幅より低い段差は跳ばずに歩いて登れる。段差を跳んで越えることを遊びに含めるなら、空中だけで効かせる。デモの足元の角の補正は空中だけで効かせている。
当たり判定やコヨーテタイムとの違い
角の補正も「当たり判定」を小さくする手も「コヨーテタイム」も、プレイヤーのわずかなずれを許す仕組みである。違うのは、どのずれを許すかである。
当たり判定を絵より小さくする手が許すのは、敵の弾や攻撃とのずれである。足場とぶつかる判定は絵の大きさのまま残すので、天井や段の角にかかるのは防げない。足場とぶつかる判定まで細くすれば角にかかりにくくなるが、壁に寄ったときに絵が壁にめり込んで見える。角の補正なら、足場とぶつかる判定は絵の大きさのまま角にかかったときだけずらせる。
コヨーテタイムが許すのはジャンプを押す時機のずれで、角の補正が許すのは跳んだ後の位置のずれである。空中で向きを変えられる度合い(「空中制御」)が小さいほど跳んだ後に位置を直せないので、角の補正が効いてくる。