|
// Compresses down to ~1006b without the debug output |
|
// The "noise" function, "_", will be the minified source code. |
|
// The road is basically an helix with varying radius, angle, and width |
|
// The collision detecion & co can all be done in polar coordinates. |
|
|
|
H=96; |
|
z=n=S=f=v=0; |
|
// Offset in the "noise" function to get different roads |
|
F=Date.now()>>9; |
|
|
|
// Precalculate the colors |
|
// Setting a #hex fillStyle is much faster than rgb() or hsl() |
|
for(i=444;--i;){ |
|
a[i]='#'; |
|
for(j=4;--j;) { |
|
a[i]+=Math.min(255,16+(i*5>>j)).toString(16); |
|
} |
|
} |
|
|
|
// Test gradient for the title/end screen |
|
g=c.createLinearGradient(0,0,0,8); |
|
g.addColorStop(0,a[96]); |
|
g.addColorStop(1,a[24]); |
|
|
|
// Controls |
|
onclick=function(x){ |
|
f=1/4-x.clientX/innerWidth/2; |
|
}; |
|
onkeydown=function(x){ |
|
x=38-x.keyCode; |
|
if(x*x==1)f=x/8; |
|
}; |
|
|
|
// Main |
|
(down=function(x){ |
|
a.height=444; |
|
a.width=444*innerWidth/innerHeight; |
|
requestAnimationFrame(down); |
|
|
|
f /= 2; |
|
n += f; |
|
// Compute the components of the road |
|
z+=444.5; |
|
for(i=444;--i;){ |
|
z--; |
|
for(j=4;--j;) { |
|
s = z / (32+j*37); |
|
t=(_.charCodeAt(s+F&1023)%(12-j*3))*(s++>=j*4); |
|
u=(_.charCodeAt(s+F&1023)%(12-j*3))*(s++>=j*4); |
|
// smoothstep 5th = x*x*x*(x*(x*6-15)+10); |
|
s%=1; |
|
c[j]=t+(u-t)*s*s*s*(s*(s*6-15)+10); |
|
} |
|
|
|
// Draw the road slice in 'i' |
|
L=444/i; |
|
R=c[1]*3; |
|
|
|
x=c[2]/2-n; |
|
c.setTransform(Math.cos(x),Math.sin(x),-Math.sin(x),Math.cos(x),a.width/2-L*10*Math.sin(x),160+L*10*Math.cos(x)); |
|
|
|
s=L*8-L*c[3]*2; |
|
t=L/(2+i/160); |
|
// Draw the road slice in 'i' |
|
c.fillStyle = a[i]; |
|
if (z&511) { |
|
c.fillRect(-s,L*H-L*R-t,s*2,t*2); |
|
u=s/9; |
|
s*=z&4?.3:.6; |
|
t++; |
|
} else { |
|
u=c.fillText(z>>9,s,L*H-L*R-t); |
|
} |
|
c.fillStyle = '#fff'; |
|
c.fillRect(-u,L*H-L*R-t,-s,t*2); |
|
c.fillRect(u,L*H-L*R-t,s,t*2); |
|
|
|
// the road slice where the vessel "sits" |
|
if(i==24) { |
|
q = H + v; |
|
// collision detection to stick the vessel to the road and |
|
// adjust its velocity |
|
if (q < R & q > (R - 2) & x*x < 2 - c[3]/2) { |
|
q = R; |
|
S = z >> 9; |
|
} |
|
v = (q > H ? (q - H) * 1.07 : v) - .07; |
|
v = v < -.5 ? -.5 : v;// > 1 ? 1 :v; |
|
} |
|
} |
|
|
|
x=L=0; |
|
c.setTransform(Math.cos(x),Math.sin(x),-Math.sin(x),Math.cos(x),a.width/2-L*10*Math.sin(x),160+L*10*Math.cos(x)); |
|
|
|
// Score |
|
c.fillStyle=g; |
|
c.fillText(S||'IMPOSSIBLE',0,0); |
|
c.textAlign='center'; |
|
c.scale(8,8); |
|
//c.font='96px sans-serif'; |
|
H=q; |
|
if(q<-48){ |
|
// Game over |
|
c.fillText('AGAIN?',0,8); |
|
} else if (S==0) { |
|
// Game on |
|
c.fillText('ROAD',0,8); |
|
} |
|
|
|
// Draw the vessel |
|
c.fillStyle='#fff'; |
|
c.shadowColor=a[96]; |
|
c.shadowBlur=16; |
|
c.arc(Math.random()*(q<0),16+Math.random()*(q<0),6+q/16,0,16,0); |
|
c.fill(); |
|
|
|
})() |