静止した円を上方に整列させ、下方からの動く円がぶつかったら消える
動く円は反射ベクトルに従って跳ね返る
簡易なブロック崩しがもうすぐできそうです。
const NUM_BLOCKS = 8; const BLOCK_ROW = 4; const BLOCK_RADIUS = 20; const MOVING_RADIUS = 10; let blocks =[]; let movingBall; function setup() { createCanvas(400, 400); noStroke(); //オブジェクトリテラルで静止円の属性を定義し //配列に入れる for (let i = 0; i < NUM_BLOCKS; i++) { const x = (width / (BLOCK_ROW + 1)) * ((i % BLOCK_ROW) + 1); const y = i < BLOCK_ROW ? 80 : 160; blocks.push({ pos: createVector(x, y), r: BLOCK_RADIUS, visible: true, }) } //同じく動く円を定義 movingBall = { pos:createVector(width / 2, 350), r:MOVING_RADIUS, velocity: createVector(5, 3), }; } function draw() { background(220); //静止円を描く fill(100, 200, 250); for (const block of blocks) { if (block.visible) { circle(block.pos.x, block.pos.y, block.r * 2); } } //動く円を描画 fill(250, 100, 100); circle(movingBall.pos.x, movingBall.pos.y, movingBall.r * 2); //位置の更新 movingBall.pos.add(movingBall.velocity); //壁との反射 if (movingBall.pos.x < movingBall.r || movingBall.pos.x > width - movingBall.r) { movingBall.velocity.x *= -1; } if (movingBall.pos.y < movingBall.r || movingBall.pos.y > height - movingBall.r) { movingBall.velocity.y *= -1; } for (const block of blocks) { if (!block.visible) continue; //衝突の検出 //現在の中心間の距離を求める const distance = p5.Vector.dist(movingBall.pos, block.pos); if (distance < movingBall.r + block.r) { //衝突したとき block.visible = false; //反射ベクトルを求める //法線ベクトル //normalize()でベクトルの長さを1として方向成分のみとする const normalV = p5.Vector.sub(movingBall.pos, block.pos).normalize(); //VとNの内積(スカラー値) const dotM = movingBall.velocity.dot(normalV); //ベクトルの反射計算 //R = V - 2 (V・N) N //反射ベクトルreflecV const reflecV = p5.Vector.sub( movingBall.velocity, p5.Vector.mult(normalV, 2 * dotM) ); //新しい速度 movingBall.velocity = reflecV; } } }