- 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);
    }
}