Map tweaks
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
max-height: 512px;
|
max-height: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tile-swatch {
|
.tile-swatch {
|
||||||
|
|||||||
@@ -41,16 +41,15 @@
|
|||||||
[ChunkTerrain.TILE_SHAPE_RAMP_SOUTHWEST_INNER]: { dx: -1, dy: 1 },
|
[ChunkTerrain.TILE_SHAPE_RAMP_SOUTHWEST_INNER]: { dx: -1, dy: 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
// Draws an arrow centered at (cx, cy) pointing toward the ramp's high
|
const INNER_CORNER_SHAPES = new Set([
|
||||||
// side, so ramp direction is visible at a glance on both the palette
|
ChunkTerrain.TILE_SHAPE_RAMP_NORTHEAST_INNER,
|
||||||
// swatches and the tile grid.
|
ChunkTerrain.TILE_SHAPE_RAMP_NORTHWEST_INNER,
|
||||||
function drawArrow(ctx, cx, cy, size, dx, dy) {
|
ChunkTerrain.TILE_SHAPE_RAMP_SOUTHEAST_INNER,
|
||||||
const mag = Math.hypot(dx, dy) || 1;
|
ChunkTerrain.TILE_SHAPE_RAMP_SOUTHWEST_INNER,
|
||||||
const ux = dx / mag, uy = dy / mag;
|
]);
|
||||||
const len = size * 0.32;
|
|
||||||
const tipX = cx + ux * len, tipY = cy + uy * len;
|
|
||||||
const tailX = cx - ux * len, tailY = cy - uy * len;
|
|
||||||
|
|
||||||
|
// Draws a single-headed arrow from (tailX, tailY) to (tipX, tipY).
|
||||||
|
function drawArrowSegment(ctx, tailX, tailY, tipX, tipY, size) {
|
||||||
ctx.strokeStyle = "#ffffff";
|
ctx.strokeStyle = "#ffffff";
|
||||||
ctx.fillStyle = "#ffffff";
|
ctx.fillStyle = "#ffffff";
|
||||||
ctx.lineWidth = Math.max(1, size * 0.08);
|
ctx.lineWidth = Math.max(1, size * 0.08);
|
||||||
@@ -62,7 +61,7 @@
|
|||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
|
||||||
const headLen = size * 0.18;
|
const headLen = size * 0.18;
|
||||||
const angle = Math.atan2(uy, ux);
|
const angle = Math.atan2(tipY - tailY, tipX - tailX);
|
||||||
const leftAngle = angle + Math.PI * 0.8;
|
const leftAngle = angle + Math.PI * 0.8;
|
||||||
const rightAngle = angle - Math.PI * 0.8;
|
const rightAngle = angle - Math.PI * 0.8;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
@@ -73,6 +72,54 @@
|
|||||||
ctx.fill();
|
ctx.fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draws an arrow centered at (cx, cy) pointing toward the ramp's high
|
||||||
|
// side, so ramp direction is visible at a glance on both the palette
|
||||||
|
// swatches and the tile grid. Used for cardinal ramps and outer-corner
|
||||||
|
// ramps (a single raised corner).
|
||||||
|
function drawArrow(ctx, cx, cy, size, dx, dy) {
|
||||||
|
const mag = Math.hypot(dx, dy) || 1;
|
||||||
|
const ux = dx / mag, uy = dy / mag;
|
||||||
|
const len = size * 0.32;
|
||||||
|
drawArrowSegment(ctx, cx - ux * len, cy - uy * len, cx + ux * len, cy + uy * len, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draws a plain right-angle bracket - two line segments meeting at 90
|
||||||
|
// degrees at the tile's corner, one running along each of the two edges
|
||||||
|
// adjacent to it - so inner-corner ramps (three corners raised, one
|
||||||
|
// dropped) read as "the adjacent sides meeting in a 90-degree corner",
|
||||||
|
// distinct from the single diagonal arrow used for outer-corner ramps.
|
||||||
|
function drawCornerBracket(ctx, cx, cy, size, dx, dy) {
|
||||||
|
const cornerDist = size * 0.42;
|
||||||
|
const armLen = size * 0.34;
|
||||||
|
const cornerX = cx + dx * cornerDist;
|
||||||
|
const cornerY = cy + dy * cornerDist;
|
||||||
|
|
||||||
|
ctx.strokeStyle = "#ffffff";
|
||||||
|
ctx.lineWidth = Math.max(1, size * 0.08);
|
||||||
|
ctx.lineCap = "round";
|
||||||
|
ctx.lineJoin = "round";
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(cornerX - dx * armLen, cornerY);
|
||||||
|
ctx.lineTo(cornerX, cornerY);
|
||||||
|
ctx.lineTo(cornerX, cornerY - dy * armLen);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draws the direction icon for a ramp tile `type` in a `size`x`size` area
|
||||||
|
// centered at (cx, cy): a diagonal arrow for cardinal/outer-corner ramps,
|
||||||
|
// or a right-angle bracket for inner-corner ramps. No-op for shapes with
|
||||||
|
// no direction (ground, erase).
|
||||||
|
function drawShapeIcon(ctx, cx, cy, size, type) {
|
||||||
|
const dir = SHAPE_DIRECTIONS[type];
|
||||||
|
if(!dir) return;
|
||||||
|
if(INNER_CORNER_SHAPES.has(type)) {
|
||||||
|
drawCornerBracket(ctx, cx, cy, size, dir.dx, dir.dy);
|
||||||
|
} else {
|
||||||
|
drawArrow(ctx, cx, cy, size, dir.dx, dir.dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Draws a small pencil icon centered in a `size`x`size` canvas.
|
// Draws a small pencil icon centered in a `size`x`size` canvas.
|
||||||
function drawPencilIcon(ctx, size) {
|
function drawPencilIcon(ctx, size) {
|
||||||
ctx.save();
|
ctx.save();
|
||||||
@@ -434,13 +481,12 @@
|
|||||||
buildPalette();
|
buildPalette();
|
||||||
});
|
});
|
||||||
|
|
||||||
const dir = SHAPE_DIRECTIONS[s.type];
|
if(SHAPE_DIRECTIONS[s.type]) {
|
||||||
if(dir) {
|
|
||||||
const icon = document.createElement("canvas");
|
const icon = document.createElement("canvas");
|
||||||
icon.width = 32;
|
icon.width = 32;
|
||||||
icon.height = 32;
|
icon.height = 32;
|
||||||
icon.className = "tile-swatch-icon";
|
icon.className = "tile-swatch-icon";
|
||||||
drawArrow(icon.getContext("2d"), 16, 16, 32, dir.dx, dir.dy);
|
drawShapeIcon(icon.getContext("2d"), 16, 16, 32, s.type);
|
||||||
btn.appendChild(icon);
|
btn.appendChild(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,8 +546,7 @@
|
|||||||
ctx.strokeStyle = "rgba(255, 255, 255, 0.25)";
|
ctx.strokeStyle = "rgba(255, 255, 255, 0.25)";
|
||||||
ctx.strokeRect(x * cell, sy, cell, cell);
|
ctx.strokeRect(x * cell, sy, cell, cell);
|
||||||
|
|
||||||
const dir = SHAPE_DIRECTIONS[type];
|
drawShapeIcon(ctx, x * cell + cell / 2, sy + cell / 2, cell, type);
|
||||||
if(dir) drawArrow(ctx, x * cell + cell / 2, sy + cell / 2, cell, dir.dx, dir.dy);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user