Skip to content

Instantly share code, notes, and snippets.

@angus-c
Created September 22, 2014 04:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save angus-c/797fa92e30f91b6c2059 to your computer and use it in GitHub Desktop.
Save angus-c/797fa92e30f91b6c2059 to your computer and use it in GitHub Desktop.
A Bouncing Ball // source http://jsbin.com/figotoreqoxe/83
<!DOCTYPE html>
<html>
<head>
<title>A Bouncing Ball</title>
</head>
<body>
<canvas id="canvas" width="300" height="300"></canvas>
<input id="delay" type="range" max="2000" value="10"/>
<script id="jsbin-javascript">
var ballCount = 15;
var ballSize = 6;
var delay = 1;
var interval;
window.onload = function() {
document.getElementById('delay').addEventListener(
'change',
function(e) {
clearInterval(interval);
interval = setInterval(renderBalls, e.target.value);
}
);
}
var Ball = function (xSpeed, ySpeed, magic) {
this.x = 300*Math.random();
this.y = 300*Math.random();
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
this.magic = magic;
};
var circle = function (x, y, radius, fillCircle, color) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
if (fillCircle) {
ctx.fillStyle=color;
ctx.fill();
} else {
ctx.stroke();
}
};
Ball.prototype.draw = function () {
var color = this.magic ? "#0000FF" : "#000000";
circle(this.x, this.y, ballSize, true, color);
};
Ball.prototype.move = function () {
this.x += this.xSpeed;
this.y += this.ySpeed;
};
Ball.prototype.checkCollision = function () {
var xE = this.x + ballSize + 2;
var xxE = this.x + Math.pow((ballSize*ballSize/2), 0.5);
var xW = this.x - ballSize - 2;
var xxW = this.x - Math.pow((ballSize*ballSize/2), 0.5);
var yN = this.y - ballSize - 2;
var yyN = this.y - Math.pow((ballSize*ballSize/2), 0.5);
var yS = this.y + ballSize + 2;
var yyS = this.y + Math.pow((ballSize*ballSize/2), 0.5);
var probe = {
e: ctx.getImageData(xE, this.y, 1, 1).data[3],
w: ctx.getImageData(xW, this.y, 1, 1).data[3],
n: ctx.getImageData(this.x, yN, 1, 1).data[3],
s: ctx.getImageData(this.x, yS, 1, 1).data[3],
ne: ctx.getImageData(xxE+1, yyN-1, 1, 1).data[3],
se: ctx.getImageData(xxE+1, yyS+1, 1, 1).data[3],
nw: ctx.getImageData(xxW-1, yyN-1, 1, 1).data[3],
sw: ctx.getImageData(xxW-1, yyS+1, 1, 1).data[3]
}
if (probe.e) {
this.xSpeed = -Math.abs(this.xSpeed);
this.afterCollision(probe);
} else if (probe.w) {
this.xSpeed = Math.abs(this.xSpeed);
this.afterCollision(probe);
} else if (probe.n) {
this.ySpeed = Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.s) {
this.ySpeed = -Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.ne) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.se) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.nw) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.sw) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
this.afterCollision(probe);
}
// ctx.fillStyle="red";
// ctx.fillRect(xE, this.y, 1, 1);
// ctx.fillRect(xW, this.y, 1, 1);
// ctx.fillRect(this.x, yN, 1, 1);
// ctx.fillRect(this.x, yS, 1, 1);
// ctx.fillRect(xxE+1, yyN-1, 1, 1);
// ctx.fillRect(xxE+1, yyS+1, 1, 1);
// ctx.fillRect(xxW-1, yyN-1, 1, 1);
// ctx.fillRect(xxW-1, yyS+1, 1, 1);
};
Ball.prototype.afterCollision = function(probe) {
if (this.magic) {
// console.log(Object.keys(probe).filter(
// function(k) {return Number(probe[k])}
// ));
// console.log('sX', this.xSpeed, 'sY', this.ySpeed);
}
}
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var balls = [];
for (var i = ballCount; i > 0; i--) {
balls[i] = new Ball(
1 - 2*Math.random(),
1 - 2*Math.random(),
i == 1
);
}
interval = setInterval(renderBalls, delay);
function renderBalls() {
ctx.clearRect(0, 0, 300, 300);
ctx.strokeRect(0, 0, 300, 300);
for (var i = ballCount; i > 0; i--) {
balls[i].draw();
balls[i].checkCollision();
balls[i].move();
}
}
</script>
<script id="jsbin-source-javascript" type="text/javascript"> var ballCount = 15;
var ballSize = 6;
var delay = 1;
var interval;
window.onload = function() {
document.getElementById('delay').addEventListener(
'change',
function(e) {
clearInterval(interval);
interval = setInterval(renderBalls, e.target.value);
}
);
}
var Ball = function (xSpeed, ySpeed, magic) {
this.x = 300*Math.random();
this.y = 300*Math.random();
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
this.magic = magic;
};
var circle = function (x, y, radius, fillCircle, color) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
if (fillCircle) {
ctx.fillStyle=color;
ctx.fill();
} else {
ctx.stroke();
}
};
Ball.prototype.draw = function () {
var color = this.magic ? "#0000FF" : "#000000";
circle(this.x, this.y, ballSize, true, color);
};
Ball.prototype.move = function () {
this.x += this.xSpeed;
this.y += this.ySpeed;
};
Ball.prototype.checkCollision = function () {
var xE = this.x + ballSize + 2;
var xxE = this.x + Math.pow((ballSize*ballSize/2), 0.5);
var xW = this.x - ballSize - 2;
var xxW = this.x - Math.pow((ballSize*ballSize/2), 0.5);
var yN = this.y - ballSize - 2;
var yyN = this.y - Math.pow((ballSize*ballSize/2), 0.5);
var yS = this.y + ballSize + 2;
var yyS = this.y + Math.pow((ballSize*ballSize/2), 0.5);
var probe = {
e: ctx.getImageData(xE, this.y, 1, 1).data[3],
w: ctx.getImageData(xW, this.y, 1, 1).data[3],
n: ctx.getImageData(this.x, yN, 1, 1).data[3],
s: ctx.getImageData(this.x, yS, 1, 1).data[3],
ne: ctx.getImageData(xxE+1, yyN-1, 1, 1).data[3],
se: ctx.getImageData(xxE+1, yyS+1, 1, 1).data[3],
nw: ctx.getImageData(xxW-1, yyN-1, 1, 1).data[3],
sw: ctx.getImageData(xxW-1, yyS+1, 1, 1).data[3]
}
if (probe.e) {
this.xSpeed = -Math.abs(this.xSpeed);
this.afterCollision(probe);
} else if (probe.w) {
this.xSpeed = Math.abs(this.xSpeed);
this.afterCollision(probe);
} else if (probe.n) {
this.ySpeed = Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.s) {
this.ySpeed = -Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.ne) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.se) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.nw) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.sw) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
this.afterCollision(probe);
}
// ctx.fillStyle="red";
// ctx.fillRect(xE, this.y, 1, 1);
// ctx.fillRect(xW, this.y, 1, 1);
// ctx.fillRect(this.x, yN, 1, 1);
// ctx.fillRect(this.x, yS, 1, 1);
// ctx.fillRect(xxE+1, yyN-1, 1, 1);
// ctx.fillRect(xxE+1, yyS+1, 1, 1);
// ctx.fillRect(xxW-1, yyN-1, 1, 1);
// ctx.fillRect(xxW-1, yyS+1, 1, 1);
};
Ball.prototype.afterCollision = function(probe) {
if (this.magic) {
// console.log(Object.keys(probe).filter(
// function(k) {return Number(probe[k])}
// ));
// console.log('sX', this.xSpeed, 'sY', this.ySpeed);
}
}
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var balls = [];
for (var i = ballCount; i > 0; i--) {
balls[i] = new Ball(
1 - 2*Math.random(),
1 - 2*Math.random(),
i == 1
);
}
interval = setInterval(renderBalls, delay);
function renderBalls() {
ctx.clearRect(0, 0, 300, 300);
ctx.strokeRect(0, 0, 300, 300);
for (var i = ballCount; i > 0; i--) {
balls[i].draw();
balls[i].checkCollision();
balls[i].move();
}
}
</script></body>
</html>
var ballCount = 15;
var ballSize = 6;
var delay = 1;
var interval;
window.onload = function() {
document.getElementById('delay').addEventListener(
'change',
function(e) {
clearInterval(interval);
interval = setInterval(renderBalls, e.target.value);
}
);
}
var Ball = function (xSpeed, ySpeed, magic) {
this.x = 300*Math.random();
this.y = 300*Math.random();
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
this.magic = magic;
};
var circle = function (x, y, radius, fillCircle, color) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
if (fillCircle) {
ctx.fillStyle=color;
ctx.fill();
} else {
ctx.stroke();
}
};
Ball.prototype.draw = function () {
var color = this.magic ? "#0000FF" : "#000000";
circle(this.x, this.y, ballSize, true, color);
};
Ball.prototype.move = function () {
this.x += this.xSpeed;
this.y += this.ySpeed;
};
Ball.prototype.checkCollision = function () {
var xE = this.x + ballSize + 2;
var xxE = this.x + Math.pow((ballSize*ballSize/2), 0.5);
var xW = this.x - ballSize - 2;
var xxW = this.x - Math.pow((ballSize*ballSize/2), 0.5);
var yN = this.y - ballSize - 2;
var yyN = this.y - Math.pow((ballSize*ballSize/2), 0.5);
var yS = this.y + ballSize + 2;
var yyS = this.y + Math.pow((ballSize*ballSize/2), 0.5);
var probe = {
e: ctx.getImageData(xE, this.y, 1, 1).data[3],
w: ctx.getImageData(xW, this.y, 1, 1).data[3],
n: ctx.getImageData(this.x, yN, 1, 1).data[3],
s: ctx.getImageData(this.x, yS, 1, 1).data[3],
ne: ctx.getImageData(xxE+1, yyN-1, 1, 1).data[3],
se: ctx.getImageData(xxE+1, yyS+1, 1, 1).data[3],
nw: ctx.getImageData(xxW-1, yyN-1, 1, 1).data[3],
sw: ctx.getImageData(xxW-1, yyS+1, 1, 1).data[3]
}
if (probe.e) {
this.xSpeed = -Math.abs(this.xSpeed);
this.afterCollision(probe);
} else if (probe.w) {
this.xSpeed = Math.abs(this.xSpeed);
this.afterCollision(probe);
} else if (probe.n) {
this.ySpeed = Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.s) {
this.ySpeed = -Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.ne) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.se) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.nw) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
this.afterCollision(probe);
} else if (probe.sw) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
this.afterCollision(probe);
}
// ctx.fillStyle="red";
// ctx.fillRect(xE, this.y, 1, 1);
// ctx.fillRect(xW, this.y, 1, 1);
// ctx.fillRect(this.x, yN, 1, 1);
// ctx.fillRect(this.x, yS, 1, 1);
// ctx.fillRect(xxE+1, yyN-1, 1, 1);
// ctx.fillRect(xxE+1, yyS+1, 1, 1);
// ctx.fillRect(xxW-1, yyN-1, 1, 1);
// ctx.fillRect(xxW-1, yyS+1, 1, 1);
};
Ball.prototype.afterCollision = function(probe) {
if (this.magic) {
// console.log(Object.keys(probe).filter(
// function(k) {return Number(probe[k])}
// ));
// console.log('sX', this.xSpeed, 'sY', this.ySpeed);
}
}
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var balls = [];
for (var i = ballCount; i > 0; i--) {
balls[i] = new Ball(
1 - 2*Math.random(),
1 - 2*Math.random(),
i == 1
);
}
interval = setInterval(renderBalls, delay);
function renderBalls() {
ctx.clearRect(0, 0, 300, 300);
ctx.strokeRect(0, 0, 300, 300);
for (var i = ballCount; i > 0; i--) {
balls[i].draw();
balls[i].checkCollision();
balls[i].move();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment