ぴったり半分カットは、左右に動く包丁の線をタップで止めて、食べ物をちょうど半分に切るゲームです。このゲームを作ると、なめらかなアニメーションの作り方や、「切った位置」を%に変えて採点するしくみが身につきます。
まずは包丁の線を食べ物の上で左右に往復させます。なめらかに動かすにはrequestAnimationFrameを使います。行って戻ってをくり返す動き(三角波)は、時間から計算で作れます。
function sweep(now) {
var t = (now - startTime) / 1000; // 経過秒
var phase = (t * freq) % 1; // 0〜1をくり返す
var tri = phase < 0.5 ? phase * 2 : 2 - phase * 2; // 0→1→0
var p = 0.03 + tri * 0.94; // 端は避けて 3%〜97%
line.style.left = (objLeft + p * objW) + 'px';
requestAnimationFrame(sweep); // 次のコマへ
}
requestAnimationFrame(sweep);
freq(1秒あたりの往復回数)を大きくすると速くなります。お題が進むほどfreqを上げれば、だんだん難しくできます。%(あまり)を使って0〜1をくり返させ、それを折り返して三角波にするのがポイントです。
タップされたら線を止め、その位置が食べ物の左から何%かを計算します。食べ物の左端の位置(objLeft)と幅(objW)が分かっていれば、引き算と割り算だけで求められます。
function doCut() {
sweeping = false; // アニメを止める
var lineX = parseFloat(line.style.left);
var leftPct = (lineX - objLeft) / objW * 100; // 左から何%か
var dev = Math.abs(leftPct - 50); // 50%からのズレ
deviations.push(dev);
// 切り口を表示(CSS変数に渡す)
object.style.setProperty('--cut', leftPct + '%');
object.classList.add('sliced');
}
「ちょうど半分」は50%なので、leftPctが50からどれだけ離れているか(dev)が成績になります。計算した割合をCSSの変数--cutに渡すと、切れた場所に線を出すといった見た目の演出もかんたんに作れます。
このゲームは全5品の平均ズレで勝負します。各お題のズレを配列にためておき、最後にその平均を出します。平均が小さい(=いつも真ん中で切れている)ほど上位です。
function finishGame() {
var sum = deviations.reduce((a, b) => a + b, 0);
var avg = sum / deviations.length; // 平均ズレ(%)
var score = Math.round(avg * 10); // 1/10%単位の整数で保存
// 小さいほど上位なので、ランキングは asc(昇順)で登録
Leaderboard.show('perfect-cut', score, { order: 'asc', format: 'percent-diff' });
}
スコアを1/10%単位の整数(例: 2.3% → 23)で保存しているのは、ランキングのデータベースが整数を扱うためです。表示するときに10で割って「±2.3%」に戻します。タイムを競うゲームと同じで、小さいほど良いので昇順(asc)で順位を決めます。
おつかれさまでした!requestAnimationFrameでのアニメーション、位置を%に直す計算、複数回の平均で採点という3つでぴったり半分カットの仕組みが分かりましたね。発展として、食べ物の種類を増やしたり、速さの上がり方を変えたり、切ったあとに2つに分かれて落ちる演出を足したりしてみましょう。
A: はい、大丈夫です。アニメーションは少し難しく感じるかもしれませんが、ステップごとに進めれば完成できます。わからないところは、ひなテックの教室で質問もできますよ。
A: 基本部分は約30分〜1時間で作れます。食べ物や難易度を調整したり演出を足すと、さらに楽しく発展させられます。