Continuously renders a procedurally generated terrain. The terrain is originally from a game created I helped create for #EnterTheMUD jam.
for(_='Math.YYmax(X.5W=W-V]],Um[sT&&(,1)=1*t,t(a,rn,.+.6*c.fill);25for()=>=Yabs(0"#:t<=-=0;(2&a?-2:2)M===-W7735027, Style=;return),>=0t+=**4*A(m[b+.211324865var ,Rect(639,B-l.h,1,20)r,l,e=4AF",h=2604",v=DDA",f=07D",m=[...Array(512)].map=>~~(6*Yrandom())n=,e{le--;)l+=M,rt*=2 l},A=(&=7)<=4[r]=[t,r](1&a?-r:r+)M={l=.3660403*+re=~~+lh=~~(r+lv=*(e+hf=a-(e-vB=r-(h-vn=f>B,M=f-n+,i=B-!n+,o=f F=B b=5&e,s=5&h;tuVf*f-B*B;uuTUf,B)yVM*M-i*i;yyn+T+!nUM,i)DVo*o-F*F DD1+T+1Uo,F)40},i={a/=4,r/=4;l0,4))**2W,B4)**2+.2*l,m=.8*l+.2*16,2A=005,3t+.4*040216,1t*=l+.3+W*n(r,a,.16,1M=(t-00**001)>8?FFF":t>2?666"4?f1W?e:A>.6||A>.1&&m<0?h1.2?v:B<.0||l<.005?e:m>1?AB5":5A4"{t:M,h:h?t+5:e||f||v?1:X1,2)}},osetInterval(t=>{o++,c.drawImage,-1,0BB++<340;){l=i(o,4*Ber0;r<=40;r+0)e=Xi(o+r,4*B+r).hl.t,l.h<e"rgba(0,0,0,"+e/50+")")}},10';G=/[-T-Y]/.exec(_);)with(_.split(G))_=join(shift());eval(_)
Zm9yKF89J01hdGguWVltYXgoWC41Vz1XLVZdXSxVbVtzVCYmKB8sMSkePTEdKnQcLHQbKGEaGixyGW4ZLC4YHisuNioYF2MuZmlsbBYpOxUyNRRmb3IoEyk9PhI9WWFicygYMBEiIxA6dDw9LQ89MDsOKDImYT8tMjoyKQxNPT09Cy1XNzczNTAyNywJFlN0eWxlPQg7cmV0dXJuByksBj49MB90Kz0FKio0KkEobVtiKwQuMjExMzI0ODY1A3ZhciACLBZSZWN0KDYzOSxCLWwuaCwxLDIwKQECchssbCxlPRA0QUYiLGg9EDI2MDQiLHY9EEREQSIsZj0QMDdEIixtPVsuLi5BcnJheSg1MTIpXS5tYXAaPT5+figUNipZcmFuZG9tKCkpBm49GRssZRJ7E2wOZS0tOylsKz1NGhwschwGdCo9MgcgbH0sQT0ZGxIoGiY9Nyk8PTQfW3IbXT1bdCxyXQYoMSZhPwwtcjpyKwwpHAZNPRkSewJsPS4zNjYwFDQwMyoaK3IGZT1+fhorbAZoPX5+KHIrbAZ2PQMqKGUraAZmPWEtKGUtdgZCPXItKGgtdgZuPWY+QixNPWYtbisDLGk9Qi0hbisDLG89ZglGPUIJYj0UNSZlLHM9FDUmaDt0DgJ1VmYqZi1CKkI7dQV1BFRVZixCKRUCeVZNKk0taSppO3kFeQRuK1QrIW5VTSxpKRUCRFZvKm8tRipGByBEBUQEMStUKzFVbyxGKQY0MBx9LGk9GRJ7YS89NCxyLz00OwJsETAULDQpKSoqMlcsQhE0HikqKjIrLjIqbCxtPS44KmwrLjIqGDE2LDIGQT0YMDA1LDMVdB0rLjQqGDA0FzAyFzE2LDEGdCo9bBsrHS4zK1cqbihyLGEsLjE2LDEVAk09KHQtHTAwKioYMDAxHik+OD8QRkZGIjp0PjI/EDY2NiIPND9mDzFXP2U6QT4uNnx8QT4uMSYmbTwwP2gPMS4yP3Y6QjwuMBR8fGw8LjAwNT9lOm0+MT8QQUI1IjoQNUE0Igd7dDpNLGg6C2g/dCs1OgtlfHwLZnx8C3Y/MTpYMSwyHCl9fSxvDnNldEludGVydmFsKHQ9PnsTbysrLGMuZHJhd0ltYWdlGiwtMSwwBkIOQisrPDM0MDspewJsPWkobyw0KkIGZQ4Tch0wO3I8PTQwO3IrHTApZT1YaShvK3IsNCpCK3IpLmgVCGwudAEsbC5oPGUfCCJyZ2JhKDAsMCwwLCIrZS81MCsiKSIBKX19LDEwFSc7Rz0vWwEtH1QtWV0vLmV4ZWMoXyk7KXdpdGgoXy5zcGxpdChHKSlfPWpvaW4oc2hpZnQoKSk7ZXZhbChfKQ==
//
var W = "#4AF",
G = "#5A4",
T = "#2604",
R = "#666",
S = "#DDA",
O = "#07D",
D = "#AB5",
I = "#FFF",
N,J,K;
// Set up permutation list.
var plist = [...Array(512)].map(_=>~~(Math.random()*256));
/**
* @param {number} x
* @param {number} y
* @param {number} f Frequency.
* @param {number} o Octaves.
* t is Total.
*/
var getHeight = (x, y, f, o) => {
K = 0;
for(;o--;) {
K += noise(x*f, y*f)
f *= 2
}
return K
}
/**
*
*/
var gradient = (h, u, v) => {
if ((h&=7)<=4) [u,v]=[v,u]
return (h&1
? -u + (h&2 ? -2 : 2)
: u + (h&2 ? -2 : 2)) * v;
}
/**
*
*/
var noise = (x, y) => {
var s = (x+y)*.366025403;
var i = ~~(x + s);
var j = ~~(y + s);
var t = (i+j)*.211324865;
var x0 = x-(i-t);
var y0 = y-(j-t);
var i1 = x0 > y0;
var x1 = x0 - i1 + .211324865;
var y1 = y0 - !i1 + .211324865;
var x2 = x0 - .57735027;
var y2 = y0 - .57735027;
var ii = i & 255;
var jj = j & 255;
J = 0;
var t0 = .5 - x0*x0-y0*y0;
if (t0 >= 0) {
J += t0 ** 4 * gradient(plist[ii+plist[jj]], x0, y0);
}
var t1 = .5 - x1*x1-y1*y1;
if (t1 >= 0) {
J += t1 ** 4 * gradient(plist[ii+i1+plist[jj+!i1]], x1, y1);
}
var t2 = .5 - x2*x2-y2*y2;
if (t2 >= 0) {
J += t2 ** 4 * gradient(plist[ii+1+plist[jj+1]], x2, y2);
}
return 40 * J
}
/**
* @param {number} x
* @param {number} y
* Here we combine serveral layers of noise to produce the terrain for a given
* cell. This is largely dark magic. A lot of layers directly depend on other
* layers, so changing one part of it can change the rest in a kind of domino
* effect.
*/
var generateCell = (x, y) => {
x /= 4
y /= 4
//
var river = Math.abs(getHeight(x, y, .0025, 4)) ** 2.5;
var tributary = Math.abs(getHeight(x, y, .04, 1)) ** 2 + river * .2;
var moisture = river * .8 + getHeight(x, y, .16, 2) * 0.2;
// Forests.
var forest = getHeight(x, y, .005, 3);
// Mountains.
J = 1 + getHeight(x, y, .04, 1) * .4
+ getHeight(x, y, .02, 1) * .6
+ getHeight(x, y, .16, 1) * .6;
J *= river;
// Hills.
J += 1.3 + getHeight(y, x, .16, 1) * .5;
// Ocean.
J -= 100 ** getHeight(x, y, .001, 1);
var type = J > 8 ? I
: J > 2 ? R
: J <= -4 ? O
: J <= -1.5 ? W
: forest > .6 || (forest > .1 && moisture < 0) ? T
: J <= -1.2 ? S
: tributary < .025 || river < .005 ? W
: moisture > 1 ? D
: G;
return {
t: type,
h: type === T ? J+5
: type === W || type === O || type === S ? 1
: Math.max(1, J*2)
}
}
var X = 0;
var A = 0;
setInterval(_ => {
// Move draw across.
X++
// Draw canvas shifted to left.
//c.globalAlpha = 1
//c.globalCompositeOperation = "copy"
c.drawImage(a, -1, 0)
// Draw new cells (that are "coming in").
//c.globalCompositeOperation = "source-over";
//if (A < 1) c.globalAlpha = A += .002;
for (Y=0; Y++<340;) {
var cell = generateCell(X, Y*4);
var shadow = 0;
for (N=10;N<=40;N+=10) {
shadow = Math.max(generateCell(X+N, Y*4+N).h);
}
// Color.
c.fillStyle = cell.t;
c.fillRect(639, Y-cell.h, 1, 20);
// Shadow.
if (cell.h < shadow) {
c.fillStyle = "rgba(0,0,0,"+shadow/50+")";
c.fillRect(639, Y-cell.h, 1, 20);
}
}
}, 10)