Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Boucing ball with collision in HTML5 Here\'s my code two two ball bouncing aroun

ID: 3809355 • Letter: B

Question

Boucing ball with collision in HTML5

Here's my code two two ball bouncing around inside a rectangle.

I couldn't figure out how to make make a collision when teo ball collide.

Please help me with the collision here.

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>HTML5 Bouncing Ball with collison</title>
<style type="text/css">
<!--
body { background-color:#ededed;
    font:normal 12px/18px Arial, Helvetica, sans-serif;
    position: center;
}

h1 { display:block;
    width:600px;
    margin:20px auto;
    padding-bottom:20px;
    font:normal 24px/30px Georgia, "Times New Roman", Times, serif;
    color:#333;
    text-shadow: 1px 2px 3px #ccc;
    border-bottom:1px solid #cbcbcb;
}

#container {
    width:600px;
    margin:0 auto;
}

#myCanvas {
    background:#fff;
    border:1px solid #cbcbcb;
}

-->
</style>

<script>  
var context;
var dx= 4;
var dy=4;
var y=150;
var x=10;

var dx2= 3;
var dy2=3;
var y2=200;
var x2=20;
function draw(){
    context= myCanvas.getContext('2d');

    //clear the previous circle before creating a new one
    context.clearRect(0,0,600,600);
    context.beginPath();
    context.fillStyle="#0000ff";
    context.arc(x,y,20,0,Math.PI*2,true);

    context.arc(x2,y2,20,0,Math.PI*2,true);
    context.closePath();
    context.fill();

    boundaryLogic();

}

function init(){
    context= myCanvas.getContext('2d');
    setInterval(draw,10);
}

function boundaryLogic()
{

    if( x<0 || x>600)
      dx=-dx;
    if( y<0 || y>600)
      dy=-dy;
    x+=dx;
    y+=dy;


    if( x2<0 || x2>600)
      dx2=-dx2;
    if( y<0 || y>600)
      dy2=-dy2;
    x2+=dx2;
    y2+=dy2;

}




</script>

</head>
<body>
<h1>Two bouncing balls with collision</h1>
<div id="container">

    <canvas id="myCanvas" width="600" height="600"></canvas>


</div>



<p class="home"><a href="https://thimbleprojects.org/dmai/213296"> <strong>Home>></strong></a></p>


</body></html>

Explanation / Answer

