forgive complete noobness here new js. i've created simple canvas 1 rectangle being controlled keydownevents , 1 moving around canvas in raf.
i want have if moving ball hits users rectangle collide , bounce bounce @ right angle hits not in reverse have tried , failed at.
i know need calculate hits on users rect, have no idea start or how can point me in right direction or give me small snippet of do?
i'll leave out keycode functions space they're not needed.
function init() { canvas = document.getelementbyid("canvasdemo"); ctx = canvas.getcontext("2d"); canvaswidth = canvas.width; canvasheight = canvas.height; drawsquare(); } function drawsquare() { ctx.clearrect(0, 0, canvaswidth, canvasheight); // user controlled square ctx.fillstyle = "blue"; ctx.fillrect(rect.x, rect.y, rect.w, rect.h); requestanimationframe(drawsquare); if (rect.x + rect.vx > canvaswidth - 20 || rect.x + rect.vx < 0) rect.vx = -rect.vx; if (rect.y + rect.vy > canvasheight - 20 || rect.y + rect.vy < 0) rect.vy = -rect.vy; rect.x += rect.vx; rect.y += rect.vy; // moving square 1 (left-right): requestanimationframe(squaretwo); if (dir1 == "right") { if (xpos < canvaswidth - 35) { xpos += 2; }else{ dir1 = "left"; } } if (dir1 == "left") { if (xpos>0) { xpos -= 2; }else{ dir1 = "right"; } } } // second square function squaretwo() { ctx.fillstyle = "black"; ctx.fillrect(xpos, ypos, 35, 35); ctx.fill(); }
to calculate reflection can -
first, define normal vector based on pads angle:
function getnormal(a) { return { x: math.sin(a), // 90° offset y: -math.cos(a) // incoming angle } }
then use dot-product calculate incident angle incoming vector:
function reflect(n, v) { var d = 2 * dot(v, n); // calc dot product x 2 v.x -= d * n.x; // update vectors reflected v.y -= d * n.y; // normal using product d return v } // helper, calc dot product 2 vectors function dot(v1, v2) { return v1.x * v2.x + v1.y * v2.y }
then need hit-test trigger reflection. when hit, reflect incoming vector on normal 90° tangent pad.
a demo/fiddle shows in use ("proof-of-concept") can found here.