fractal-hell/js/index.js

243 lines
5.1 KiB
JavaScript
Raw Permalink Normal View History

2024-09-13 03:30:57 -04:00
//const width = 2048;
//const height = 2048;
2024-09-14 22:32:14 -04:00
const tileSize = 256;
2024-09-14 22:02:23 -04:00
const chunkSize = 16;
2024-09-13 07:19:07 -04:00
const assets = [
2024-09-14 22:02:23 -04:00
'assets/groundA.svg',
'assets/groundB.svg',
2024-09-13 07:19:07 -04:00
'assets/player.svg',
2024-09-14 22:02:23 -04:00
'assets/collapseA.svg',
'assets/collapseB.svg',
'assets/nothing.svg',
'assets/box.svg'
2024-09-13 07:19:07 -04:00
];
2024-09-12 19:19:06 -04:00
function getRGBA(data, i) {
let out = new Uint8Array(4);
for (let j = i * 4; j < i * 4 + 4; j++) {
2024-09-13 03:30:57 -04:00
out[j - i * 4] = data[j];
2024-09-12 19:19:06 -04:00
}
return out;
}
function setRGBA(data, i, input) {
for (let j = i * 4; j < i * 4 + 4; j++) {
data[j] = input[j - i * 4];
}
}
2024-09-13 03:30:57 -04:00
function toPoint(x2, y2, base, fac, exp, inSize) {
let isMask = 1;
x2 = Math.round(x2 / tileSize);
y2 = Math.round(y2 / tileSize);
for (let j = 0; j < exp; j++) {
isMask *= base[(y2 % inSize) * inSize + (x2 % inSize)];
2024-09-12 19:19:06 -04:00
2024-09-13 03:30:57 -04:00
x2 /= inSize;
y2 /= inSize;
2024-09-12 19:19:06 -04:00
2024-09-13 03:30:57 -04:00
x2 = Math.floor(x2);
y2 = Math.floor(y2);
2024-09-12 19:19:06 -04:00
}
2024-09-13 03:30:57 -04:00
isMask *= fac;
2024-09-12 19:19:06 -04:00
2024-09-13 07:19:07 -04:00
isMask = (isMask - 0.5) + 0.5;
2024-09-13 03:30:57 -04:00
isMask = Math.max(isMask, 0);
isMask = Math.min(isMask, 1);
return isMask;
}
2024-09-12 19:19:06 -04:00
2024-09-13 21:25:41 -04:00
function getChunk(x, y) {
2024-09-14 22:02:23 -04:00
let cx = Math.floor(x / chunkSize);
let cy = Math.floor(y / chunkSize);
2024-09-13 21:25:41 -04:00
let id = cx + ',' + cy;
return id;
}
2024-09-13 03:30:57 -04:00
function Game(inSize, exp, cs) {
this.exp = exp;
2024-09-13 07:19:07 -04:00
this.assets = [];
2024-09-13 03:30:57 -04:00
this.inSize = inSize;
this.cs = cs;
2024-09-12 19:19:06 -04:00
2024-09-13 03:30:57 -04:00
this.img = new Image();
this.base = new Float32Array(inSize * inSize);
this.frames = 0;
this.camera = [0, 0];
2024-09-12 19:19:06 -04:00
2024-09-13 21:25:41 -04:00
this.modChunks = {};
2024-09-13 03:30:57 -04:00
this.dead = false;
}
2024-09-12 19:19:06 -04:00
2024-09-14 22:47:08 -04:00
Game.prototype.placeBlock = function (block, get = false, xI = false, yI = false) {
2024-09-14 22:32:14 -04:00
let { camera, base, fac, exp, inSize } = this;
2024-09-13 21:25:41 -04:00
2024-09-14 22:47:08 -04:00
if (xI === false) xI = camera[0];
if (yI === false) yI = camera[1];
let x = Math.round(xI / tileSize);
let y = Math.round(yI / tileSize);
2024-09-13 21:25:41 -04:00
2024-09-14 22:02:23 -04:00
let bx = x % chunkSize;
let by = y % chunkSize;
2024-09-13 21:25:41 -04:00
let id = getChunk(x, y);
2024-09-14 22:02:23 -04:00
let chunk = this.modChunks[id] = this.modChunks[id] || new Uint8Array(chunkSize * chunkSize);
2024-09-13 21:25:41 -04:00
2024-09-14 22:32:14 -04:00
if (get) {
let g = chunk[by * chunkSize + bx];
if (g != 0) return g - 1;
2024-09-14 22:47:08 -04:00
let isMask = toPoint(xI, yI, base, fac, exp, inSize);
2024-09-14 22:32:14 -04:00
2024-09-14 22:47:08 -04:00
let assetI = ((x & y) % 3) == 0 ? 0 : 1;
2024-09-14 22:32:14 -04:00
if (isMask < 0.5) return 5;
if (isMask < 0.501) return 4;
if (isMask < 0.51) return 3;
return assetI;
}
2024-09-14 22:02:23 -04:00
chunk[by * chunkSize + bx] = block + 1;
2024-09-13 21:25:41 -04:00
}
2024-09-13 06:11:07 -04:00
Game.prototype.player = function () {
2024-09-13 07:19:07 -04:00
let { ctx, fac, base, exp, inSize, camera, cs, assets } = this;
2024-09-13 21:25:41 -04:00
ctx.drawImage(assets[2], cs / 2 - tileSize / 1.8, cs / 2 - tileSize / 1.8, tileSize / 0.9, tileSize / 0.9);
2024-09-13 06:11:07 -04:00
2024-09-14 22:32:14 -04:00
let isBlock = this.placeBlock(0, true);
if (isBlock == 5) {
2024-09-13 06:11:07 -04:00
this.dead = true;
}
let cx = Math.floor(camera[0]) / tileSize;
let cy = Math.floor(camera[1]) / tileSize;
let sum = 0;
for (let i in base) {
sum += base[i]
}
2024-09-13 21:25:41 -04:00
sum *= (fac ** (1 / exp));
2024-09-13 06:11:07 -04:00
let dim = Math.log(sum) / (Math.log(base.length) / 2);
2024-09-14 22:32:14 -04:00
document.querySelector('.ui-text').textContent = `X: ${cx}\nY: ${cy}\nDimensionality: ${dim}`
2024-09-13 06:11:07 -04:00
}
2024-09-13 03:30:57 -04:00
Game.prototype.main = function () {
var { base, inSize, ctx, cs, frames, exp, camera, dat } = this;
if (this.dead) {
document.querySelector('.message').style.display = 'flex';
return;
} else {
}
2024-09-12 19:19:06 -04:00
2024-09-13 21:25:41 -04:00
ctx.clearRect(0, 0, cs, cs);
2024-09-13 07:19:07 -04:00
2024-09-13 03:30:57 -04:00
this.frames++;
2024-09-12 19:19:06 -04:00
2024-09-13 07:19:07 -04:00
this.fac = 0.99999 ** frames;
2024-09-14 22:32:14 -04:00
for (let i = 0; i < ((cs / tileSize + 2) * (cs / tileSize + 2)); i++) {
let x = i % (cs / tileSize + 2);
x--;
2024-09-13 07:19:07 -04:00
x *= tileSize;
2024-09-14 22:32:14 -04:00
let y = Math.floor(i / ((cs / tileSize + 2)));
y--;
2024-09-13 07:19:07 -04:00
y *= tileSize;
2024-09-13 21:25:41 -04:00
x = x + Math.round((camera[0] - cs / 2) / tileSize) * tileSize;
y = y + Math.round((camera[1] - cs / 2) / tileSize) * tileSize;
let x2 = x - camera[0] + cs / 2;
let y2 = y - camera[1] + cs / 2;
let id = getChunk(x / tileSize, y / tileSize);
2024-09-12 19:19:06 -04:00
2024-09-13 21:25:41 -04:00
let chunk = this.modChunks[id];
2024-09-14 22:02:23 -04:00
let bx = Math.round(x / tileSize) % chunkSize;
2024-09-14 22:32:14 -04:00
let by = Math.round(y / tileSize) % chunkSize;
2024-09-13 21:25:41 -04:00
2024-09-14 22:47:08 -04:00
let assetI = this.placeBlock(0,true,x,y);
2024-09-13 07:19:07 -04:00
2024-09-13 21:25:41 -04:00
ctx.drawImage(this.assets[assetI], x2, y2, tileSize, tileSize);
2024-09-12 19:19:06 -04:00
}
2024-09-13 03:30:57 -04:00
2024-09-13 06:11:07 -04:00
this.player();
2024-09-12 19:19:06 -04:00
}
2024-09-13 03:30:57 -04:00
Game.prototype.map = function () {
var { base, inSize, exp } = this;
2024-09-12 19:19:06 -04:00
//noise.seed(Math.random() * 1000);
for (let i in base) {
let x = i % inSize;
let y = Math.floor(i / inSize);
base[i] = Math.random();
2024-09-13 03:30:57 -04:00
base[i] = Math.max(base[i], 0);
base[i] = Math.min(base[i], 1);
base[i] = Math.pow(base[i], 0.3);
2024-09-13 18:04:29 -04:00
base[i] = base[i] * 0.3 + 0.7;
2024-09-12 19:19:06 -04:00
//base[i] = (Math.random() > 0.5) ? 0 : 1;
}
2024-09-13 03:30:57 -04:00
this.fac = 1;
2024-09-13 18:04:29 -04:00
let x2 = 0, y2 = 0, mask = 0;
2024-09-13 03:30:57 -04:00
2024-09-13 07:21:57 -04:00
for (let i = 0; i < 1000000; i++) {
2024-09-13 18:04:29 -04:00
x2 = Math.random() * (1.000012 ** i) * 1e2;
y2 = Math.random() * (1.000012 ** i) * 1e2;
mask = toPoint(x2, y2, base, this.fac, exp, inSize);
2024-09-13 03:30:57 -04:00
if (mask == 1) break;
}
this.camera = [x2, y2];
2024-09-12 19:19:06 -04:00
}
2024-09-13 03:30:57 -04:00
Game.prototype.loop = function () {
2024-09-12 19:19:06 -04:00
let that = this;
2024-09-13 03:30:57 -04:00
setInterval(function () { that.main() }, 1000 / 60);
2024-09-12 19:19:06 -04:00
}
2024-09-13 03:30:57 -04:00
Game.prototype.startGame = function () {
2024-09-12 19:19:06 -04:00
var canvas = document.querySelector("#canvas");
2024-09-13 03:30:57 -04:00
canvas.width = this.cs;
canvas.height = this.cs;
2024-09-12 19:19:06 -04:00
2024-09-13 03:30:57 -04:00
var ctx = this.ctx = canvas.getContext("2d");
2024-09-12 19:19:06 -04:00
2024-09-14 22:32:14 -04:00
//ctx.imageSmoothingEnabled = true;
2024-09-12 19:19:06 -04:00
2024-09-13 07:19:07 -04:00
for (let asset in assets) {
this.assets[asset] = new Image();
this.assets[asset].src = assets[asset];
}
2024-09-13 03:30:57 -04:00
this.dat = ctx.getImageData(0, 0, this.cs, this.cs);
2024-09-12 19:19:06 -04:00
this.map();
this.loop();
}
2024-09-13 03:30:57 -04:00
Game.prototype.init = function () {
2024-09-12 19:19:06 -04:00
let that = this;
that.startGame();
}
2024-09-14 22:32:14 -04:00
let game = new Game(8, 8, 16 * tileSize)
2024-09-13 03:30:57 -04:00
game.init();