98 lines
2.5 KiB
JavaScript
98 lines
2.5 KiB
JavaScript
import * as graphics from "./graphics_core.mjs";
|
|
export * from "./graphics_core.mjs";
|
|
|
|
import { range, iter_2d } from "./utils/range.mjs";
|
|
import * as entity from "./entity.mjs";
|
|
import * as world from "./world.mjs";
|
|
|
|
|
|
|
|
const canvas = document.getElementById("canvas");
|
|
const canvas_context = canvas.getContext("2d");
|
|
graphics.set_size(canvas.width, canvas.height);
|
|
|
|
const BASE_SCALE = 81;
|
|
|
|
export function draw_rect (x, y, size = BASE_SCALE) {
|
|
graphics.fill_rect(x, y, size, size);
|
|
}
|
|
|
|
function checkerboard (x, y) {
|
|
return ((x ^ y) & 1) === 0;
|
|
}
|
|
|
|
function should_be_darker (x, y) {
|
|
const CENTER = world.CENTER;
|
|
const BOX_SIZE = world.BOX_SIZE;
|
|
|
|
return x === CENTER && y === CENTER
|
|
|| (x === 0 || x === BOX_SIZE - 1) && (y === 0 || y === BOX_SIZE - 1)
|
|
}
|
|
|
|
export function draw_floor (start_x, start_y, scale, invert = false) {
|
|
iter_2d(range(0, world.BOX_SIZE - 1), (x, y) => {
|
|
let dark = "#888";
|
|
let bright = "#aaa";
|
|
if (should_be_darker(x, y)) {
|
|
dark = "#555";
|
|
bright = "#666";
|
|
}
|
|
|
|
graphics.set_color(dark);
|
|
draw_rect(x * scale + start_x, y * scale + start_y, scale);
|
|
|
|
graphics.set_color(bright);
|
|
draw_rect(x * scale + start_x, y * scale + start_y, scale / 2);
|
|
draw_rect((x + 0.5) * scale + start_x, (y + 0.5) * scale + start_y, scale / 2);
|
|
});
|
|
}
|
|
|
|
export function draw_world (box, start_x = 0, start_y = 0, scale = BASE_SCALE) {
|
|
if (scale < 1) return;
|
|
|
|
draw_floor(start_x, start_y, scale, !checkerboard(start_x, start_y));
|
|
|
|
world.for_each_tile(box, (x, y, tile) => {
|
|
draw_tile(tile, x * scale + start_x, y * scale + start_y, scale);
|
|
});
|
|
|
|
entity.for_each((entity, id) => {
|
|
if (entity.box !== box) return;
|
|
graphics.set_color(entity.color);
|
|
const [visual_x, visual_y] = project_pos(entity.x, entity.y, scale);
|
|
draw_rect(start_x + visual_x, start_y + visual_y, scale);
|
|
});
|
|
}
|
|
|
|
function draw_tile (tile, x, y, scale) {
|
|
switch (tile.type) {
|
|
case "box": {
|
|
// recursively draw box contents.
|
|
draw_world(tile.box, x, y, scale / world.BOX_SIZE);
|
|
break;
|
|
}
|
|
case "paint": {
|
|
graphics.set_color(tile.color);
|
|
draw_rect(x, y, scale);
|
|
break;
|
|
}
|
|
// temporary: in the future, textures will exist and tile definitions will exist and keep track of textures for tiles.
|
|
case "grass": {
|
|
graphics.set_color("#2a0");
|
|
draw_rect(x, y, scale);
|
|
graphics.set_color("#4c0");
|
|
draw_rect(x, y, scale * 0.5);
|
|
draw_rect(x + scale / 2, y + scale / 2, scale * 0.5);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
function project_pos (x, y, scale) {
|
|
return [x, y].map(a => a * scale);
|
|
}
|
|
|
|
export function render () {
|
|
graphics.render(canvas_context);
|
|
}
|