Created
January 25, 2015 00:36
-
-
Save angus-c/f9d77a5dd216c50eaadc to your computer and use it in GitHub Desktop.
bouncer // source http://jsbin.com/vodep
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.3.22/rx.all.js"></script> | |
<title>bouncer</title> | |
</head> | |
<body> | |
<svg id="box" class="space" style="border: 1px solid; width: 400px; height: 400px" height="100%"></svg> | |
<script id="jsbin-javascript"> | |
var svgNS = "http://www.w3.org/2000/svg"; | |
var size = parseInt(document.getElementById('box').style.width); | |
var ballCount = 25; | |
var ballSize = 10; | |
var v = 0; | |
var xChange = new Rx.Subject(); | |
var yChange = new Rx.Subject(); | |
var subscription = xChange.subscribe(function (data) { | |
data.ball.xSpeed = data.x; | |
}); | |
var subscription = yChange.subscribe(function (data) { | |
data.ball.ySpeed = data.y; | |
}); | |
var probeOffsets = { | |
primary: ballSize + 3, | |
secondary: Math.pow((ballSize*ballSize/2), 0.5) + 2 | |
} | |
var Ball = function (xSpeed, ySpeed, magic, id) { | |
this.x = size*Math.random(); | |
this.y = size*Math.random(); | |
this.xSpeed = xSpeed; | |
this.ySpeed = ySpeed; | |
this.magic = magic; | |
this.id = id; | |
}; | |
function circle(id, x, y, radius, color) { | |
var c = document.createElementNS(svgNS, "circle"); | |
c.setAttribute('id', id); | |
c.setAttribute("class", 'ball'); | |
c.setAttributeNS(null, "cx", x); | |
c.setAttributeNS(null, "cy", y); | |
c.setAttributeNS(null, "r", radius); | |
c.setAttributeNS(null, "fill", color || "blue"); | |
document.getElementById("box").appendChild(c); | |
return c; | |
} | |
Ball.prototype.draw = function () { | |
this.node = circle(this.id, this.x, this.y, ballSize, this.magic ? 'red' : this.color); | |
}; | |
var balls = []; | |
for (var i = 1; i <= ballCount; i++) { | |
balls[i] = new Ball( | |
1 - 2 * Math.random(), | |
1 - 2 * Math.random(), | |
i == 1, | |
i, | |
'blue' | |
); | |
balls[i].draw(); | |
} | |
Ball.prototype.move = function () { | |
this.node.setAttributeNS(null, "cx", this.x += this.xSpeed); | |
this.node.setAttributeNS(null, "cy", this.y += this.ySpeed); | |
}; | |
Ball.prototype.registerOpposingX = function(val) { | |
xChange.onNext({ball: this, x: val}); | |
} | |
Ball.prototype.registerOpposingY = function(val) { | |
yChange.onNext({ball: this, y: val}); | |
} | |
Ball.prototype.checkCollision = function () { | |
var p = probeOffsets.primary; | |
var s = probeOffsets.secondary; | |
var probes = [[p, 0], [-p, 0], [0, p], [0, -p], [s, s], [-s, -s], [s, -s], [-s, s]]; | |
for (var i = 0; i < probes.length; i++) { | |
var probeLeft = (probes[i][0] < 0); | |
var probeTop = (probes[i][1] < 0); | |
var detected = elemAt(this.x + probes[i][0], this.y + probes[i][1]); | |
if (!detected || !(detected.id)) { | |
if (probes[i][0]) { | |
this.registerOpposingX((probeLeft ? 1 : -1) * Math.abs(this.xSpeed)); | |
} | |
if (probes[i][1]) { | |
this.registerOpposingY((probeTop ? 1 : -1) * Math.abs(this.ySpeed)); | |
} | |
} else if(detected.id != 'box') { | |
if (probes[i][0]) { | |
this.registerOpposingX((probeLeft ? 1 : -1) * Math.abs(balls[detected.id]['xSpeed'])); | |
balls[detected.id].registerOpposingX((probeLeft ? -1 : 1) * Math.abs(this['xSpeed'])); | |
} | |
if (probes[i][1]) { | |
this.registerOpposingY((probeTop ? 1 : -1) * Math.abs(balls[detected.id]['ySpeed'])); | |
balls[detected.id].registerOpposingY((probeLeft ? -1 : 1) * Math.abs(this['ySpeed'])); | |
} | |
} | |
} | |
function elemAt(x, y) { | |
return document.elementFromPoint(x+8, y+8); | |
} | |
if (this.magic) { | |
//console.log(Object.keys(probe).filter(function(k) { | |
// return !isAt(probe[k].x, probe[k].y, 'box'); | |
//})); | |
//console.log('sX', this.xSpeed, 'sY', this.ySpeed); | |
} | |
}; | |
function checkCollisions() { | |
for (var i = 1; i <= ballCount; i++) { | |
balls[i].checkCollision(); | |
} | |
} | |
function moveAll() { | |
for (var i = 1; i <= ballCount; i++) { | |
balls[i].move(); | |
} | |
if (!v) { | |
requestAnimationFrame(moveAll); | |
} | |
} | |
if (!v) { | |
moveAll(); | |
} else { | |
document.body.addEventListener('click', moveAll); | |
} | |
setInterval(checkCollisions, 0); | |
/* | |
function point(id, x, y, color) { | |
var c = document.createElementNS(svgNS, "circle"); | |
c.setAttribute('id', id); | |
c.setAttribute("class", 'probe'); | |
c.setAttributeNS(null, "cx", x); | |
c.setAttributeNS(null, "cy", y); | |
c.setAttributeNS(null, "r", 1); | |
c.setAttributeNS(null, "fill", color || "red"); | |
document.getElementById("box").appendChild(c); | |
} | |
*/ | |
</script> | |
<script id="jsbin-source-html" type="text/html"><!DOCTYPE html> | |
<html> | |
<head> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/rxjs/2.3.22/rx.all.js"><\/script> | |
<title>bouncer</title> | |
</head> | |
<body> | |
<svg id="box" class="space" style="border: 1px solid; width: 400px; height: 400px" height="100%"></svg> | |
</body> | |
</html></script> | |
<script id="jsbin-source-javascript" type="text/javascript">var svgNS = "http://www.w3.org/2000/svg"; | |
var size = parseInt(document.getElementById('box').style.width); | |
var ballCount = 25; | |
var ballSize = 10; | |
var v = 0; | |
var xChange = new Rx.Subject(); | |
var yChange = new Rx.Subject(); | |
var subscription = xChange.subscribe(function (data) { | |
data.ball.xSpeed = data.x; | |
}); | |
var subscription = yChange.subscribe(function (data) { | |
data.ball.ySpeed = data.y; | |
}); | |
var probeOffsets = { | |
primary: ballSize + 3, | |
secondary: Math.pow((ballSize*ballSize/2), 0.5) + 2 | |
} | |
var Ball = function (xSpeed, ySpeed, magic, id) { | |
this.x = size*Math.random(); | |
this.y = size*Math.random(); | |
this.xSpeed = xSpeed; | |
this.ySpeed = ySpeed; | |
this.magic = magic; | |
this.id = id; | |
}; | |
function circle(id, x, y, radius, color) { | |
var c = document.createElementNS(svgNS, "circle"); | |
c.setAttribute('id', id); | |
c.setAttribute("class", 'ball'); | |
c.setAttributeNS(null, "cx", x); | |
c.setAttributeNS(null, "cy", y); | |
c.setAttributeNS(null, "r", radius); | |
c.setAttributeNS(null, "fill", color || "blue"); | |
document.getElementById("box").appendChild(c); | |
return c; | |
} | |
Ball.prototype.draw = function () { | |
this.node = circle(this.id, this.x, this.y, ballSize, this.magic ? 'red' : this.color); | |
}; | |
var balls = []; | |
for (var i = 1; i <= ballCount; i++) { | |
balls[i] = new Ball( | |
1 - 2 * Math.random(), | |
1 - 2 * Math.random(), | |
i == 1, | |
i, | |
'blue' | |
); | |
balls[i].draw(); | |
} | |
Ball.prototype.move = function () { | |
this.node.setAttributeNS(null, "cx", this.x += this.xSpeed); | |
this.node.setAttributeNS(null, "cy", this.y += this.ySpeed); | |
}; | |
Ball.prototype.registerOpposingX = function(val) { | |
xChange.onNext({ball: this, x: val}); | |
} | |
Ball.prototype.registerOpposingY = function(val) { | |
yChange.onNext({ball: this, y: val}); | |
} | |
Ball.prototype.checkCollision = function () { | |
var p = probeOffsets.primary; | |
var s = probeOffsets.secondary; | |
var probes = [[p, 0], [-p, 0], [0, p], [0, -p], [s, s], [-s, -s], [s, -s], [-s, s]]; | |
for (var i = 0; i < probes.length; i++) { | |
var probeLeft = (probes[i][0] < 0); | |
var probeTop = (probes[i][1] < 0); | |
var detected = elemAt(this.x + probes[i][0], this.y + probes[i][1]); | |
if (!detected || !(detected.id)) { | |
if (probes[i][0]) { | |
this.registerOpposingX((probeLeft ? 1 : -1) * Math.abs(this.xSpeed)); | |
} | |
if (probes[i][1]) { | |
this.registerOpposingY((probeTop ? 1 : -1) * Math.abs(this.ySpeed)); | |
} | |
} else if(detected.id != 'box') { | |
if (probes[i][0]) { | |
this.registerOpposingX((probeLeft ? 1 : -1) * Math.abs(balls[detected.id]['xSpeed'])); | |
balls[detected.id].registerOpposingX((probeLeft ? -1 : 1) * Math.abs(this['xSpeed'])); | |
} | |
if (probes[i][1]) { | |
this.registerOpposingY((probeTop ? 1 : -1) * Math.abs(balls[detected.id]['ySpeed'])); | |
balls[detected.id].registerOpposingY((probeLeft ? -1 : 1) * Math.abs(this['ySpeed'])); | |
} | |
} | |
} | |
function elemAt(x, y) { | |
return document.elementFromPoint(x+8, y+8); | |
} | |
if (this.magic) { | |
//console.log(Object.keys(probe).filter(function(k) { | |
// return !isAt(probe[k].x, probe[k].y, 'box'); | |
//})); | |
//console.log('sX', this.xSpeed, 'sY', this.ySpeed); | |
} | |
}; | |
function checkCollisions() { | |
for (var i = 1; i <= ballCount; i++) { | |
balls[i].checkCollision(); | |
} | |
} | |
function moveAll() { | |
for (var i = 1; i <= ballCount; i++) { | |
balls[i].move(); | |
} | |
if (!v) { | |
requestAnimationFrame(moveAll); | |
} | |
} | |
if (!v) { | |
moveAll(); | |
} else { | |
document.body.addEventListener('click', moveAll); | |
} | |
setInterval(checkCollisions, 0); | |
/* | |
function point(id, x, y, color) { | |
var c = document.createElementNS(svgNS, "circle"); | |
c.setAttribute('id', id); | |
c.setAttribute("class", 'probe'); | |
c.setAttributeNS(null, "cx", x); | |
c.setAttributeNS(null, "cy", y); | |
c.setAttributeNS(null, "r", 1); | |
c.setAttributeNS(null, "fill", color || "red"); | |
document.getElementById("box").appendChild(c); | |
} | |
*/ | |
</script></body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var svgNS = "http://www.w3.org/2000/svg"; | |
var size = parseInt(document.getElementById('box').style.width); | |
var ballCount = 25; | |
var ballSize = 10; | |
var v = 0; | |
var xChange = new Rx.Subject(); | |
var yChange = new Rx.Subject(); | |
var subscription = xChange.subscribe(function (data) { | |
data.ball.xSpeed = data.x; | |
}); | |
var subscription = yChange.subscribe(function (data) { | |
data.ball.ySpeed = data.y; | |
}); | |
var probeOffsets = { | |
primary: ballSize + 3, | |
secondary: Math.pow((ballSize*ballSize/2), 0.5) + 2 | |
} | |
var Ball = function (xSpeed, ySpeed, magic, id) { | |
this.x = size*Math.random(); | |
this.y = size*Math.random(); | |
this.xSpeed = xSpeed; | |
this.ySpeed = ySpeed; | |
this.magic = magic; | |
this.id = id; | |
}; | |
function circle(id, x, y, radius, color) { | |
var c = document.createElementNS(svgNS, "circle"); | |
c.setAttribute('id', id); | |
c.setAttribute("class", 'ball'); | |
c.setAttributeNS(null, "cx", x); | |
c.setAttributeNS(null, "cy", y); | |
c.setAttributeNS(null, "r", radius); | |
c.setAttributeNS(null, "fill", color || "blue"); | |
document.getElementById("box").appendChild(c); | |
return c; | |
} | |
Ball.prototype.draw = function () { | |
this.node = circle(this.id, this.x, this.y, ballSize, this.magic ? 'red' : this.color); | |
}; | |
var balls = []; | |
for (var i = 1; i <= ballCount; i++) { | |
balls[i] = new Ball( | |
1 - 2 * Math.random(), | |
1 - 2 * Math.random(), | |
i == 1, | |
i, | |
'blue' | |
); | |
balls[i].draw(); | |
} | |
Ball.prototype.move = function () { | |
this.node.setAttributeNS(null, "cx", this.x += this.xSpeed); | |
this.node.setAttributeNS(null, "cy", this.y += this.ySpeed); | |
}; | |
Ball.prototype.registerOpposingX = function(val) { | |
xChange.onNext({ball: this, x: val}); | |
} | |
Ball.prototype.registerOpposingY = function(val) { | |
yChange.onNext({ball: this, y: val}); | |
} | |
Ball.prototype.checkCollision = function () { | |
var p = probeOffsets.primary; | |
var s = probeOffsets.secondary; | |
var probes = [[p, 0], [-p, 0], [0, p], [0, -p], [s, s], [-s, -s], [s, -s], [-s, s]]; | |
for (var i = 0; i < probes.length; i++) { | |
var probeLeft = (probes[i][0] < 0); | |
var probeTop = (probes[i][1] < 0); | |
var detected = elemAt(this.x + probes[i][0], this.y + probes[i][1]); | |
if (!detected || !(detected.id)) { | |
if (probes[i][0]) { | |
this.registerOpposingX((probeLeft ? 1 : -1) * Math.abs(this.xSpeed)); | |
} | |
if (probes[i][1]) { | |
this.registerOpposingY((probeTop ? 1 : -1) * Math.abs(this.ySpeed)); | |
} | |
} else if(detected.id != 'box') { | |
if (probes[i][0]) { | |
this.registerOpposingX((probeLeft ? 1 : -1) * Math.abs(balls[detected.id]['xSpeed'])); | |
balls[detected.id].registerOpposingX((probeLeft ? -1 : 1) * Math.abs(this['xSpeed'])); | |
} | |
if (probes[i][1]) { | |
this.registerOpposingY((probeTop ? 1 : -1) * Math.abs(balls[detected.id]['ySpeed'])); | |
balls[detected.id].registerOpposingY((probeLeft ? -1 : 1) * Math.abs(this['ySpeed'])); | |
} | |
} | |
} | |
function elemAt(x, y) { | |
return document.elementFromPoint(x+8, y+8); | |
} | |
if (this.magic) { | |
//console.log(Object.keys(probe).filter(function(k) { | |
// return !isAt(probe[k].x, probe[k].y, 'box'); | |
//})); | |
//console.log('sX', this.xSpeed, 'sY', this.ySpeed); | |
} | |
}; | |
function checkCollisions() { | |
for (var i = 1; i <= ballCount; i++) { | |
balls[i].checkCollision(); | |
} | |
} | |
function moveAll() { | |
for (var i = 1; i <= ballCount; i++) { | |
balls[i].move(); | |
} | |
if (!v) { | |
requestAnimationFrame(moveAll); | |
} | |
} | |
if (!v) { | |
moveAll(); | |
} else { | |
document.body.addEventListener('click', moveAll); | |
} | |
setInterval(checkCollisions, 0); | |
/* | |
function point(id, x, y, color) { | |
var c = document.createElementNS(svgNS, "circle"); | |
c.setAttribute('id', id); | |
c.setAttribute("class", 'probe'); | |
c.setAttributeNS(null, "cx", x); | |
c.setAttributeNS(null, "cy", y); | |
c.setAttributeNS(null, "r", 1); | |
c.setAttributeNS(null, "fill", color || "red"); | |
document.getElementById("box").appendChild(c); | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment