Skip to content

Instantly share code, notes, and snippets.

@angus-c
Created January 13, 2015 16:43
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/190218971b16b6a8b35c to your computer and use it in GitHub Desktop.
Save angus-c/190218971b16b6a8b35c to your computer and use it in GitHub Desktop.
bouncer // source http://jsbin.com/vodep
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="http://code.jquery.com/jquery-git2.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 = 30;
var ballSize = 10;
var delay = 0;
var interval;
// var colors = ['black', 'blue', 'fuschia', 'green', 'coral', 'gray', 'navy', 'purple', 'olive', 'red'];
var map;
var collisionCount = 0;
// window.onload = function() {
// document.getElementById('delay').addEventListener(
// 'change',
// function(e) {
// clearInterval(interval);
// interval = setInterval(renderBalls, e.target.value);
// }
// );
// }
var Ball = function (xSpeed, ySpeed, magic, id, color) {
this.x = size*Math.random();
this.y = size*Math.random();
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
this.magic = magic;
this.id = id;
this.color = color;
this.movesSinceCollision = 0;
};
function circle(id, x, y, radius, color) {
var c = document.createElementNS(svgNS, "circle");
c.setAttribute('id', id);
c.setAttribute("class", 'ball');
//c.setAttributeNS(null, "id", "circle1");
c.setAttributeNS(null, "cx", x);
c.setAttributeNS(null, "cy", y);
c.setAttributeNS(null, "r", radius);
c.setAttributeNS(null, "fill", color || "blue");
//myCircle.setAttributeNS(null, "stroke", "none");
document.getElementById("box").appendChild(c);
}
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);
}
Ball.prototype.draw = function () {
circle(this.id, this.x, this.y, ballSize, this.color);
};
var balls = [];
for (var i = 1; i <= ballCount; i++) {
console.log(i);
balls[i] = new Ball(
1 - 2*Math.random(),
1 - 2*Math.random(),
i == 1,
i,
//'#' + ('00' + Math.floor(i*255/(ballCount-1)).toString(16)).slice(-2) + '00' + ('00'+i).slice(-2) //set blue to id
'blue'
);
balls[i].draw();
}
interval = setInterval(moveAll, delay);
function moveAll() {
[].slice.call(document.querySelectorAll('.probe')).forEach(function(e){
e.parentNode.removeChild(e)
});
for (var i = 1; i <= ballCount; i++) {
balls[i].checkCollision();
balls[i].move();
}
}
Ball.prototype.move = function () {
this.x += this.xSpeed;
this.y += this.ySpeed;
this.movesSinceCollision++;
$('#' + this.id)[0].setAttributeNS(null, "cx", this.x);
$('#' + this.id)[0].setAttributeNS(null, "cy", this.y);
};
Ball.prototype.checkCollision = function () {
var xE = this.x + ballSize + 4;
var xxE = this.x + Math.pow((ballSize*ballSize/2), 0.5);
var xW = this.x - ballSize - 4;
var xxW = this.x - Math.pow((ballSize*ballSize/2), 0.5);
var yN = this.y - ballSize - 4;
var yyN = this.y - Math.pow((ballSize*ballSize/2), 0.5);
var yS = this.y + ballSize + 4;
var yyS = this.y + Math.pow((ballSize*ballSize/2), 0.5);
var collidingBallIndex;
var probe = {
e: {
x: xE,
y: this.y
},
w: {
x: xW,
y: this.y
},
n: {
x: this.x,
y: yN
},
s: {
x: this.x,
y: yS
},
ne: {
x: xxE + 2,
y: yyN - 2
},
se: {
x: xxE + 2,
y: yyS + 2
},
nw: {
x: xxW - 2,
y: yyN - 2
},
sw: {
x: xxW - 2,
y: yyS + 2
}
};
if (!isAt(probe.e.x, probe.e.y, 'box')) {
this.xSpeed = -Math.abs(this.xSpeed);
//this.afterCollision(probe.e);
} else if (!isAt(probe.w.x, probe.w.y, 'box')) {
this.xSpeed = Math.abs(this.xSpeed);
//this.afterCollision(probe.w);
} else if (!isAt(probe.n.x, probe.n.y, 'box')) {
this.ySpeed = Math.abs(this.ySpeed);
//this.afterCollision(probe.n);
} else if (!isAt(probe.s.x, probe.s.y, 'box', 's')) {
this.ySpeed = -Math.abs(this.ySpeed);
//this.afterCollision(probe.s);
} else if (!isAt(probe.ne.x, probe.ne.y, 'box')) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
//this.afterCollision(probe.ne);
} else if (!isAt(probe.se.x, probe.se.y, 'box', 'se')) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
//this.afterCollision(probe.se);
} else if (!isAt(probe.nw.x, probe.nw.y, 'box')) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
//this.afterCollision(probe.nw);
} else if (!isAt(probe.sw.x, probe.sw.y, 'box')) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
//this.afterCollision(probe.sw);
}
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);
}
Object.keys(probe).forEach(function(e) {
//console.log(probe[e]);
//point(e, probe[e].x, probe[e].y);
});
};
function classAtContains(x, y, str) {
var elem = document.elementFromPoint(x, y);
//console.log(x, y, elem, elem && elem.className.baseValue)
return elem && elem.className.baseValue && (elem.className.baseValue.indexOf(str) > -1);
}
function isAt(x, y, id, check) {
var elem = document.elementFromPoint(x+8, y+8);
if (check) {
//debugger;
//console.log(check, x, y, elem, elem && elem.id)
}
return elem && elem.id && (elem.id == id);
}
function getOpacityAt(x, y) {
//return map[(Math.round(x) + Math.round(y)*300)*4 - 1];
}
function getBlueAt(x, y) {
//return map[(Math.round(x) + Math.round(y)*300)*4 - 2];
}
Ball.prototype.afterCollision = function(probe) {
// blue value is the id
collidingBallIndex = getBlueAt(probe.x, probe.y);
if (balls[collidingBallIndex]) {
balls[collidingBallIndex].color = "#ff" + balls[collidingBallIndex].color.slice(-4);
}
if (!this.movesSinceCollision) {
//console.log('pos:', this.x, this.y);
//console.log(
// Object.keys(probe).filter(
// function(k) {return Number(probe[k])}
// )
//);
}
this.movesSinceCollision = 0;
};
// var canvas = document.getElementById("canvas");
// var ctx = canvas.getContext("2d");
// var size = canvas.width;
</script>
<script id="jsbin-source-html" type="text/html"><!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-2.1.1.min.js"><\/script>
<script src="//code.jquery.com/jquery-git2.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 = 30;
var ballSize = 10;
var delay = 0;
var interval;
// var colors = ['black', 'blue', 'fuschia', 'green', 'coral', 'gray', 'navy', 'purple', 'olive', 'red'];
var map;
var collisionCount = 0;
// window.onload = function() {
// document.getElementById('delay').addEventListener(
// 'change',
// function(e) {
// clearInterval(interval);
// interval = setInterval(renderBalls, e.target.value);
// }
// );
// }
var Ball = function (xSpeed, ySpeed, magic, id, color) {
this.x = size*Math.random();
this.y = size*Math.random();
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
this.magic = magic;
this.id = id;
this.color = color;
this.movesSinceCollision = 0;
};
function circle(id, x, y, radius, color) {
var c = document.createElementNS(svgNS, "circle");
c.setAttribute('id', id);
c.setAttribute("class", 'ball');
//c.setAttributeNS(null, "id", "circle1");
c.setAttributeNS(null, "cx", x);
c.setAttributeNS(null, "cy", y);
c.setAttributeNS(null, "r", radius);
c.setAttributeNS(null, "fill", color || "blue");
//myCircle.setAttributeNS(null, "stroke", "none");
document.getElementById("box").appendChild(c);
}
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);
}
Ball.prototype.draw = function () {
circle(this.id, this.x, this.y, ballSize, this.color);
};
var balls = [];
for (var i = 1; i <= ballCount; i++) {
console.log(i);
balls[i] = new Ball(
1 - 2*Math.random(),
1 - 2*Math.random(),
i == 1,
i,
//'#' + ('00' + Math.floor(i*255/(ballCount-1)).toString(16)).slice(-2) + '00' + ('00'+i).slice(-2) //set blue to id
'blue'
);
balls[i].draw();
}
interval = setInterval(moveAll, delay);
function moveAll() {
[].slice.call(document.querySelectorAll('.probe')).forEach(function(e){
e.parentNode.removeChild(e)
});
for (var i = 1; i <= ballCount; i++) {
balls[i].checkCollision();
balls[i].move();
}
}
Ball.prototype.move = function () {
this.x += this.xSpeed;
this.y += this.ySpeed;
this.movesSinceCollision++;
$('#' + this.id)[0].setAttributeNS(null, "cx", this.x);
$('#' + this.id)[0].setAttributeNS(null, "cy", this.y);
};
Ball.prototype.checkCollision = function () {
var xE = this.x + ballSize + 4;
var xxE = this.x + Math.pow((ballSize*ballSize/2), 0.5);
var xW = this.x - ballSize - 4;
var xxW = this.x - Math.pow((ballSize*ballSize/2), 0.5);
var yN = this.y - ballSize - 4;
var yyN = this.y - Math.pow((ballSize*ballSize/2), 0.5);
var yS = this.y + ballSize + 4;
var yyS = this.y + Math.pow((ballSize*ballSize/2), 0.5);
var collidingBallIndex;
var probe = {
e: {
x: xE,
y: this.y
},
w: {
x: xW,
y: this.y
},
n: {
x: this.x,
y: yN
},
s: {
x: this.x,
y: yS
},
ne: {
x: xxE + 2,
y: yyN - 2
},
se: {
x: xxE + 2,
y: yyS + 2
},
nw: {
x: xxW - 2,
y: yyN - 2
},
sw: {
x: xxW - 2,
y: yyS + 2
}
};
if (!isAt(probe.e.x, probe.e.y, 'box')) {
this.xSpeed = -Math.abs(this.xSpeed);
//this.afterCollision(probe.e);
} else if (!isAt(probe.w.x, probe.w.y, 'box')) {
this.xSpeed = Math.abs(this.xSpeed);
//this.afterCollision(probe.w);
} else if (!isAt(probe.n.x, probe.n.y, 'box')) {
this.ySpeed = Math.abs(this.ySpeed);
//this.afterCollision(probe.n);
} else if (!isAt(probe.s.x, probe.s.y, 'box', 's')) {
this.ySpeed = -Math.abs(this.ySpeed);
//this.afterCollision(probe.s);
} else if (!isAt(probe.ne.x, probe.ne.y, 'box')) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
//this.afterCollision(probe.ne);
} else if (!isAt(probe.se.x, probe.se.y, 'box', 'se')) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
//this.afterCollision(probe.se);
} else if (!isAt(probe.nw.x, probe.nw.y, 'box')) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
//this.afterCollision(probe.nw);
} else if (!isAt(probe.sw.x, probe.sw.y, 'box')) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
//this.afterCollision(probe.sw);
}
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);
}
Object.keys(probe).forEach(function(e) {
//console.log(probe[e]);
//point(e, probe[e].x, probe[e].y);
});
};
function classAtContains(x, y, str) {
var elem = document.elementFromPoint(x, y);
//console.log(x, y, elem, elem && elem.className.baseValue)
return elem && elem.className.baseValue && (elem.className.baseValue.indexOf(str) > -1);
}
function isAt(x, y, id, check) {
var elem = document.elementFromPoint(x+8, y+8);
if (check) {
//debugger;
//console.log(check, x, y, elem, elem && elem.id)
}
return elem && elem.id && (elem.id == id);
}
function getOpacityAt(x, y) {
//return map[(Math.round(x) + Math.round(y)*300)*4 - 1];
}
function getBlueAt(x, y) {
//return map[(Math.round(x) + Math.round(y)*300)*4 - 2];
}
Ball.prototype.afterCollision = function(probe) {
// blue value is the id
collidingBallIndex = getBlueAt(probe.x, probe.y);
if (balls[collidingBallIndex]) {
balls[collidingBallIndex].color = "#ff" + balls[collidingBallIndex].color.slice(-4);
}
if (!this.movesSinceCollision) {
//console.log('pos:', this.x, this.y);
//console.log(
// Object.keys(probe).filter(
// function(k) {return Number(probe[k])}
// )
//);
}
this.movesSinceCollision = 0;
};
// var canvas = document.getElementById("canvas");
// var ctx = canvas.getContext("2d");
// var size = canvas.width;
</script></body>
</html>
var svgNS = "http://www.w3.org/2000/svg";
var size = parseInt(document.getElementById('box').style.width);
var ballCount = 30;
var ballSize = 10;
var delay = 0;
var interval;
// var colors = ['black', 'blue', 'fuschia', 'green', 'coral', 'gray', 'navy', 'purple', 'olive', 'red'];
var map;
var collisionCount = 0;
// window.onload = function() {
// document.getElementById('delay').addEventListener(
// 'change',
// function(e) {
// clearInterval(interval);
// interval = setInterval(renderBalls, e.target.value);
// }
// );
// }
var Ball = function (xSpeed, ySpeed, magic, id, color) {
this.x = size*Math.random();
this.y = size*Math.random();
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
this.magic = magic;
this.id = id;
this.color = color;
this.movesSinceCollision = 0;
};
function circle(id, x, y, radius, color) {
var c = document.createElementNS(svgNS, "circle");
c.setAttribute('id', id);
c.setAttribute("class", 'ball');
//c.setAttributeNS(null, "id", "circle1");
c.setAttributeNS(null, "cx", x);
c.setAttributeNS(null, "cy", y);
c.setAttributeNS(null, "r", radius);
c.setAttributeNS(null, "fill", color || "blue");
//myCircle.setAttributeNS(null, "stroke", "none");
document.getElementById("box").appendChild(c);
}
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);
}
Ball.prototype.draw = function () {
circle(this.id, this.x, this.y, ballSize, this.color);
};
var balls = [];
for (var i = 1; i <= ballCount; i++) {
console.log(i);
balls[i] = new Ball(
1 - 2*Math.random(),
1 - 2*Math.random(),
i == 1,
i,
//'#' + ('00' + Math.floor(i*255/(ballCount-1)).toString(16)).slice(-2) + '00' + ('00'+i).slice(-2) //set blue to id
'blue'
);
balls[i].draw();
}
interval = setInterval(moveAll, delay);
function moveAll() {
[].slice.call(document.querySelectorAll('.probe')).forEach(function(e){
e.parentNode.removeChild(e)
});
for (var i = 1; i <= ballCount; i++) {
balls[i].checkCollision();
balls[i].move();
}
}
Ball.prototype.move = function () {
this.x += this.xSpeed;
this.y += this.ySpeed;
this.movesSinceCollision++;
$('#' + this.id)[0].setAttributeNS(null, "cx", this.x);
$('#' + this.id)[0].setAttributeNS(null, "cy", this.y);
};
Ball.prototype.checkCollision = function () {
var xE = this.x + ballSize + 4;
var xxE = this.x + Math.pow((ballSize*ballSize/2), 0.5);
var xW = this.x - ballSize - 4;
var xxW = this.x - Math.pow((ballSize*ballSize/2), 0.5);
var yN = this.y - ballSize - 4;
var yyN = this.y - Math.pow((ballSize*ballSize/2), 0.5);
var yS = this.y + ballSize + 4;
var yyS = this.y + Math.pow((ballSize*ballSize/2), 0.5);
var collidingBallIndex;
var probe = {
e: {
x: xE,
y: this.y
},
w: {
x: xW,
y: this.y
},
n: {
x: this.x,
y: yN
},
s: {
x: this.x,
y: yS
},
ne: {
x: xxE + 2,
y: yyN - 2
},
se: {
x: xxE + 2,
y: yyS + 2
},
nw: {
x: xxW - 2,
y: yyN - 2
},
sw: {
x: xxW - 2,
y: yyS + 2
}
};
if (!isAt(probe.e.x, probe.e.y, 'box')) {
this.xSpeed = -Math.abs(this.xSpeed);
//this.afterCollision(probe.e);
} else if (!isAt(probe.w.x, probe.w.y, 'box')) {
this.xSpeed = Math.abs(this.xSpeed);
//this.afterCollision(probe.w);
} else if (!isAt(probe.n.x, probe.n.y, 'box')) {
this.ySpeed = Math.abs(this.ySpeed);
//this.afterCollision(probe.n);
} else if (!isAt(probe.s.x, probe.s.y, 'box', 's')) {
this.ySpeed = -Math.abs(this.ySpeed);
//this.afterCollision(probe.s);
} else if (!isAt(probe.ne.x, probe.ne.y, 'box')) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
//this.afterCollision(probe.ne);
} else if (!isAt(probe.se.x, probe.se.y, 'box', 'se')) {
this.xSpeed = -Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
//this.afterCollision(probe.se);
} else if (!isAt(probe.nw.x, probe.nw.y, 'box')) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = Math.abs(this.ySpeed);
//this.afterCollision(probe.nw);
} else if (!isAt(probe.sw.x, probe.sw.y, 'box')) {
this.xSpeed = Math.abs(this.xSpeed);
this.ySpeed = -Math.abs(this.ySpeed);
//this.afterCollision(probe.sw);
}
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);
}
Object.keys(probe).forEach(function(e) {
//console.log(probe[e]);
//point(e, probe[e].x, probe[e].y);
});
};
function classAtContains(x, y, str) {
var elem = document.elementFromPoint(x, y);
//console.log(x, y, elem, elem && elem.className.baseValue)
return elem && elem.className.baseValue && (elem.className.baseValue.indexOf(str) > -1);
}
function isAt(x, y, id, check) {
var elem = document.elementFromPoint(x+8, y+8);
if (check) {
//debugger;
//console.log(check, x, y, elem, elem && elem.id)
}
return elem && elem.id && (elem.id == id);
}
function getOpacityAt(x, y) {
//return map[(Math.round(x) + Math.round(y)*300)*4 - 1];
}
function getBlueAt(x, y) {
//return map[(Math.round(x) + Math.round(y)*300)*4 - 2];
}
Ball.prototype.afterCollision = function(probe) {
// blue value is the id
collidingBallIndex = getBlueAt(probe.x, probe.y);
if (balls[collidingBallIndex]) {
balls[collidingBallIndex].color = "#ff" + balls[collidingBallIndex].color.slice(-4);
}
if (!this.movesSinceCollision) {
//console.log('pos:', this.x, this.y);
//console.log(
// Object.keys(probe).filter(
// function(k) {return Number(probe[k])}
// )
//);
}
this.movesSinceCollision = 0;
};
// var canvas = document.getElementById("canvas");
// var ctx = canvas.getContext("2d");
// var size = canvas.width;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment