- Author:
- Mark Tucker
- Twitter:
- @
- GitHub:
- Facebook:
- Google+:
- +
- Reddit:
- /r/
- Pouet:
- Website:
- twitter.com/tuckermark
- Compo:
- classic
- Demo link:
- https://js1k.com/2010-first/demo/283
- Shortlink:
- https://js1k.com/283
- Blog post:
- please update here!
- Bytes:
- 1015
- Chars:
- 1015
- Submission
var a=document,b=a.getElementById("c"),c=b.getContext("2d"),d=1E3,e=100,f=10,h=256,i=Math,j=i.random,k=i.floor,l="fillStyle",m="length",n,o,p,q,r=0,s=[],t=[],v=[],w=0;a.body.setAttribute("style","overflow:hidden;background:#000;");b.width=n=innerWidth;b.height=o=innerHeight;for(p=0;p<e;p++){v[p]=[];s[p]={x:j()*d,y:d*(1+j()/3),a:-i.sqrt(d*f+j()*d*f)}}setInterval(x,33);function y(g,u){for(p=f;p;p--)t[t[m]]={fillStyle:"rgba("+k(h*j())+","+k(h*j())+","+k(h*j())+",.5)",x:g,y:u,c:e*(j()-j()),a:e*(j()-j()),b:e}}function x(){r++;c[l]="rgba(0,0,0,.05)";c.fillRect(0,0,n,o);for(p=t[m]-1;q=t[p];p--){q.a+=.2;q.x+=q.c/30;q.y+=q.a/30;c[l]=q[l];z(q.x,q.y,q.b/20*j());--q.b<0||q.x<0||q.x>d||q.y<0||q.y>d?t.splice(p,1):v[q.x/f|0][q.y/f|0]=r}c[l]="#fff";for(p=s[m]-1;q=s[p];p--)if(q.y>d)q.y--;else{q.a+=.3;q.y+=q.a/30;z(q.x,q.y,1);if(r-v[q.x/f|0][q.y/f|0]<30){s.splice(p,1);y(q.x,q.y)}}}function z(g,u,A){c.beginPath();c.arc(g*n/d,u*o/d,A,0,7,1>0);c.closePath();c.fill()}b.onclick=function(g){w++||y(g.pageX/n*d,g.pageY/o*d)};
- Description
- A game: you have one click to start a chain reaction to destroy all the balls.
- Base64 encoded
dmFyIGE9ZG9jdW1lbnQsYj1hLmdldEVsZW1lbnRCeUlkKCJjIiksYz1iLmdldENvbnRleHQoIjJkIiksZD0xRTMsZT0xMDAsZj0xMCxoPTI1NixpPU1hdGgsaj1pLnJhbmRvbSxrPWkuZmxvb3IsbD0iZmlsbFN0eWxlIixtPSJsZW5ndGgiLG4sbyxwLHEscj0wLHM9W10sdD1bXSx2PVtdLHc9MDthLmJvZHkuc2V0QXR0cmlidXRlKCJzdHlsZSIsIm92ZXJmbG93OmhpZGRlbjtiYWNrZ3JvdW5kOiMwMDA7Iik7Yi53aWR0aD1uPWlubmVyV2lkdGg7Yi5oZWlnaHQ9bz1pbm5lckhlaWdodDtmb3IocD0wO3A8ZTtwKyspe3ZbcF09W107c1twXT17eDpqKCkqZCx5OmQqKDEraigpLzMpLGE6LWkuc3FydChkKmYraigpKmQqZil9fXNldEludGVydmFsKHgsMzMpO2Z1bmN0aW9uIHkoZyx1KXtmb3IocD1mO3A7cC0tKXRbdFttXV09e2ZpbGxTdHlsZToicmdiYSgiK2soaCpqKCkpKyIsIitrKGgqaigpKSsiLCIrayhoKmooKSkrIiwuNSkiLHg6Zyx5OnUsYzplKihqKCktaigpKSxhOmUqKGooKS1qKCkpLGI6ZX19ZnVuY3Rpb24geCgpe3IrKztjW2xdPSJyZ2JhKDAsMCwwLC4wNSkiO2MuZmlsbFJlY3QoMCwwLG4sbyk7Zm9yKHA9dFttXS0xO3E9dFtwXTtwLS0pe3EuYSs9LjI7cS54Kz1xLmMvMzA7cS55Kz1xLmEvMzA7Y1tsXT1xW2xdO3oocS54LHEueSxxLmIvMjAqaigpKTstLXEuYjwwfHxxLng8MHx8cS54PmR8fHEueTwwfHxxLnk+ZD90LnNwbGljZShwLDEpOnZbcS54L2Z8MF1bcS55L2Z8MF09cn1jW2xdPSIjZmZmIjtmb3IocD1zW21dLTE7cT1zW3BdO3AtLSlpZihxLnk+ZClxLnktLTtlbHNle3EuYSs9LjM7cS55Kz1xLmEvMzA7eihxLngscS55LDEpO2lmKHItdltxLngvZnwwXVtxLnkvZnwwXTwzMCl7cy5zcGxpY2UocCwxKTt5KHEueCxxLnkpfX19ZnVuY3Rpb24geihnLHUsQSl7Yy5iZWdpblBhdGgoKTtjLmFyYyhnKm4vZCx1Km8vZCxBLDAsNywxPjApO2MuY2xvc2VQYXRoKCk7Yy5maWxsKCl9Yi5vbmNsaWNrPWZ1bmN0aW9uKGcpe3crK3x8eShnLnBhZ2VYL24qZCxnLnBhZ2VZL28qZCl9Ow==
- Original source
/**
* Compiled with closure:
* java -jar compiler-latest.jar --optimization_level=ADVANCED_OPTIMIZATIONS
*
* After this, there's some whitespace, 0.x's, and other minor details
* to save a few characters.
*
*/
var d = document;
var c = d.getElementById("c");
var g = c.getContext('2d');
// World width/height is 1000, hundred is the number of balls and the
// number of horizontal and vertical buckets we work with (see below),
// and ten is gravity.
var thousand = 1000, hundred = 100, ten = 10, tfs = 256;
var math = Math, random = math.random, floor = math.floor;
var fillStyle = "fillStyle", length = "length";
var w, h;
var iii; // generic loop counter
var it; // generic element
var counter = 0; // number of loop iterations
// by assigning counter to buckets[x][y], we can tell whether a
// shrapnel was recently at the position x, y.
var balls = [], shrapnel = [], buckets = [], shots = 0;
d.body.setAttribute("style", "overflow:hidden;background:#000;")
c.width = w = innerWidth;
c.height = h = innerHeight;
// 100 balls, 100x100 buckets
for (iii = 0; iii < hundred; iii++) {
buckets[iii] = [];
balls[iii] = {
x: random()*thousand,
y: thousand*(1+random()/3),
vy: -math.sqrt(thousand*ten + random()*thousand*ten)
};
}
setInterval(loop, 33);
// add 10 shrapnel
function explode(x, y) {
for (iii = ten; iii; iii--) {
shrapnel[shrapnel[length]] = {
fillStyle: "rgba(" +
floor(tfs*random()) + "," +
floor(tfs*random()) + "," +
floor(tfs*random()) + ",.5)", // random RGB with a=0.5
x: x,
y: y,
vx: hundred*(random() - random()),
vy: hundred*(random() - random()),
life: hundred
};
}
}
function loop() {
counter++;
// blit
g[fillStyle] = "rgba(0,0,0,.05)";
g.fillRect(0, 0, w, h);
// update/draw/remove shrapnel
for (iii = shrapnel[length] - 1; it = shrapnel[iii]; iii--) {
it.vy += .2; // ten/60 => .2
it.x += it.vx/30;
it.y += it.vy/30;
g[fillStyle] = it[fillStyle];
//arc(it.x, it.y, it.life/20);
arc(it.x, it.y, it.life/20*random());
// if (
--it.life < 0 ||
it.x < 0 || it.x > thousand ||
it.y < 0 || it.y > thousand ? // ) {
shrapnel.splice(iii, 1) : // } else {
buckets[it.x/ten|0][it.y/ten|0] = counter; // }
}
//update/draw/remove balls
g[fillStyle] = "#fff";
for (iii = balls[length] - 1; it = balls[iii]; iii--) {
if (it.y > thousand) {
it.y--;
} else {
it.vy += .3; // ten/30 => .3
it.y += it.vy/30;
arc(it.x, it.y, 1);
if (counter - buckets[it.x/ten|0][it.y/ten|0] < 30) {
balls.splice(iii, 1);
explode(it.x, it.y);
//it.y=1e9 ? would need to profile
}
}
}
}
// draw an arc at x, y with radius r
function arc(x, y, r) {
g.beginPath();
g.arc(x*w/thousand, y*h/thousand, r, 0, 7, 1>0);
g.closePath();
g.fill();
}
// click event... explode at location if we haven't fired yet.
c.onclick = function(e) {
if (!shots++) {
explode(e.pageX/w*thousand, e.pageY/h*thousand);
}
}