|
|
|
@ -19,25 +19,43 @@ await Promise.all(promises);
|
|
|
|
|
font = await font.loaded;
|
|
|
|
|
document.fonts.add(font);
|
|
|
|
|
|
|
|
|
|
let world = World.new();
|
|
|
|
|
let world = World.deserialize(await (await fetch("/stackline/tests/other/prime.json")).json());
|
|
|
|
|
world.init();
|
|
|
|
|
|
|
|
|
|
// let world = World.new();
|
|
|
|
|
let cx = 0;
|
|
|
|
|
let cy = 0;
|
|
|
|
|
let zoom = 1;
|
|
|
|
|
let grid = true;
|
|
|
|
|
|
|
|
|
|
let pane = Pane.empty(5, 5);
|
|
|
|
|
world.set_pane("main", pane);
|
|
|
|
|
let click_x = 0, click_y = 0;
|
|
|
|
|
let mouse_x = 0, mouse_y = 0;
|
|
|
|
|
let mouse_down = false;
|
|
|
|
|
let hovered = false;
|
|
|
|
|
let selected = null;
|
|
|
|
|
|
|
|
|
|
let available = available_tiles();
|
|
|
|
|
console.log(available);
|
|
|
|
|
for (let n = 0; n < available.length; n++) {
|
|
|
|
|
world.set(
|
|
|
|
|
n % 5,
|
|
|
|
|
~~(n / 5),
|
|
|
|
|
new FullTile(available[n])
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
let running = null;
|
|
|
|
|
|
|
|
|
|
let tile = world.get(4, 0);
|
|
|
|
|
tile.signal = new Signal();
|
|
|
|
|
tile.state = "Active";
|
|
|
|
|
world.set(4, 0, tile);
|
|
|
|
|
|
|
|
|
|
// let pane = Pane.empty(5, 5);
|
|
|
|
|
// world.set_pane("main", pane);
|
|
|
|
|
|
|
|
|
|
// let available = available_tiles();
|
|
|
|
|
// console.log(available);
|
|
|
|
|
// for (let n = 0; n < available.length; n++) {
|
|
|
|
|
// world.set(
|
|
|
|
|
// n % 5,
|
|
|
|
|
// ~~(n / 5),
|
|
|
|
|
// new FullTile(available[n])
|
|
|
|
|
// );
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
console.log(world.toString());
|
|
|
|
|
console.log(world.serialize());
|
|
|
|
|
|
|
|
|
|
resize();
|
|
|
|
|
window.addEventListener("resize", resize);
|
|
|
|
@ -49,14 +67,30 @@ function draw() {
|
|
|
|
|
ctx.fillStyle = "#202027";
|
|
|
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
|
|
|
|
|
|
|
function stroke_rect(x, y, width, height) {
|
|
|
|
|
ctx.lineWidth = zoom_factor;
|
|
|
|
|
ctx.strokeRect(
|
|
|
|
|
Math.round(x * tile_size + cx + canvas.width / 2) - zoom_factor * 1.5,
|
|
|
|
|
Math.round(y * tile_size + cy + canvas.height / 2) - zoom_factor * 1.5,
|
|
|
|
|
Math.round(width * tile_size) + zoom_factor * 2,
|
|
|
|
|
Math.round(height * tile_size) + zoom_factor * 2,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function fill_rect(x, y, width, height) {
|
|
|
|
|
ctx.fillRect(
|
|
|
|
|
Math.round(x * tile_size + cx + canvas.width / 2) - zoom_factor * 1,
|
|
|
|
|
Math.round(y * tile_size + cy + canvas.height / 2) - zoom_factor * 1,
|
|
|
|
|
Math.round(width * tile_size) + zoom_factor * 1,
|
|
|
|
|
Math.round(height * tile_size) + zoom_factor * 1,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let panes = [];
|
|
|
|
|
|
|
|
|
|
for (let name of world.panes()) {
|
|
|
|
|
let pane = world.get_pane(name);
|
|
|
|
|
|
|
|
|
|
ctx.strokeStyle = "rgba(128, 128, 128, 0.5)";
|
|
|
|
|
ctx.lineWidth = zoom_factor;
|
|
|
|
|
|
|
|
|
|
panes.push({
|
|
|
|
|
x: pane.x,
|
|
|
|
|
y: pane.y,
|
|
|
|
@ -64,11 +98,12 @@ function draw() {
|
|
|
|
|
height: pane.height
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
ctx.strokeRect(
|
|
|
|
|
Math.round(pane.x * tile_size + cx + canvas.width / 2) - zoom_factor * 1.5,
|
|
|
|
|
Math.round(pane.y * tile_size + cy + canvas.height / 2) - zoom_factor * 1.5,
|
|
|
|
|
Math.round(pane.width * tile_size) + zoom_factor * 3,
|
|
|
|
|
Math.round(pane.height * tile_size) + zoom_factor * 3,
|
|
|
|
|
ctx.strokeStyle = "rgba(128, 128, 128, 0.5)";
|
|
|
|
|
stroke_rect(
|
|
|
|
|
pane.x,
|
|
|
|
|
pane.y,
|
|
|
|
|
pane.width,
|
|
|
|
|
pane.height,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
pane.free();
|
|
|
|
@ -115,7 +150,7 @@ function draw() {
|
|
|
|
|
Math.round(x2),
|
|
|
|
|
Math.round(y2),
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
} else if (grid) {
|
|
|
|
|
// Draw grid
|
|
|
|
|
let inside = false;
|
|
|
|
|
|
|
|
|
@ -127,7 +162,7 @@ function draw() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (inside || width < 100 && height < 100) {
|
|
|
|
|
ctx.fillStyle = inside ? "#505050" : "#303030";
|
|
|
|
|
ctx.fillStyle = inside ? "#404040" : "#303030";
|
|
|
|
|
|
|
|
|
|
ctx.fillRect(
|
|
|
|
|
Math.round(x2 + tile_size / 2) - zoom_factor,
|
|
|
|
@ -139,6 +174,15 @@ function draw() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hovered) {
|
|
|
|
|
let [x, y] = get_hovered();
|
|
|
|
|
|
|
|
|
|
ctx.strokeStyle = "rgba(230, 255, 230, 0.2)";
|
|
|
|
|
ctx.fillStyle = "rgba(230, 255, 230, 0.07)";
|
|
|
|
|
stroke_rect(x, y, 1, 1);
|
|
|
|
|
fill_rect(x, y, 1, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function resize() {
|
|
|
|
@ -153,40 +197,85 @@ function loop() {
|
|
|
|
|
window.requestAnimationFrame(loop);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mouse_x = 0, mouse_y = 0;
|
|
|
|
|
let mouse_down = false;
|
|
|
|
|
|
|
|
|
|
canvas.addEventListener("mousedown", (evt) => {
|
|
|
|
|
mouse_x = evt.clientX;
|
|
|
|
|
mouse_y = evt.clientY;
|
|
|
|
|
click_x = mouse_x = evt.clientX;
|
|
|
|
|
click_y = mouse_y = evt.clientY;
|
|
|
|
|
mouse_down = true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
canvas.addEventListener("mousemove", (evt) => {
|
|
|
|
|
hovered = true;
|
|
|
|
|
|
|
|
|
|
if (mouse_down) {
|
|
|
|
|
// TODO: numerically stable solution
|
|
|
|
|
cx += evt.clientX - mouse_x;
|
|
|
|
|
cy += evt.clientY - mouse_y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mouse_x = evt.clientX;
|
|
|
|
|
mouse_y = evt.clientY;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
canvas.addEventListener("mouseup", (evt) => {
|
|
|
|
|
mouse_down = false;
|
|
|
|
|
|
|
|
|
|
let dist = Math.sqrt((mouse_x - click_x) ** 2 + (mouse_y - click_y) ** 2);
|
|
|
|
|
if (dist < 10) {
|
|
|
|
|
selected = get_hovered();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
canvas.addEventListener("mouseenter", (evt) => {
|
|
|
|
|
hovered = true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
canvas.addEventListener("mouseleave", (evt) => {
|
|
|
|
|
mouse_down = false;
|
|
|
|
|
hovered = false;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
canvas.addEventListener("wheel", (event) => {
|
|
|
|
|
const ZOOM_STRENGTH = -0.005;
|
|
|
|
|
let old_zoom = zoom;
|
|
|
|
|
zoom += event.deltaY * ZOOM_STRENGTH;
|
|
|
|
|
zoom = Math.min(Math.max(zoom, 0.0), 4.0);
|
|
|
|
|
|
|
|
|
|
let delta = Math.ceil(Math.pow(2, zoom)) / Math.ceil(Math.pow(2, old_zoom));
|
|
|
|
|
cx *= delta;
|
|
|
|
|
cy *= delta;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
window.addEventListener("keydown", (event) => {
|
|
|
|
|
if (hovered) {
|
|
|
|
|
if (event.code === "Space") {
|
|
|
|
|
if (running !== null) {
|
|
|
|
|
clearInterval(running);
|
|
|
|
|
running = null;
|
|
|
|
|
} else if (event.shiftKey) {
|
|
|
|
|
world.init();
|
|
|
|
|
running = setInterval(() => {
|
|
|
|
|
world.step();
|
|
|
|
|
}, 100);
|
|
|
|
|
} else {
|
|
|
|
|
world.init();
|
|
|
|
|
world.step();
|
|
|
|
|
}
|
|
|
|
|
} else if (event.code === "KeyG") {
|
|
|
|
|
grid = !grid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function get_hovered() {
|
|
|
|
|
let zoom_factor = Math.ceil(Math.pow(2, zoom));
|
|
|
|
|
let tile_size = 10 * zoom_factor;
|
|
|
|
|
|
|
|
|
|
let x = Math.floor((mouse_x - canvas.width / 2 - cx) / tile_size);
|
|
|
|
|
let y = Math.floor((mouse_y - canvas.height / 2 - cy) / tile_size);
|
|
|
|
|
|
|
|
|
|
return [x, y];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function to_color(num) {
|
|
|
|
|
let alpha = (num >> 24) & 0xff;
|
|
|
|
|
let red = (num >> 16) & 0xff;
|
|
|
|
|