Snake Time 02
Snake Time 02
window.requestAnimationFrame()
関数を理解しよう No.1
window.requestAnimationFrame()
関数は渡された関数をブラウザの表示を邪魔しないタイミングで処理されるようにする関数。
animation(time)
という仮の関数を定義し、window.requestAnimationFrame()
関数に渡してみよう。
その時、注意が必要なのがtime
という渡される関数のパラメーター。これはwindow.requestAnimationFrame()
関数が実行されたからのミリ秒の値が渡される。
このパラメーターを使って色々なアニメーションの制御ができる。
*ログにミリ秒が表示されれば成功
// 仮に関数
// timeというパラメーターが大事
// ここにアニメーションが始まってからのミリ秒が記録される
function animation(time) {
console.log(time)
}
// animation関数を渡し、実行してもらおう
window.requestAnimationFrame(animation)
window.requestAnimationFrame()
関数を理解しよう No.2
window.requestAnimationFrame()
関数に渡す仮の関数をアロー関数にし、すっきりさせよう。
*前のステップと挙動は変わらない
// 仮関数を消し、アロー関数に変換
window.requestAnimationFrame((time) => {
console.log(time)
})
window.requestAnimationFrame()
関数を繰り返し実行しよう
main()
関数の中にmain()
関数を呼び出し、永遠に呼び続けられるようにしよう。関数の中に同じ関数を呼び出すことを recursion という。
*ミリ秒が増加しているのがログで表示されれば成功
function main(currentTime) {
// main()のなかにmain()を呼ぶことで、永遠に呼び続ける
// これをrecursionという
window.requestAnimationFrame((time) => {
main(time)
})
console.log(currentTime)
}
// 関数を呼び出す
main()
snakes
を動かそう
update()
関数とdraw()
関数を使い、snakes
を動かそう
update()
関数の中にdirection
変数を設定
direction
は snake が動く次の座標への動きを示すベクトル。{ x: 0, y: -1 }
はx
(横)には動かず、y
(縦)には 1 ずつ進むということ。つまり上に動くということ。
newPoint
でsnakes
に足す新しい座標を作成する。snakes[0]
とは蛇の頭を指す。そのx
とy
の座標にdirection
ベクトルを足し、新しい座標を計算する。
snakes.unshift()
でsnakes
配列の頭にnewPoint
を付け足し、snakes.pop()
でsnakes
配列の最後を消す。これによって蛇が動いているように見せる。
main()
関数のif (secondsSinceLastRender < snakeSpeed) return
の後にupdate()
関数とdraw()
関数を呼び出す。
drawGrid()
関数の中にctx.clearRect(0, 0, canvas.width, canvas.height)
を付け足す。これをしなければ、ループごとにグリッドを描画してしまい、グリッドの灰色がどんどん濃くなっていってしまうため。
*snakes
が上に向かって進んでいけば成功
function drawGrid() {
// 画面をクリアする
ctx.clearRect(0, 0, canvas.width, canvas.height)
// (省略…)
}
function main(currentTime) {
// main()のなかにmain()を呼ぶことで、永遠に呼び続ける
// これをrecursionという
window.requestAnimationFrame((time) => {
main(time)
})
// secondsSinceLastRenderは
// main関数が受け取ったcurrentTime変数から
// lastRenderTimeを引き
// 1000で割った数値(ミリ秒から秒に変更するため)
const secondsSinceLastRender = (currentTime - lastRenderTime) / 1000
// もしsecondsSinceLastRenderが(SNAKE_SPEED)より小さい時は
// update関数、draw関数を実行しない
// つまり以下を実行せず、ここでストップ
if (secondsSinceLastRender < snakeSpeed) return
update()
draw()
lastRenderTime = currentTime
console.log(currentTime)
}
function update() {
const direction = { x: 0, y: -1 }
// 新しい座標をsnakes[0]から計算する
const newX = snakes[0].x + direction.x
const newY = snakes[0].y + direction.y
const newPoint = {
x: newX,
y: newY,
}
// snakes配列の頭にnewPointを追加
snakes.unshift(newPoint)
// snakes配列の一番最後を消す
snakes.pop()
}
function draw() {
drawGrid()
drawSnake()
drawFood()
}
main()