Source for demo by Hayato Araki. See also description.
function P(b,e){c[e?'stroke':'fill'](c.arc(b[0]+=(b[0]>W?-W:b[0]<0?W:0)+b[3],b[1]+=(b[1]>H?-H:b[1]<0?H:0)+b[4],b[5],e?0:b[2]-2,e?6.3:b[2]+2,c.beginPath()))}function T(b,e){return M.sqrt(M.pow(b[0]-a[0],2)+M.pow(b[1]-a[1],2))<a[5]+b[5]}function L(){c.clearRect(0,0,W,H);i=u?.2:d?-.08:0;p[3]=p[3]*.986+X(t=p[2]+=l?-.12:r?.12:0)*i;p[4]=p[4]*.986+Y(t)*i;P(p);for(i=7;i--;x|=T(p)){P(a=A[i]=A[i]||[p[0]+W/4+R()*W/2,p[1]+H/4+R()*H/2,t=R()*6.3,X(t),Y(t),R()*40+20],1);for(n in G)T(g=G[n])?s+=g[6]|G.splice(n,1)|A.splice(i,1):i?0:--g[6]?P(g):G.shift()}c.fillText("Score: "+s,5,14);x?alert("GameOver"):setTimeout(L,17)}L(D=document,C=D.body.children[0],C.style.position='fixed',C.width=W=innerWidth,C.height=H=innerHeight,c=C.getContext('2d'),M=Math,R=M.random,X=M.cos,Y=M.sin,p=[W/2,H/2,0,0,0,10],A=[],G=[],a=g=l=u=r=d=z=i=n=t=x=s=0,D.onkeyup=K=function(b,e){t=b.keyCode-32;t?t-5?t-6?t-7?t-8?0:d=e:r=e:u=e:l=e:z=z|!e?e:G.push([p[0],p[1],t=p[2],p[3]+X(t)*14,p[4]+Y(t)*14,4,30])},D.onkeypress=D.onkeydown=function(b){K(b,1);return!1})