Change tilemap to dimension and simple generation

This commit is contained in:
2026-03-06 15:46:42 -03:00
parent 0f3f8de735
commit e5d2a3e7e2
20 changed files with 137 additions and 186 deletions
+5 -5
View File
@@ -2,12 +2,12 @@ import { System } from "$/common/ecs/mod.ts";
import { World } from "$/common/ecs/world.ts";
import { Position } from "$/common/components/position.ts";
import { AnimatedSprite, Sprite } from "$/client/components/sprite.ts";
import { Tilemap } from "$/client/components/tilemap.ts";
import { Dimension } from "../components/dimension.ts";
import { PlayerInventory } from "$/client/components/inventory.ts";
import { Camera } from "$/client/components/camera.ts";
import { render_animated_sprite, render_sprite } from "./rendering/sprites.ts";
import { render_tilemap } from "./rendering/tilemap.ts";
import { render_dimension } from "./rendering/dimension.ts";
import { render_player_inventory } from "./rendering/player.ts";
export class RenderSystem extends System {
@@ -56,10 +56,10 @@ export class RenderSystem extends System {
render_animated_sprite(this.ctx, animated_sprite, position);
}
const tilemap = entity.get(Tilemap);
const dimension = entity.get(Dimension);
if (tilemap) {
render_tilemap(this.ctx, tilemap);
if (dimension) {
render_dimension(this.ctx, dimension, camera);
}
// Ui
+37
View File
@@ -0,0 +1,37 @@
import { get_sprite_region } from "$/common/utils.ts";
import { Dimension } from "$/client/components/dimension.ts";
import { TEXTURE_SIZE, TILE_SIZE } from "$/common/constants.ts";
import { Camera, world_to_screen } from "$/client/components/camera.ts";
export function render_dimension(ctx: CanvasRenderingContext2D, tilemap: Dimension, camera: Camera) {
ctx.save();
for (const tile of tilemap.tiles) {
const region = get_sprite_region(tile.id);
const x = tile.x * TILE_SIZE;
const y = tile.y * TILE_SIZE;
const screen_position = world_to_screen(x, y, camera, ctx.canvas.width, ctx.canvas.height);
if (
screen_position.x + TILE_SIZE < 0 || screen_position.x > ctx.canvas.width ||
screen_position.y + TILE_SIZE < 0 || screen_position.y > ctx.canvas.height
) {
continue;
}
ctx.drawImage(
tilemap.image,
region.x * TEXTURE_SIZE,
region.y * TEXTURE_SIZE,
TEXTURE_SIZE,
TEXTURE_SIZE,
x,
y,
TILE_SIZE,
TILE_SIZE,
);
}
ctx.restore();
}
-30
View File
@@ -1,30 +0,0 @@
import { Tilemap } from "$/client/components/tilemap.ts";
export function render_tilemap(ctx: CanvasRenderingContext2D, tilemap: Tilemap) {
ctx.save();
ctx.translate(
-Math.floor(ctx.canvas.width / 2),
-Math.floor(ctx.canvas.height / 2),
);
for (const tile of tilemap.tiles) {
const tx = tile.index % tilemap.columns;
const ty = Math.floor(tile.index / tilemap.columns);
const sx = tx * tilemap.tile_size + (tx * tilemap.margin);
const sy = ty * tilemap.tile_size + (ty * tilemap.margin);
ctx.drawImage(
tilemap.image,
sx,
sy,
tilemap.tile_size,
tilemap.tile_size,
tile.x * tilemap.tile_size * tilemap.scale,
tile.y * tilemap.tile_size * tilemap.scale,
tilemap.tile_size * tilemap.scale,
tilemap.tile_size * tilemap.scale,
);
}
ctx.restore();
}
-99
View File
@@ -1,99 +0,0 @@
import { System } from "$/common/ecs/mod.ts";
import { point_inside_rec } from "$/common/utils.ts";
import { ClientWorld } from "$/client/client_world.ts";
import { Camera } from "$/client/components/camera.ts";
import { Tilemap } from "$/client/components/tilemap.ts";
import { DebugUI } from "$/client/debug_ui.ts";
import { InputManager } from "$/client/input_manager.ts";
export class TileEditorSystem extends System {
constructor() {
super();
}
update(world: ClientWorld, _delta: number): void {
if (!world.debugging) {
return;
}
DebugUI.ctx.save();
DebugUI.ctx.setTransform(1, 0, 0, 1, 0, 0);
const ctx = world.ctx;
const camera_entity = world.get_entities().values().find((e) => e.get(Camera)?.active);
const camera = camera_entity?.get(Camera);
if (!camera) {
return;
}
for (const entity of world.get_entities()) {
const tilemap = entity.get(Tilemap);
if (!tilemap) {
continue;
}
const scaled_size = tilemap.tile_size * tilemap.scale;
const mouse = InputManager.get_mouse_position();
DebugUI.begin("Tile Editor", 500, 10, 300);
DebugUI.progress_bar(0.5);
if (DebugUI.button("Save")) {
navigator.clipboard.writeText(JSON.stringify(tilemap));
}
for (let i = 0; i < tilemap.rows; i += 1) {
for (let j = 0; j < tilemap.columns; j += 1) {
const x = DebugUI.cursor_x + j * scaled_size;
const y = DebugUI.cursor_y;
const hovered = point_inside_rec(mouse.x, mouse.y, x, y, scaled_size, scaled_size);
if (DebugUI.is_inside_windows(mouse.x, mouse.y) && hovered && InputManager.is_mouse_pressed(0)) {
InputManager.consume_mouse(0);
tilemap.selected_tile = i * tilemap.columns + j;
}
ctx.drawImage(
tilemap.image,
j * tilemap.tile_size + (j * tilemap.margin),
i * tilemap.tile_size + (i * tilemap.margin),
tilemap.tile_size,
tilemap.tile_size,
x,
y,
scaled_size,
scaled_size,
);
}
DebugUI.advance(scaled_size);
}
DebugUI.end();
if (tilemap.editing) {
const world_x = mouse.x + camera.x;
const world_y = mouse.y + camera.y;
const tx = Math.floor(world_x / (tilemap.tile_size * tilemap.scale));
const ty = Math.floor(world_y / (tilemap.tile_size * tilemap.scale));
if (InputManager.is_mouse_pressed(0)) {
const maybe_tile = tilemap.tiles.find((tile) => tile.x === tx && tile.y === ty);
if (maybe_tile?.index !== tilemap.selected_tile) {
tilemap.tiles.push({ x: tx, y: ty, index: tilemap.selected_tile });
}
} else if (InputManager.is_mouse_pressed(1)) {
InputManager.consume_mouse(1);
const index = tilemap.tiles.findLastIndex((tile) => tile.x === tx && tile.y === ty);
if (index !== -1) {
tilemap.tiles.splice(index, 1);
}
}
}
}
DebugUI.ctx.restore();
}
}