JS ゲーム製作 p5.js 複数円の衝突を関数化する - 円を増やす準備
何をするか
p5.js
前回の記事で 2円の衝突判定の実装をやったが、関数化はされていなかったので、 ゲームを作るために必要な関数化を行う。
そのために以下の処理を行う
2円のオブジェクト化
円の描画
テキストの描画
2円のオブジェクトからの距離の計算
2円のオブジェクトからの衝突の是非の計算
を関数化していく
円をオブジェクト化する
変数でのベタ書き
最初はこうしていた。
let x0 = 120; let y0 = 180; let r0 = 60; let x1 = mouseX; let y1 = mouseY; let r1 = 120;
固定座標の 円 0 と mouse の座標が同期される 円 1 の 座標と半径を変数で記述していた
オブジェクトにする
function draw() { const circleA = { x: 120, y: 180, r: 60, }; const circleB = { x: mouseX, y: mouseY, r: 120, } }
draw() の関数内にオブジェクトとして円を作る。
そうするとこれから書く距離の測定や衝突の判断に、円のオブジェクトを2つ指定するだけでよくなる。
なお draw() 関数外だと mouseX, mouseY が機能しない。
距離の取得
距離の取得の処理
let distance = sqrt( (x1-x0)**2 + (y1-y0)**2 ); let distanceComma2 = nfc(distance, 2); let distanceText = `Distance: ${distanceComma2}`;
まず、前回に2つの円から距離を取る処理を書いた
これを関数化する
距離の取得の関数化
function getDistance(circleObjectA, circleObjectB) { let x0 = circleObjectA.x; let y0 = circleObjectA.y; let x1 = circleObjectB.x; let y1 = circleObjectB.y; let distance = sqrt( (x1-x0)**2 + (y1-y0)**2 ); let distanceComma2 = nfc(distance, 2); let distanceText = `Distance: ${distanceComma2}`; return distanceText; }
これで 2円から距離を返す関数ができた。使ってみる
const distanceOf0and1 = getDistance(circleA, circleB); console.log(distanceOf0and1); sketch.js:8 Distance: 246.45
ちゃんと計算されているのが確認できた。
円の表示
circle(x0, y0, 2*r0) circle(x1, y1, 2*r1)
これで描画していたのを、円をオブジェクト化したので
function drawCircle(circleObject){ circle(circleObject.x, circleObject.y, 2*circleObject.r) } drawCircle(circleA) drawCircle(circleB)
こうなる
テキストの表示
関数化する前
strokeWeight(1); stroke(0); textSize(32); text(distanceText, 3, 420);
その度にスタイルを記述した後に text() で書いてた
関数化する
スタイルを固定化して関数化する。
function displayText(message,fromLeft,fromTop){ strokeWeight(1); stroke(0); textSize(32); text(message, fromLeft, fromTop); }
先ほど getDistance() で取得したテキストを使って
displayText(distanceOf0and1, 3, 420)
ちゃんと表示された。
衝突
ここまでで 円のオブジェクト化と描画系と距離の計算まで関数化したので
ようやく衝突処理もオブジェクト化できる
関数化する前
let isHit = distanceOf0and1 < r0 + r1;
衝突判定は2つの円の距離より各円の半径の和が小さいかどうかで判定する。これを関数化したい
関数化後
function isHit(circleA, circleB) { let distance = getDistance(circleA, circleB); let isHit = distance < circleA.r + circleB.r; return isHit } isHit(circleA, circleB)
これで円を増やしても実装できる!
実際に動いているコードはこちら
ブランチはこちら。Pull Request あったらください