JS1K

#2: the original

Source description for demo by Romain Huet.

/** * Labyrinth Game for JS1k.com * Romain Huet - @romainhuet * Website: <http://romainhuet.com/> * Twitter: <http://twitter.com/romainhuet> */ d = document; b = d.body; e = b.children[0]; c = e.getContext('2d'); w = 640; h = 480; r = 8; t = w - 2*r; x = w/2; y = h/2 - 2*r; X = Y = dx = dy = O = s = 0; N = 25; a = []; // Canvas dimensions e.width = w; e.height = h; cx = outerWidth/2; cy = 30 + h/2 - r; // CSS styles b.s = b.style; e.s = e.style; b.s.padding = '30px'; b.s.textAlign = 'center'; e.s.border = r + 'px solid #eee'; // Methods shortcuts c.f = c.fillRect; d.c = d.createElement; M = Math; R = M.random; P = M.pow; S = M.sqrt; MA = M.max; MI = M.min; // Score paragraph p = d.c('p'); p.innerHTML = 'Score: 0'; b.appendChild(p); // Capture cursor position d.onmousemove = function(e) { X = e.clientX; Y = e.clientY; dx = (X - cx) / N; dy = (Y - cy) / N; }; // Draw a disc (ball, hole, or coin) function D(x, y, r, t) { c.beginPath(); c.fillStyle = '#' + '67f555fa1'.substr(3*t, 3); c.arc(x, y, r, 0, 2*M.PI, true); c.fill(); } // Display the whole game I = setInterval(function() { // Game c.fillStyle = '#ded'; c.f(0, 0, w, h); // Holes for (i = 0; i < N; i++) { // Hole or coin k = i == N - 1; // Generate position if (!a[i]) { a[i] = [w*R(), h*R(), k ? 6 : r*(1 + R())]; } v = a[i]; j = S(P(v[0] - x, 2) + P(v[1] - y, 2)); // Display D(v[0], v[1], v[2], k ? 2 : 1); // Check point or drop if (k && j <= v[2] + r) { p.innerHTML = 'Score: ' + ++s; a[i] = null; } else if (j <= v[2]) { O = 1; } } // Display ball if (!O) { D(x = MA(r, MI(w - r, x - dx)), y = MA(r, MI(h - 2*r, y - dy)), r, 0); } // Display timer c.fillStyle = '#e64'; c.f(0, h - r, w, r); c.fillStyle = '#eba'; c.f(t, h - r, w - t, r); // Game over? if ((t -= 0.5) < 0 || O) { clearInterval(I); } }, N);