第一章 操作感No.002
加速と減速
Acceleration and Deceleration別名 加減速、慣性、走り出しと止まり方
概要
キャラクターが走り出してから最高速に達するまでと、入力をやめてから止まるまでの速さの変わり方。加速に時間をかけると走り出しがもっさりし、減速に時間をかけると止まりたい位置を行き過ぎて滑る。短くすれば思いどおりに動かしやすくなり、長くすれば重さや勢いが出る。
使われる場面
- 狭い足場に乗る場面
- 止まる位置がずれると足場から落ちる。減速を短くして、離した位置の近くで止まれるようにする。
- 弾や敵の攻撃をよける場面
- 押してすぐに動き出せず、すぐに向きを変えられないと、見えている攻撃もよけられない。加速と切り返しの減速を短くして、入力にすぐ応えるようにする。
- 重い乗り物や大きなキャラクター
- 加速と減速に時間をかけて、動き出しにくく止まりにくい重さを見せる。そのぶん、狭い場所で細かく動かす場面は減らす。
- 氷の床や滑る床
- その床の上だけ減速を長くして、止まりにくい床を仕掛けにする。普通の床では止まれる位置で止まれなくなるので、足場の置き方もそれに合わせる。
判断基準
| こういうとき | こうする |
|---|---|
| 走り出しがもっさりしている、という感想が出る | 最高速までの時間を短くする。機敏に動かしたいゲームでは、0〜0.1 秒(毎秒 60 回の更新で 0〜6 フレーム)から試す。 |
| 止まりたいところで止まれずに滑る、という感想が出る | 止まるまでの時間を短くする。止まる位置が遊びに直結するゲームでは、加速より減速を短くし、0〜0.1 秒から試す。 |
| 反対向きに押しても、しばらく元の向きへ進んでから向きが変わる | 切り返しのときの減速を、離したときの減速と別の値にして短くする。止まり方のなめらかさを残したまま、向きだけをすぐ変えられる。 |
| 最高速を上げたら、止まるまでに滑る距離が伸びた | 止まるまでに進む距離は最高速と止まるまでの時間の積に比例する。最高速を 2 倍にしたら、止まるまでの時間を半分にすると距離が元に戻る。 |
| 動きが機械的で、キャラクターに重さや勢いを感じない | 加速と減速を少し足す。0.1〜0.2 秒ほどから試し、狭い足場で止まれなくなるほど長くしない。重い乗り物などは 0.2〜0.5 秒まで延ばす。 |
| 小刻みに押して位置を合わせようとしても、思った量だけ動かない | 加速が長いと、短い押しではほとんど動かない。最高速までの時間を短くするか、押し始めから最高速の何割かの速さで動き出す作りにする。 |
遊んでこう感じたら
指示の例
走り出しがもっさりしている。加速を速くして、最高速に達するまでの時間を今の半分くらいにして
止まりたいところで止まれずに滑る。減速を強くして、ボタンを離してから 0.05 秒くらいで止まるようにして
左右に切り返すと、しばらく元の向きに滑ってから向きが変わる。反対向きに押したときの減速だけを強くして、すぐに向きが変わるようにして
動きが機械的で重さを感じない。加速と減速をどちらも 0.15 秒くらいにして、動き出しと止まり方に少し勢いを付けて
氷の床の上でも普通の床と同じようにすぐ止まれてしまう。氷の床の上だけ減速を弱くして、止まるまでに 0.5 秒くらいかかるようにして
詳細
速さを少しずつ変える作り
左右の入力でキャラクターを動かすとき、いちばん単純な作りは押しているあいだは最高速で動かし、離したら止めるものである。この作りでは押した瞬間に最高速になり、離した瞬間に止まる。これに対して、速さを 1 ステップごとに少しずつ目標の速さへ近づけると、走り出しにも止まるまでにも時間がかかる。走り出しで速さを上げていくことを加速、止まるときに速さを下げていくことを減速と呼ぶ。減速が長く止まりにくい動きは「慣性が強い」とも言う。
調整する値は最高速、止まった状態から最高速に達するまでの時間、最高速から止まるまでの時間の三つである。時間の代わりに 1 秒あたりに変える速さの量(加速度)で指定する作りもある。加速度は最高速を時間で割れば求まる。押している向きの最高速か、離していれば 0 を目標の速さにして、1 ステップごとに一定の量ずつ近づける。1 ステップで変える量は最高速 ÷ 時間 × 1 ステップの秒数である。
// current を target に向けて、最大 maxDelta だけ近づける
function approach(current: number, target: number, maxDelta: number) {
if (Math.abs(target - current) <= maxDelta) return target;
return current + Math.sign(target - current) * maxDelta;
}
// 1 ステップごとに。inputDir は入力の向き(-1、0、1)、dt は 1 ステップの秒数
const turning = velocity * inputDir < 0; // 動いている向きと反対に押している
const target = turning ? 0 : inputDir * maxSpeed; // 反対向きに押したときは、まず止まるまで減速する
const time = inputDir !== 0 && !turning ? accelTime : decelTime;
velocity = time > 0 ? approach(velocity, target, (maxSpeed / time) * dt) : target;
x += velocity * dt;
止まるまでに進む距離
一定の割合で減速すると、速さは最高速から 0 まで一直線に下がるので、止まるまでの平均の速さは最高速の半分になる。そのため、止まるまでに進む距離は最高速 × 止まるまでの時間 ÷ 2 になる。デモの最高速は 1 秒に体の幅 10 個分である。止まるまでの時間を 0.3 秒にすると、離した位置から体の幅 1.5 個分滑る。
走り出しも同じ形で、最高速に達するまでの平均の速さは最高速の半分になる。そのため、最高速に達した後は、加減速なしに比べて最高速 × 最高速までの時間 ÷ 2 だけ後ろを走る。加速と減速が同じ長さなら、最高速に達するまで押し続けたときに止まる位置は加減速なしと変わらない。走り出しで遅れた分を止まるまでに滑る分で取り戻すからである。デモの最初の場面で既定の設定のまま二つの段が同じ位置に止まるのはこのためである。違いは着くまでの時間と、離してから滑る動きに出る。
この式から、最高速を上げると、止まるまでの時間が同じでも滑る距離が伸びる。最高速を 2 倍にしたら、止まるまでの時間を半分にすると滑る距離が元に戻る。行き過ぎを体の幅の半分以下に抑えるには、止まるまでの時間を最高速で体の幅 1 個分を進む時間以下にする。デモではこの時間が 0.1 秒である。
長さの目安
機敏に動かしたいアクションでは、加速と減速をどちらも 0〜0.1 秒(毎秒 60 回の更新で 0〜6 フレーム)から試す。重さや勢いを見せたいキャラクターや乗り物では、0.2〜0.5 秒ほどに延ばす。0 にすると思いどおりに動かせるが、動きが機械的に見えることがある。長くするほど重さは出るが、押してから思った所へ着くまで待たされる。
止まる位置が遊びに直結するゲームでは、加速より減速を短くする。走り出しの遅れは着くのが少し遅れるだけで済むが、止まる位置のずれは足場から落ちるなどの失敗に直接つながるからである。空中では地上と別の値を使い、空中でどこまで向きを変えられるかは「空中制御」として決める。
切り返しの減速
動いている向きと反対に押して向きを変える操作を切り返しと呼ぶ。上のコードでは切り返しのときも止まるまでは減速し、止まってから反対向きに加速する。デモもこの作りで、下の段で向きが変わるまでの時間は止まるまでの時間と同じになる。止まるまでの時間を長くすると、反対に押しても元の向きへ滑り続けるので、攻撃をよけようとしても間に合わないことがある。反対向きに押したときの減速にも加速の時間を使う作りもある。その場合は加速を長くしたときに同じことが起きる。
そこで、切り返しのときだけ使う減速を別に持ち、離したときの減速より短くするゲームもある。離したときの止まり方はなめらかなまま、向きだけをすぐに変えられる。
短く押したときに動く量
加速に時間がかかると、短く押しただけでは最高速に届かない。押した時間が最高速までの時間より短いとき、押してから止まるまでに進む距離は押した時間の 2 乗に比例する。押す時間を半分にすると、進む距離は 4 分の 1 になる。デモの下の段の既定の設定(加速と減速がどちらも 0.3 秒)では、0.1 秒の押しで進む距離は加減速なしの 3 分の 1 になる。
このため、小刻みに押して位置を合わせようとしても、思った量だけ動かない。減速も長いと、押すたびに離した後も滑るので、止まるのを待ってからでないと次の押し方を決められない。細かい位置合わせが要るゲームでは、最高速までの時間を短くするか、押し始めから最高速の何割かの速さで動き出す作りにする。
似た感じを生むほかの設定
加速が長いと、押しても目に見えて動き出すまでに時間がかかる。「入力遅延」と同じように、押したのに反応しない感じになる。入力遅延は押してから動き始めるまでの遅れで、加速は動き始めてから速くなるまでの遅れなので、直す場所が違う。
カメラが遅れてキャラクターを追う作りだと、キャラクターが止まった後も画面が動き続けるので、実際より滑っているように見える。止まり方を調整するときは、カメラの追い方(「カメラのデッドゾーン」など)による見え方と分けて確かめる。