ボールを壁で弾ませる
これはゲーム開発Canvasチュートリアルの10ステップのうち3番目のステップです。このレッスンを終えたあとの完成予想のソースコードはGamedev-Canvas-workshop/lesson3.htmlで入手できます。
ボールが動くのを見られたのは良いことですが、画面からすぐ消えてしまっては面白くないじゃありませんか! これを解決するためにとても簡単な衝突検知 (後ほど詳しく説明します) を導入し、Canvasの四辺でボールを弾ませます。
簡単な衝突検知
衝突を検知するためにボールが壁に触っている (衝突している) か確かめ、もし触っている場合には動く方向をそれに従って変更します。
計算を簡単にするために、描画される円の半径をもつballRadius
という変数を定義しましょう。次のコードを既にどこかにある変数定義の後に追記しましょう。
var ballRadius = 10;
あわせてdrawBall()
関数内のボールを描画している行も次のように更新しましょう。
ctx.arc(x, y, ballRadius, 0, Math.PI*2);
上端と下端で弾ませる
ボールを弾ませる壁は4つあります。まずは上端に注目しましょう。毎フレーム、ボールがCanvasの上端に触っているかどうか確認する必要があります。もし触っているなら、ボールの動きを反転させ、ボールが反対方向に動き、視界の範囲内に留まるようにしましす。座標系は左上端から始まることを思い出しながら考えてみれば、次のようなコードが思いつくでしょう。
if(y + dy < 0) {
dy = -dy;
}
もしボールの位置のy
の値が0未満だったら、符号反転させた値を設定することでy軸方向の動きの向きを変えます。もしボールが上に向かって毎フレーム2ピクセルの速さで動いていたら、今度は「上」に向かって毎フレーム-2ピクセルの速さで動く、つまり下に向かって毎フレーム2ピクセルの速さで動きます。
上記のコードは上端でボールを弾ませていました。では今度は下端について考えてみましょう。
if(y + dy > canvas.height) {
dy = -dy;
}
y
座標がCanvasの高さより高かったら(左上端からy
の値を数えているため、上端は0で始まり下端はCanvasの高さである480ピクセルとなることを思い出してください) 、先程のようにy
軸方向の動きを反転させます。
これら2つの文を合わせればコードの冗長さを減らせます。
if(y + dy > canvas.height || y + dy < 0) {
dy = -dy;
}
2つの文のどちらかがtrue
だったら、ボールの動きを反転させます。
左端と右端で弾ませる
上端と下端を対処したところで、左端と右端を考えてみましょう。実のところとても良く似ていて、y
をx
で置き換えて文を繰り返すだけでよいのです。
if(x + dx > canvas.width || x + dx < 0) {
dx = -dx;
}
if(y + dy > canvas.height || y + dy < 0) {
dy = -dy;
}
ここで上記のコードをdraw()関数の、ちょうど閉じ波括弧の前に挿入しておいてください。
まだボールが壁に隠れる!
ここであなたのコードを試してみましょう。驚くはずです。Canvasの四辺全てでボールが弾んでいます! でも別の問題がありました。ボールが壁にぶつかるとき、位置を変える少し前に壁に沈んでしまいます。
壁と円周の衝突地点を計算すべきところで、壁と円の中心の衝突地点を計算しているのがこの理由です。ボールは壁に触ったときに弾むべきで、壁に半分のめり込んだときに弾んでも仕方ありません。そこで円周を含めるために文を少し調節します。最後に追加したコードを次のように書き換えます。
if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
dx = -dx;
}
if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) {
dy = -dy;
}
ボールの中心と辺の距離がボールの半径とちょうど等しくなったときに動く向きを変えます。半径を辺の長さから引き、もう一方では足すことで衝突検知が正しく行われたような印象が出ます。思ったとおり、壁にぶつかった時点でボールが弾むようになります。
自分のコードと比べる
もう一度、このパートを終えた後にできたコードと比べてみて、それからコードで遊んでみてください。
練習: 壁に当たるたびにボールの色をランダムに変えてみてください。
次のステップ
ボールが動き、かつゲームボードに留まるようになることまでこぎつけました。第4章では操作できるパドルを実装してみます。 パドルとキーボード操作を見てみましょう。