I gave JavaScript objects an identity. They are flies. They live; they reproduce; they die. Sit back and watch them evolve based on the rules of their world, or take a more active role in their evolut…
var w=500,j,k,M=Math,a=[],F="#ff88",v=document.body.childNodes[1];v.width=v.height=w;c=v.getContext("2d");v.onmousedown=function(A){j=A.clientX;k=A.clientY};for(i=0;i<16;)a[i++]=new z(p(32),p(232),p(32),2*o(),16*o()+16);setInterval(function d(){g=c.createLinearGradient(0,0,0,w);g.addColorStop(0,F+32);g.addColorStop(1,F+96);c.fillStyle=g;c.fillRect(0,0,w,w);for(i in a){u=a[i];e=u.e;y=u.y;x=u.x;if(!u.A||j>x&&j<x+e&&k>y&&k<y+e||u.a>u.q)u.A=0,u.y+=9;else m(x,u.h,e),x=P,m(y,u.h,e),y=P;c.fillStyle="rgb("+u.r+","+u.g+","+u.b+")";c.fillRect(x,y,e,e);if(y>w)f(),s=a[S],a[i]=new z(p(s.r),p(s.g),p(s.b),l(s.h+n()*o()),l(s.e+n()*o()));u.a++}j=k=0},32);function z(R,G,B,H,E){Q=this;Q.r=R;Q.g=G;Q.b=B;Q.h=H;Q.e=E;Q.a=0;Q.q=999-E*H;Q.A=1;Q.x=o()*w;Q.y=o()*w;Q.s=E*9}function f(){L=-255;for(I in a){U=a[I],Z=U.s+U.a*U.A;if(Z>L)S=I;L=Z}}function p(A){A=~~l(A+n()*o()*32);return A>255?255:A}function m(A,B,C){P=l(A+n()*o()*B);P=P>w-C?w-C:P}function o(){return M.random()}function n(){return o()>0.5?-1:1}function l(A){return M.abs(A)};
dmFyIHc9NTAwLGosayxNPU1hdGgsYT1bXSxGPSIjZmY4OCIsdj1kb2N1bWVudC5ib2R5LmNoaWxkTm9kZXNbMV07di53aWR0aD12LmhlaWdodD13O2M9di5nZXRDb250ZXh0KCIyZCIpO3Yub25tb3VzZWRvd249ZnVuY3Rpb24oQSl7aj1BLmNsaWVudFg7az1BLmNsaWVudFl9O2ZvcihpPTA7aTwxNjspYVtpKytdPW5ldyB6KHAoMzIpLHAoMjMyKSxwKDMyKSwyKm8oKSwxNipvKCkrMTYpO3NldEludGVydmFsKGZ1bmN0aW9uIGQoKXtnPWMuY3JlYXRlTGluZWFyR3JhZGllbnQoMCwwLDAsdyk7Zy5hZGRDb2xvclN0b3AoMCxGKzMyKTtnLmFkZENvbG9yU3RvcCgxLEYrOTYpO2MuZmlsbFN0eWxlPWc7Yy5maWxsUmVjdCgwLDAsdyx3KTtmb3IoaSBpbiBhKXt1PWFbaV07ZT11LmU7eT11Lnk7eD11Lng7aWYoIXUuQXx8aj54JiZqPHgrZSYmaz55JiZrPHkrZXx8dS5hPnUucSl1LkE9MCx1LnkrPTk7ZWxzZSBtKHgsdS5oLGUpLHg9UCxtKHksdS5oLGUpLHk9UDtjLmZpbGxTdHlsZT0icmdiKCIrdS5yKyIsIit1LmcrIiwiK3UuYisiKSI7Yy5maWxsUmVjdCh4LHksZSxlKTtpZih5PncpZigpLHM9YVtTXSxhW2ldPW5ldyB6KHAocy5yKSxwKHMuZykscChzLmIpLGwocy5oK24oKSpvKCkpLGwocy5lK24oKSpvKCkpKTt1LmErK31qPWs9MH0sMzIpO2Z1bmN0aW9uIHooUixHLEIsSCxFKXtRPXRoaXM7US5yPVI7US5nPUc7US5iPUI7US5oPUg7US5lPUU7US5hPTA7US5xPTk5OS1FKkg7US5BPTE7US54PW8oKSp3O1EueT1vKCkqdztRLnM9RSo5fWZ1bmN0aW9uIGYoKXtMPS0yNTU7Zm9yKEkgaW4gYSl7VT1hW0ldLFo9VS5zK1UuYSpVLkE7aWYoWj5MKVM9STtMPVp9fWZ1bmN0aW9uIHAoQSl7QT1+fmwoQStuKCkqbygpKjMyKTtyZXR1cm4gQT4yNTU/MjU1OkF9ZnVuY3Rpb24gbShBLEIsQyl7UD1sKEErbigpKm8oKSpCKTtQPVA+dy1DP3ctQzpQfWZ1bmN0aW9uIG8oKXtyZXR1cm4gTS5yYW5kb20oKX1mdW5jdGlvbiBuKCl7cmV0dXJuIG8oKT4wLjU/LTE6MX1mdW5jdGlvbiBsKEEpe3JldHVybiBNLmFicyhBKX07
// --------------------------------
// Created by William Malone
//
// More details at wmalone.com/js1k
// --------------------------------
var w = 500, // Canvas width and height
j, k, // Click x,y
M = Math, // Math Object
a = [], // Fly array
F = "#ff88",
// Do canvas things
v = document.body.childNodes[0]; // Get canvas
v.width = v.height = w; // Set canvas dimensions
c = v.getContext("2d"); // Get context
// Click events
v.onmousedown = function(A) {
j = A.clientX; // Click X Position
k = A.clientY // Click Y Position
}
// Create the first flies
for(i=0;i<16;) a[i++]=new z(p(32), p(232), p(32), 2*o(), 16*o()+16)
// ---------------------------- Redraw
setInterval(
// Redraw function
function d() {
// Draw background gradient
g = c.createLinearGradient(0, 0, 0, w);
g.addColorStop(0, F+32);
g.addColorStop(1, F+96);
c.fillStyle = g;
c.fillRect(0, 0, w, w)
// For each fly
for(i in a) {
u = a[i];
e = u.e;
y = u.y;
x = u.x;
// Check if the fly died
if(!u.A || j > x && j < x + e && k > y && k < y + e || u.a > u.q)
u.A=0, // Mark fly as dead
u.y += 9 // Fly begins to drop
else m(x,u.h,e),x=P, // Move fly x position
m(y,u.h,e),y=P;// Move fly y position
// Draw fly
c.fillStyle = "rgb(" + u.r + "," + u.g + "," + u.b + ")";
c.fillRect(x, y, e, e) // Draw the fly
// The fly has dropped entirely off the canvas
if(y > w) // Delete fly
f(),
s = a[S], // Choose fly to reproduce
a[i] = new z(p(s.r), p(s.g), p(s.b), l(s.h + n() * o()), l(s.e + n() * o()));
u.a++ // Age the fly
}
j = k = 0 // Clear mouse click location
}
,32) // Redraw frequency aka one fly year (in milliseconds)
// ---------------------------- Fly Reproduction
// Create a new fly
function z(R, G, B, H, E) {
Q=this;
Q.r = R; // Red
Q.g = G; // Green
Q.b = B; // Blue
Q.h = H; // Vibration Amount
Q.e = E; // Size
Q.a = 0; // Age
Q.q = 999 - E*H; // Maximum Age (Vibration and Size take energy which shortens lifetime)
Q.A = 1; // Alive Boolean
Q.x = o() * w; // X Position
Q.y = o() * w; // Y Position
Q.s = E*9 // Macheesmo (probability of reproducing)
}
// Update a global index of the fly that gets to reproduce
function f() {
L=-255 // Largest macheesmo
for(I in a) { // For each fly
U=a[I],
Z=U.s + U.a*U.A // Calculate the probability of reproduction
if(Z > L) // If it is bigger than all the other flies
S=I; // Update the index of the lucky fly
L=Z // Update a 'local' variable
}
}
// ---------------------------- Mutation
// Returns a color randomly changed
function p(A) {
A = ~~l(A + n() * o() * 32) // Move the color component randomly up or down
return A > 255 ? 255 : A // Ensure the color is with the rgb of range 0-255
}
// Updates a global to new random position within the boundries of the canvas
function m(A,B,C){
P = l(A + n() * o() * B); // Move position in a random amount (up to vibrate amount)
P = P > w - C ? w - C : P // Ensure position is on the canvas
}
// ---------------------------- Math
// Return random number
function o() {
return M.random() // Return random decimal 0.0 to 1.0
}
// Returns positive or negative
function n() {
return o() > .5 ? -1 : 1 // Randomly return -1 or 1
}
// Return absolue value of parameter
function l(A) {
return M.abs(A) // Return the absolute value of parameter
}