A mix between brick breaker and pinball, featuring super cool animated bumpers! Use L and R arrow keys to play. Actually any key will work for L! (its not a bug its a code-reducing "feature") The game…
var M=Math,d=document,c=d.body.children.c,C=c.getContext("2d"),K="F0970007fff7F117FF170A1701D".split(7),Q=J=$=0,X=2,P=Y=y=x=14,q=99,o=22,n=38,L,U,E,T;function a(c,l,t,W,H){if(!W){J++;Q++;Y*=1.05;X*=1.1;i=-1;u=[];while(++i<o*n)M.random()*.51>.5?u.push([i%n*w,~~(i/o)*9]):0;d=i=u.length;}else{C.beginPath();C.fillStyle="#"+K[c%7];H?C.rect(l,t,W,H):C.arc(l,t,W,0,M.PI*2,1);C.closePath();C.fill()}}c.ontouchmove=d.onkeydown=d.onkeyup=function(e,c){U=e.keyCode%39;(c=e.touches)?z=c[0].pageX:L=!U;return e.type=="keyup"?U=L=0:!c};c.width=W=480;H=600;c.height=H+q;z=W/2;w=W/n;setInterval(function(j){a(J,0,0,W,H);a(J+1,x,y,P);C.font="50px Arial";C.fillText([J,Q-1,$],o,H-$%H-9);z+=L?9+J/2:U?-(9+J/2):0;a(J+1,z,H-P,q,P);T=x+X;E=y+Y;B=E+P;i=d;while(--i){j=(u[i][0]+=M.abs(M.log(i/J)))%W;A=++u[i][1]%320;a(i,j,A,11);if(x>j-P&&x<j+P&&y>A-P&&y<A+P){Y=-Y;$++;if($%o>o-2)a()}}if(T+P>W||T-P<0)X=-X;if(E-P<0)Y=-Y;else if(B>H)if(x>z-8&&x<z+q+8){X=9*((x-(z+q/2))/q);y=H-9;Y=-Y}else if(B>H){Y=P;z=W/2;y=0;if(--Q<1)J=Q=$=X=1}x+=X;y+=Y},o);a()
dmFyIE09TWF0aCxkPWRvY3VtZW50LGM9ZC5ib2R5LmNoaWxkcmVuLmMsQz1jLmdldENvbnRleHQoIjJkIiksSz0iRjA5NzAwMDdmZmY3RjExN0ZGMTcwQTE3MDFEIi5zcGxpdCg3KSxRPUo9JD0wLFg9MixQPVk9eT14PTE0LHE9OTksbz0yMixuPTM4LEwsVSxFLFQ7ZnVuY3Rpb24gYShjLGwsdCxXLEgpe2lmKCFXKXtKKys7USsrO1kqPTEuMDU7WCo9MS4xO2k9LTE7dT1bXTt3aGlsZSgrK2k8bypuKU0ucmFuZG9tKCkqLjUxPi41P3UucHVzaChbaSVuKncsfn4oaS9vKSo5XSk6MDtkPWk9dS5sZW5ndGg7fWVsc2V7Qy5iZWdpblBhdGgoKTtDLmZpbGxTdHlsZT0iIyIrS1tjJTddO0g/Qy5yZWN0KGwsdCxXLEgpOkMuYXJjKGwsdCxXLDAsTS5QSSoyLDEpO0MuY2xvc2VQYXRoKCk7Qy5maWxsKCl9fWMub250b3VjaG1vdmU9ZC5vbmtleWRvd249ZC5vbmtleXVwPWZ1bmN0aW9uKGUsYyl7VT1lLmtleUNvZGUlMzk7KGM9ZS50b3VjaGVzKT96PWNbMF0ucGFnZVg6TD0hVTtyZXR1cm4gZS50eXBlPT0ia2V5dXAiP1U9TD0wOiFjfTtjLndpZHRoPVc9NDgwO0g9NjAwO2MuaGVpZ2h0PUgrcTt6PVcvMjt3PVcvbjtzZXRJbnRlcnZhbChmdW5jdGlvbihqKXthKEosMCwwLFcsSCk7YShKKzEseCx5LFApO0MuZm9udD0iNTBweCBBcmlhbCI7Qy5maWxsVGV4dChbSixRLTEsJF0sbyxILSQlSC05KTt6Kz1MPzkrSi8yOlU/LSg5K0ovMik6MDthKEorMSx6LEgtUCxxLFApO1Q9eCtYO0U9eStZO0I9RStQO2k9ZDt3aGlsZSgtLWkpe2o9KHVbaV1bMF0rPU0uYWJzKE0ubG9nKGkvSikpKSVXO0E9Kyt1W2ldWzFdJTMyMDthKGksaixBLDExKTtpZih4PmotUCYmeDxqK1AmJnk+QS1QJiZ5PEErUCl7WT0tWTskKys7aWYoJCVvPm8tMilhKCl9fWlmKFQrUD5XfHxULVA8MClYPS1YO2lmKEUtUDwwKVk9LVk7ZWxzZSBpZihCPkgpaWYoeD56LTgmJng8eitxKzgpe1g9OSooKHgtKHorcS8yKSkvcSk7eT1ILTk7WT0tWX1lbHNlIGlmKEI+SCl7WT1QO3o9Vy8yO3k9MDtpZigtLVE8MSlKPVE9JD1YPTF9eCs9WDt5Kz1ZfSxvKTthKCkJCQ==
// Creative Commons CC by SA
var M = Math,
d = document,
c = d.body.children.c,
C = c.getContext("2d"),
K = "F0970007fff7F117FF170A1701D".split(7), // some colors
Q = J = $ = 0, // lives level, score
X = 2, // ball x-speed
P = Y = y = x = 14, // padding / paddle height, ball y-speed, x and y positions of ball
q = 99, // paddle width
o = 22, // bumper rows
n = 38, // bumper colls
L,U,E,T;
// functions are combined to save chars
function a(c,l,t,W,H) {
// Setup a new level
if(!W) {
J++; // increment level
Q++; // reward with 1up
Y*=1.05; // speed up just a little
X*=1.1; // speed up just a little
i = -1; // current pin
u = []; // our array of bumpers
// store an array of [x,y] array objects representing pixel positions of bumpers
// in the push - i%n gives us our col, * w give our x; ~~(i/o) gives our row (~~ is bitwise floor), * 9 gives our y
while(++i<o*n) M.random()*.51 >.5 ? u.push([i%n * w, ~~(i/o) * 9]) : 0;
d=i=u.length;
// draw a shape
} else {
C.beginPath();
C.fillStyle = "#"+K[c%7];
H ? C.rect(l,t,W,H) : C.arc(l, t, W, 0, M.PI*2, 1);
C.closePath();
C.fill()
}
}
// move the paddle on key press or swipe on touch uis
c.ontouchmove = d.onkeydown = d.onkeyup = function(e,c) {
// on any key press set U to 0 (falsy) if L is depressed or set it to a positive int (any key is the left key)
U=e.keyCode%39;
// if touch ui use that, if not set L ( !U returns true if U is set to 0 and false for the positive ints)
(c = e.touches) ? z = c[0].pageX : L=!U;
//on keyup set both U and L to 0 so the paddle stops moving,
//if no keyup return !c (returns false if there are touch events) becasue thouch events need to be blocked after here esp for android
return e.type == "keyup" ? U=L=0 : !c
};
c.width = W = 480; // render area width
H = 600; // render area height
c.height = H+q; // need the extra room below render area to handle touch eventswithout covering up the paddle
z = W/2; // bumper start position
w = W/n; // column width
// main loop
setInterval(function(j) {
// background
a(J,0,0,W,H);
// draw the ball
a(J+1, x, y, P);
// draw the score
C.font = "50px Arial";
C.fillText([J,Q-1,$], o, H-$%H-9); // H-$%H == y pixel value, text climbs up as score increases and then wraps back to the bottom
// position and render the paddle
z += L ? 9+J/2 : U ? -(9+J/2) : 0;
a(J+1, z, H-P, q, P);
T = x+X;
E = y+Y;
B = E+P;
// hit a bumper
i=d;
while(--i) {
// modify the x positon of the bumper for animation, use log for a cool effect,
// %W to wrap across, abs to keep things positive for higer levels
j=(u[i][0]+=M.abs(M.log(i/J)))%W;
// modifiy the y position slightly for animation, %320 to wrap vertically
A=++u[i][1]%320;
// draw the bumper
a(i, j, A, 11);
// bumper hit test
if(x>j-P && x<j+P && y>A-P && y<A+P) {
Y = -Y; // change direction
$++; // score!
if($%o > o-2) a() // level up! rebuild gameboard for increasing score;
}
}
// bounce off the sides
if(T + P > W || T - P < 0) X = -X;
if (E - P < 0)
// bounce off the top
Y = -Y
else if (B > H)
if (x > z-8 && x < z + q+8) {
//move the ball differently based on where it hit the paddle
X = 9 * ((x-(z+q/2))/q);
y = H-9;
Y = -Y
} else if (B > H) {
// ball hit bottom, loose a life
Y=P;
z=W/2; // reset the ball and paddle
y=0; // ball stop on bottom and depleates score
// no more lives, loose game/start over
if(--Q<1)J=Q=$=X=1
}
x += X;
y += Y
}, o);
// generate level 1
a()