for(p in a)a[p[b=d=o=0]+(p[6]||'')]=a[p];w=c.width=550;h=c.height=310;M=Math;p=M.abs;R=522;t=63;T=43;V=W=B=282;setInterval(function(){with(a){A=function(c,y,x,r){ba();c>9?stroke(m(c,x),l(y,r)):(strokeStyle=fillStyle='#'+'9000fff3119b'.substr(c,3),c>5?fc(x,x,y,r):f(a(X=x||X,y,G=r||G,0,7,0)))};A(7,w,0,h);A(9,487,32,246);A(1,u,u,18);A(1,v=w/2);A(1,u,q=516);A(1,v);A(1,28,v,O=15);A(1,B);if(!b)for(E=[],x=0;b<o+2&&b<8;++b)x+=t,y=M.random()*h,y=y>B?B-9:y<T?T:y,E[b]={x:x,y:y};for(i=0;i<b-1;++i)r=E[i],p(x-r.x)<O&&p(y-r.y)<O?(o=i?0:o+1,b=d=0):A(i?0:2,r.y-7,r.x-7,8);(x<t||x>q||(x>268&&x<288))&&(y<t||y>274)&&d>0?(b=d=o=0):y>B?N(0,B):y<T?N(0,T):x>R?N(R):x<T?N(T):0;d-=M.max(~~(d/9),.2);A(4,g=y-7,z=x-7);fx(o,v,t);d>0?(K?(x+=F?d:-d,y=k*x+n):(y+=F?d:-d,x=(y-n)/k)):A(C=V-7,z,D=W-7,g,A(4,D,C))}},u=35);function N(s,e){Z=s?(U=I,e=k*s+n,2*e-J):(s=(e-n)/k,U=2*s-I,J);S(x=s,y=e)}function S(){I=x,J=y,k=(y-Z)/(x-U),n=y-k*x,F=(K=p(U-x)>p(Z-y))?U>x:Z>y}onmousemove=function(j){V=j.pageX;W=j.pageY};onmouseup=function(){d<=0&&S(d=u,U=V,Z=W)}
/*
GAME: Tactical 8-ball Pool
--------------------------
Author: Totti Anh Nguyen (http://iamtotti.com)
Controls:
- Move mouse to aim.
- Left mouse click to shoot.
*/
for(p in a) a[p[d = o = V = W = 0]+(p[6]||'')]=a[p];
u=50; // unit
X=w=c.width=667;
h=c.height=377;
v=w/2; // half width (center)
P=v-10;
Q=v+10;
G=8.5;
D=70; // max speed
z='#';
// level : b
M=Math;
p=M.abs;
// Table boundaries
R = 621;
// Left = Top
T = 57;
B = 331;
setInterval(function(){
// we'll need the context a lot
with(a){
A=function(c,x,y,r,_){
ba();
// a is the abbreviated form of arc
a(x,y,r,0,7,0);
(_&&s())||(strokeStyle=fillStyle=z+'900fff000'.substr(c*3,3),f());
};
C=function(c,x,y,w,h){fillStyle=z+c;fc(x,y,w,h)};
Y=function(q,w,e,r,t){ba();m(q,w);l(e,r);l(t,w);s();};
// draw the pool table
C('4c1f22',0, 0, w, h);
C('0e617f',32, 32, 603, 313);
// Table Inner
C('07516c',43, 43, 581, 291);
// Table Shadow
C(r='139ebd',46, 46, 575, 285);
lineWidth=30;
lineJoin="bevel";
strokeStyle = '#'+r;
// Draw top-center gate
Y(P,t=67,v,37,Q);
// Draw bottom-center gate
Y(P,306,v,343,Q);
// Draw top-left gates
Y(61,64,35,35,t);
// Draw bottom-left gates
Y(61,313,35,341,70);
// Draw top-right gates
Y(600,62,631,37,607);
// Draw bottom-right gates
Y(601,313,631,341,606);
// Draw holes
H = 18;
// Two on the left
A(2,35,35,H);
A(2,35,342,H);
// Two on the right
A(2,632,35, H);
A(2,632,342, H);
// Two in the middle
O=14.5;
A(2,v, 28, O);
A(2,v, 349, O);
// Draw Score
font = "90px Arial";
fillStyle = g = "rgba(0,0,0,0.5)";
fx(o, v, h/2);
if(X){
X = 0;
// Init E balls
for (E = [], x=b=0; b < 9 && b < o+2; ++b) {
x += 60;
y = M.random()*x + 20;
y=y>B?B-9:y<T?T+9:y;
x=x>R?R-9:x<T?T+9:x;
E.push({x:x,y:y});
}
}
else {
// Falling to Holes detection
if ((x < t || x > 611 || (x > P && x < Q+6)) && (y < t || y > 321))
X = 1,
d = o = 0;
// Ball collision detection
for(i = 0; i < b-1; ++i) {
r = E[i];
// (x > r.x - 13) && (x < r.x + 13) && (y > r.y - 13) && (y < r.y + 13)){
if (p(x-r.x) < 13 && p(y-r.y) < 13){
o = i ? 0 : o+1;
X = 1;
d = 0;
}
// Draw E ball
A(i ? 2 : 0, r.x-6, r.y-6, G);
}
}
// ~~ Math.floor
d -= M.max(~~(d/10), .2);
// Draw white ball
A(1, x-6, y-6, X ? 7 : G);
// If balls moving
if (d > 0) {
// Draw running balls
if (K)
x += F ? d : -d,
y = k * x + n;
else
y += F ? d : -d,
x = (y - n) / k;
// Check boundaries
// Bottom
if (y > B) N(0,B);
// Top
else if (y < T) N(0,T);
// Right
else if (x > R) N(R);
// Left
else if (x < T) N(T);
}
else
// Draw the aiming lines to shot
if (V > T && V < R &&
W > T && W < B)
lineWidth=1,
// Expected ball
fillStyle = g,
A(3, V-6, W-6, G, 1),
// Direction line
m(V-6, W-6),
l(x-6, y-6),
s();
}
}, u);
/**
* Reflect ball against wall
*/
function N(i,j){
// Update line scope
// Reflection happens
// Reset starting position
Z = i ? (U=I, j = k*i + n, 2*j - J) : (i = (j - n) / k, U = 2*i - I, J);
S(I = x = i, J = y = j);
}
function S(x, y) {
// Figure out where to go ?
k = (y - Z) / (x - U);
n = y - k*x;
F = (K = p(U-x) > p(Z-y)) ? U > x : Z > y;
}
onmouseup=function(e){
if (d <= 0)
// Power
d = e.altKey ? D : D/2,
// Target
U = e.pageX,
Z = e.pageY,
// Compute line scope
S(I = x, J = y);
}
// Track mouse position when aiming
onmousemove=function(e){
V = e.pageX;
W = e.pageY;
}