<html>
<head>
<title>Balls!</title>
<script type="text/javascript">
function ready() {
var Quadtree = function (lvl, coords) {
this.MAX_OBJECTS = 2;
this.MAX_LEVELS = 2;

this.level = lvl;
this.objects = [];
this.bounds = coords;
this.nodes = [];


this.clear = function () {
this.objects.length = 0;

for (var i = 0; i < this.nodes.length; i++) {
if (this.nodes[i] != null) {
this.nodes[i].clear();
this.nodes[i] = null;
}
}
}

this.split = function () {
var subWidth = Math.round(this.bounds.width / 2);
var subHeight = Math.round(this.bounds.height / 2);
var x = this.bounds.x;
var y = this.bounds.y;

this.nodes[0] = new Quadtree(this.level + 1, {
x: x + subWidth,
y: y,
width: subWidth,
height: subHeight
});
this.nodes[1] = new Quadtree(this.level + 1, {
x: x,
y: y,
width: subWidth,
height: subHeight
});
this.nodes[2] = new Quadtree(this.level + 1, {
x: x,
y: y + subHeight,
width: subWidth,
height: subHeight
});
this.nodes[3] = new Quadtree(this.level + 1, {
x: x + subWidth,
y: y + subHeight,
width: subWidth,
height: subHeight
});
}

this.getIndex = function (coord) {
var index = -1;
var horizontalMidpoint = this.bounds.x + (this.bounds.width / 2);
var verticalMidpoint = this.bounds.y + (this.bounds.height / 2);

var topQuadrant = (coord.y + coord.radius < verticalMidpoint);
var bottomQuadrant = (coord.y - coord.radius > verticalMidpoint);

if (coord.x + coord.radius < horizontalMidpoint) {
if (topQuadrant) {
index = 1;
} else if (bottomQuadrant) {
index = 2;
}
}
else if (coord.x - coord.radius > horizontalMidpoint) {
if (topQuadrant) {
index = 0;
} else if (bottomQuadrant) {
index = 3;
}
}
return index;
}

this.insert = function (coord) {
if (this.nodes[0] != null) {
var index = this.getIndex(coord);

if (index != -1) {
this.nodes[index].insert(coord);

return;
}
}

this.objects.push(coord);

if (this.objects.length > this.MAX_OBJECTS && this.level < this.MAX_LEVELS) {
if (this.nodes[0] == null) {
this.split();
}
var i = 0;
while (i < this.objects.length) {
var index = this.getIndex(this.objects[i]);
if (index != -1) {
this.nodes[index].insert(this.objects[i]);
this.objects.splice(i, 1);
} else {
i++;
}
}
}
}

this.retrieve = function (coord) {
var index = this.getIndex(coord);
var returnObjects = [];
if (index != -1 && this.nodes[0] != null) {
returnObjects = returnObjects.concat(this.nodes[index].retrieve(coord));
}

returnObjects = returnObjects.concat(this.objects);

return returnObjects;
}
this.stringify = function () {
return JSON.stringify(this, undefined, 0);
}
this.draw = function (ctx) {
var hmp = this.bounds.x + (this.bounds.width / 2);
var vmp = this.bounds.y + (this.bounds.height / 2);
context.beginPath();
context.moveTo(this.bounds.x, vmp);
context.lineTo(this.bounds.x + this.bounds.width, vmp);
context.stroke();
context.beginPath();
context.moveTo(hmp, this.bounds.y);
context.lineTo(hmp, this.bounds.y + this.bounds.height);
context.stroke();
for (var i = 0; i < 4; i++) {
if ((this.nodes[i] != null) && (this.nodes[i].objects.length != 0)) this.nodes[i].draw();
}
}
}

window.requestAnimFrame = (function () {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();

function random_int(start, end) {
return Math.floor(Math.random() * (end - start + 1) + start);
}
var balls = function balls(context) {
this.context = context,
this.all_balls = [];
this.quad = new Quadtree(0, {
x: 0,
y: 0,
width: this.context.canvas.width,
height: this.context.canvas.height
});
this.add = function () {
var x = new ball(this.context);
this.all_balls.push(x);
return x;
}
this.start = function () {
(function animloop() {
requestAnimFrame(animloop);
var x = new Date().getTime() - (this.time || new Date().getTime());
this.time = new Date().getTime();
Balls.update(x);
Balls.collision(x);
Balls.frames();
Balls.redraw();
})();
}
this.frames = function () {
var time = new Date().getTime();
if (!this.last_fps_time) this.last_fps_time = time;
if (!this.frames_since_last) this.frames_since_last = 0;
this.frames_since_last++;
if (time - this.last_fps_time >= 1000) {
this.frame_text = this.frames_since_last + " FPS";
this.frames_since_last = 0;
this.last_fps_time = time;
}
}
this.redraw = function () {
this.context.save();
this.context.setTransform(1, 0, 0, 1, 0, 0);
this.context.clearRect(0, 0, canvas.width, canvas.height);
this.context.restore();
this.each(function () {
this.draw();
});
var quadtree = false;
if (quadtree) {
this.quad.draw(this.context);
}
this.context.fillStyle = '#000000';
this.context.font = "12px 'Open Sans'";
this.context.fillText(this.frame_text || this.frames_since_last + " FPS", 5, 17);
}
this.each = function (fn) {
for (var i = 0; i < this.all_balls.length; i++) {
fn.apply(this.all_balls[i]);
}
}
this.collision = function (t) {

var returnObjects = [];
var quad = this.quad;
this.each(function () {
var A = {}, B = {};
A = this;
returnObjects = quad.retrieve(A);
for (var x = 0; x < returnObjects.length; x++) {
B = returnObjects[x];
if (A != B) {
if (((a = Math.pow(A.x - B.x, 2)) + (b = Math.pow(A.y - B.y, 2))) <= (c = Math.pow(A.radius + B.radius, 2))) {
var ax = (A.x_vel * (A.mass - B.mass) + (2 * B.mass * B.x_vel)) / (A.mass + B.mass);
var ay = (A.y_vel * (A.mass - B.mass) + (2 * B.mass * B.y_vel)) / (A.mass + B.mass);
B.x_vel = (B.x_vel * (B.mass - A.mass) + (2 * A.mass * A.x_vel)) / (A.mass + B.mass);
B.y_vel = (B.y_vel * (B.mass - A.mass) + (2 * A.mass * A.y_vel)) / (A.mass + B.mass);
A.x_vel = ax;
A.y_vel = ay;
A.x = A.x + (t * A.x_vel / 16);
A.y = A.y + (t * A.y_vel / 16);
B.x = B.x + (t * B.x_vel / 16);
B.y = B.y + (t * B.y_vel / 16);

}
}
}
});
}
this.update = function (t) {
var quad = this.quad;
quad.clear();
this.each(function () {
quad.insert(this);
this.x += (t * this.x_vel / 16);
this.y += (t * this.y_vel / 16);
var t_x_vel = this.x_vel;
var t_y_vel = this.y_vel;
if (this.x >= this.context.canvas.width - this.radius && this.x_vel > 0) this.x_vel = -this.x_vel;
if (this.x <= this.radius && this.x_vel < 0) this.x_vel = -this.x_vel;
if (this.y >= this.context.canvas.height - this.radius && this.y_vel > 0) this.y_vel = -this.y_vel;
if (this.y <= this.radius && this.y_vel < 0) this.y_vel = -this.y_vel;
if (this.x_vel != t_x_vel) this.x += (t * this.x_vel / 16);
if (this.y_vel != t_y_vel) this.y += (t * this.y_vel / 16);
});
}
}
Object.prototype.ball = function ball(context) {
this.context = context;
this.canvas = context.canvas;
this.context.fillStyle = '#ABC123';
this.radius = 15;
this.x = random_int(this.radius + 1, this.canvas.width - this.radius - 1);
this.y = random_int(this.radius + 1, this.canvas.height - this.radius - 1);
this.x_vel = random_int(-8, 8);
this.y_vel = random_int(-8, 8);
this.draw = function () {
this.context.beginPath();
this.context.arc(this.x, this.y, this.radius, 0, (Math.PI / 180) * 360, false);
this.context.fillStyle = this.col;
this.context.fill();
this.context.closePath();
}
this.color = function (col) {
this.col = col;
}
this.resize = function (r) {
this.radius = r;
this.mass = Math.ceil(r * r * Math.PI / 750);
}
this.resize(this.radius);
return this;
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
context.canvas.width = window.innerWidth * 0.9;
context.canvas.height = window.innerHeight * 0.9;
var Balls = new balls(context);
for (var i = 0; i < 2; i++) {
var b = Balls.add();
b.color("#" + ((1 << 24) * Math.random() | 0).toString(16));
b.resize(random_int(15, 50));
b.draw();
}
Balls.start();
}
</script>
<style>
#canvas {
border:1px solid #000000;
}

</style>
</head>
<body>
<canvas id="canvas"></canvas>
</body>

</html>

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote