Better maze rendering

This commit is contained in:
syuilo 2019-05-10 20:52:54 +09:00
parent f8e0bb399d
commit 58ceee5465
No known key found for this signature in database
GPG key ID: BDC4C49D06AB9D69
2 changed files with 124 additions and 101 deletions

View file

@ -1,6 +1,7 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as gen from 'random-seed'; import * as gen from 'random-seed';
const p = require('pureimage'); const p = require('pureimage');
import * as Line from 'pureimage/src/Line.js';
import { CellType } from './maze'; import { CellType } from './maze';
import { themes } from './themes'; import { themes } from './themes';
@ -29,25 +30,25 @@ export function renderMaze(seed, maze: CellType[][], stream: fs.WriteStream): Pr
// Draw // Draw
function drawCell(ctx, x, y, size, left, right, top, bottom, mark) { function drawCell(ctx, x, y, size, left, right, top, bottom, mark) {
const wallThickness = size / 8; const wallThickness = size / 8;
const wallMargin = size / 4; const margin = size / 5;
const markerMargin = size / 3; const markerMargin = size / 3;
ctx.fillStyle = colors.road; ctx.fillStyle = colors.road;
if (left) { if (left) {
ctx.beginPath(); ctx.beginPath();
ctx.fillRect(x, y + wallMargin, size - wallMargin, size - (wallMargin * 2)); ctx.fillRect(x, y + margin, size - margin, size - (margin * 2));
} }
if (right) { if (right) {
ctx.beginPath(); ctx.beginPath();
ctx.fillRect(x + wallMargin, y + wallMargin, size - wallMargin, size - (wallMargin * 2)); ctx.fillRect(x + margin, y + margin, size - margin, size - (margin * 2));
} }
if (top) { if (top) {
ctx.beginPath(); ctx.beginPath();
ctx.fillRect(x + wallMargin, y, size - (wallMargin * 2), size - wallMargin); ctx.fillRect(x + margin, y, size - (margin * 2), size - margin);
} }
if (bottom) { if (bottom) {
ctx.beginPath(); ctx.beginPath();
ctx.fillRect(x + wallMargin, y + wallMargin, size - (wallMargin * 2), size - wallMargin); ctx.fillRect(x + margin, y + margin, size - (margin * 2), size - margin);
} }
if (mark) { if (mark) {
@ -56,131 +57,153 @@ export function renderMaze(seed, maze: CellType[][], stream: fs.WriteStream): Pr
ctx.fillRect(x + markerMargin, y + markerMargin, size - (markerMargin * 2), size - (markerMargin * 2)); ctx.fillRect(x + markerMargin, y + markerMargin, size - (markerMargin * 2), size - (markerMargin * 2));
} }
const wallLeftTopX = x + wallMargin - (wallThickness / 2); function line(ax, ay, bx, by) {
const wallLeftTopY = y + wallMargin - (wallThickness / 2); return new Line(x + ax, y + ay, x + bx, y + by);
const wallRightTopX = x + size - wallMargin - (wallThickness / 2); }
const wallRightTopY = y + wallMargin - (wallThickness / 2);
const wallLeftBottomX = x + wallMargin - (wallThickness / 2);
const wallLeftBottomY = y + size - wallMargin - (wallThickness / 2);
const wallRightBottomX = x + size - wallMargin - (wallThickness / 2);
const wallRightBottomY = y + size - wallMargin - (wallThickness / 2);
ctx.fillStyle = colors.wall; ctx.strokeStyle = colors.wall;
ctx.lineWidth = wallThickness;
ctx.lineCap = 'square';
if (left && right && top && bottom) { if (left && right && top && bottom) {
ctx.beginPath(); ctx.beginPath();
if (rand(2) === 0) { if (rand(2) === 0) {
ctx.fillRect(x + wallMargin - (wallThickness / 2), y, wallThickness, size); ctx.drawLine(line(0, margin, size, margin)); // ─ 上
ctx.fillRect(x + size - wallMargin - (wallThickness / 2), y, wallThickness, size); ctx.drawLine(line(0, size - margin, size, size - margin)); // ─ 下
ctx.fillRect(x, y + wallMargin - (wallThickness / 2), wallMargin, wallThickness); ctx.drawLine(line(margin, 0, margin, margin)); // │ 左上
ctx.fillRect(x + size - wallMargin, y + wallMargin - (wallThickness / 2), wallMargin, wallThickness); ctx.drawLine(line(size - margin, 0, size - margin, margin)); // │ 右上
ctx.fillRect(x, y + size - wallMargin - (wallThickness / 2), wallMargin, wallThickness); ctx.drawLine(line(margin, size - margin, margin, size)); // │ 左下
ctx.fillRect(x + size - wallMargin, y + size - wallMargin - (wallThickness / 2), wallMargin, wallThickness); ctx.drawLine(line(size - margin, size - margin, size - margin, size)); // │ 右下
} else { } else {
ctx.fillRect(x, y + wallMargin - (wallThickness / 2), size, wallThickness); ctx.drawLine(line(margin, 0, margin, size)); // │ 左
ctx.fillRect(x, y + size - wallMargin - (wallThickness / 2), size, wallThickness); ctx.drawLine(line(size - margin, 0, size - margin, size)); // │ 右
ctx.fillRect(wallLeftTopX, y, wallThickness, wallMargin - (wallThickness / 2)); ctx.drawLine(line(0, margin, margin, margin)); // ─ 左上
ctx.fillRect(wallRightTopX, y, wallThickness, wallMargin - (wallThickness / 2)); ctx.drawLine(line(size - margin, margin, size, margin)); // ─ 右上
ctx.fillRect(wallLeftTopX, wallLeftBottomY, wallThickness, wallMargin + (wallThickness / 2)); ctx.drawLine(line(0, size - margin, margin, size - margin)); // ─ 左下
ctx.fillRect(wallRightTopX, wallRightBottomY, wallThickness, wallMargin + (wallThickness / 2)); ctx.drawLine(line(size - margin, size - margin, size, size - margin)); // ─ 右下
} }
return; return;
} }
if (!left && right && !top && bottom) { // ─
ctx.beginPath(); if (left && right && !top && !bottom) {
ctx.fillRect(wallLeftTopX, wallLeftTopY, size - wallMargin + (wallThickness / 2), wallThickness); ctx.drawLine(line(0, margin, size, margin)); // ─ 上
ctx.fillRect(wallLeftTopX, wallLeftTopY, wallThickness, size - wallMargin + (wallThickness / 2)); ctx.drawLine(line(0, size - margin, size, size - margin)); // ─ 下
return;
} }
if (right && bottom) { // │
ctx.fillRect(wallRightBottomX, wallRightBottomY, wallMargin + (wallThickness / 2), wallThickness); if (!left && !right && top && bottom) {
ctx.fillRect(wallRightBottomX, wallRightBottomY, wallThickness, wallMargin + (wallThickness / 2)); ctx.drawLine(line(margin, 0, margin, size)); // │ 左
} ctx.drawLine(line(size - margin, 0, size - margin, size)); // │ 右
return;
if (left && !right && !top && bottom) {
ctx.beginPath();
ctx.fillRect(x, y + wallMargin - (wallThickness / 2), size - wallMargin + (wallThickness / 2), wallThickness);
ctx.fillRect(wallRightTopX, y + wallMargin - (wallThickness / 2), wallThickness, size - wallMargin + (wallThickness / 2));
}
if (left && bottom) {
ctx.fillRect(x, wallLeftBottomY, wallMargin - (wallThickness / 2), wallThickness);
ctx.fillRect(wallLeftBottomX, wallLeftBottomY, wallThickness, wallMargin + (wallThickness / 2));
}
if (!left && right && top && !bottom) {
ctx.beginPath();
ctx.fillRect(wallLeftBottomX, y, wallThickness, size - wallMargin + (wallThickness / 2));
ctx.fillRect(wallLeftBottomX, wallLeftBottomY, size - wallMargin + (wallThickness / 2), wallThickness);
}
if (right && top) {
ctx.fillRect(wallRightTopX, y, wallThickness, wallMargin - (wallThickness / 2));
ctx.fillRect(wallRightTopX, wallRightTopY, size - wallMargin - (wallThickness * 2), wallThickness);
}
if (left && !right && top && !bottom) {
ctx.beginPath();
ctx.fillRect(x, wallLeftBottomY, size - wallMargin - (wallThickness / 2), wallThickness);
ctx.fillRect(wallRightTopX, y, wallThickness, size - wallMargin + (wallThickness / 2));
}
if (left && top) {
ctx.fillRect(wallLeftTopX, y, wallThickness, wallMargin + (wallThickness / 2));
ctx.fillRect(x, wallLeftTopY, wallMargin - (wallThickness / 2), wallThickness);
} }
// 左行き止まり
if (!left && right && !top && !bottom) { if (!left && right && !top && !bottom) {
ctx.beginPath(); ctx.drawLine(line(margin, margin, size, margin)); // ─ 上
ctx.fillRect(wallLeftTopX, wallLeftTopY, size - wallMargin + (wallThickness / 2), wallThickness); ctx.drawLine(line(margin, margin, margin, size - margin)); // │ 左
ctx.fillRect(wallLeftBottomX, wallLeftBottomY, size - wallMargin + (wallThickness / 2), wallThickness); ctx.drawLine(line(margin, size - margin, size, size - margin)); // ─ 下
ctx.fillRect(wallLeftTopX, wallLeftTopY, wallThickness, size - wallMargin - (wallThickness * 2));
return; return;
} }
// 右行き止まり
if (left && !right && !top && !bottom) { if (left && !right && !top && !bottom) {
ctx.beginPath(); ctx.drawLine(line(0, margin, size - margin, margin)); // ─ 上
ctx.fillRect(x, wallLeftTopY, size - wallMargin + (wallThickness / 2), wallThickness); ctx.drawLine(line(size - margin, margin, size - margin, size - margin)); // │ 右
ctx.fillRect(x, wallLeftBottomY, size - wallMargin + (wallThickness / 2), wallThickness); ctx.drawLine(line(0, size - margin, size - margin, size - margin)); // ─ 下
ctx.fillRect(wallRightTopX, wallRightTopY, wallThickness, size - wallMargin - (wallThickness * 2));
return; return;
} }
// 上行き止まり
if (!left && !right && !top && bottom) { if (!left && !right && !top && bottom) {
ctx.beginPath(); ctx.drawLine(line(margin, margin, size - margin, margin)); // ─ 上
ctx.fillRect(wallLeftTopX, wallLeftTopY, wallThickness, size - wallMargin + (wallThickness / 2)); ctx.drawLine(line(margin, margin, margin, size)); // │ 左
ctx.fillRect(wallRightTopX, wallRightTopY, wallThickness, size - wallMargin + (wallThickness / 2)); ctx.drawLine(line(size - margin, margin, size - margin, size)); // │ 右
ctx.fillRect(wallLeftTopX, wallLeftTopY, size - wallMargin - (wallThickness * 2), wallThickness);
return; return;
} }
// 下行き止まり
if (!left && !right && top && !bottom) { if (!left && !right && top && !bottom) {
ctx.beginPath(); ctx.drawLine(line(margin, size - margin, size - margin, size - margin)); // ─ 下
ctx.fillRect(wallLeftTopX, y, wallThickness, size - wallMargin + (wallThickness / 2)); ctx.drawLine(line(margin, 0, margin, size - margin)); // │ 左
ctx.fillRect(wallRightTopX, y, wallThickness, size - wallMargin + (wallThickness / 2)); ctx.drawLine(line(size - margin, 0, size - margin, size - margin)); // │ 右
ctx.fillRect(wallLeftBottomX, wallLeftBottomY, size - wallMargin - (wallThickness * 2), wallThickness);
return; return;
} }
if (top && bottom) { // ┌
if (!left) { if (!left && !top && right && bottom) {
ctx.beginPath(); ctx.drawLine(line(margin, margin, size, margin)); // ─ 上
ctx.fillRect(x + wallMargin - (wallThickness / 2), y, wallThickness, size); ctx.drawLine(line(margin, margin, margin, size)); // │ 左
} ctx.drawLine(line(size - margin, size - margin, size, size - margin)); // ─ 下
if (!right) { ctx.drawLine(line(size - margin, size - margin, size - margin, size)); // │ 右
ctx.beginPath(); return;
ctx.fillRect(x + size - wallMargin - (wallThickness / 2), y, wallThickness, size);
}
} }
if (left && right) {
if (!top) { // ┐
ctx.beginPath(); if (left && !right && !top && bottom) {
ctx.fillRect(x, y + wallMargin - (wallThickness / 2), size, wallThickness); ctx.drawLine(line(0, margin, size - margin, margin)); // ─ 上
} ctx.drawLine(line(size - margin, margin, size - margin, size)); // │ 右
if (!bottom) { ctx.drawLine(line(0, size - margin, margin, size - margin)); // ─ 下
ctx.beginPath(); ctx.drawLine(line(margin, size - margin, margin, size)); // │ 左
ctx.fillRect(x, y + size - wallMargin - (wallThickness / 2), size, wallThickness); return;
} }
// └
if (!left && right && top && !bottom) {
ctx.drawLine(line(margin, 0, margin, size - margin)); // │ 左
ctx.drawLine(line(margin, size - margin, size, size - margin)); // ─ 下
ctx.drawLine(line(size - margin, 0, size - margin, margin)); // │ 右
ctx.drawLine(line(size - margin, margin, size, margin)); // ─ 上
return;
}
// ┘
if (left && !right && top && !bottom) {
ctx.drawLine(line(margin, 0, margin, margin)); // │ 左
ctx.drawLine(line(0, margin, margin, margin)); // ─ 上
ctx.drawLine(line(size - margin, 0, size - margin, size - margin)); // │ 右
ctx.drawLine(line(0, size - margin, size - margin, size - margin)); // ─ 下
return;
}
// ├
if (!left && right && top && bottom) {
ctx.drawLine(line(margin, 0, margin, size)); // │ 左
ctx.drawLine(line(size - margin, 0, size - margin, margin)); // │ 右
ctx.drawLine(line(size - margin, margin, size, margin)); // ─ 上
ctx.drawLine(line(size - margin, size - margin, size, size - margin)); // ─ 下
ctx.drawLine(line(size - margin, size - margin, size - margin, size)); // │ 右
return;
}
// ┤
if (left && !right && top && bottom) {
ctx.drawLine(line(size - margin, 0, size - margin, size)); // │ 右
ctx.drawLine(line(margin, 0, margin, margin)); // │ 左
ctx.drawLine(line(0, margin, margin, margin)); // ─ 上
ctx.drawLine(line(0, size - margin, margin, size - margin)); // ─ 下
ctx.drawLine(line(margin, size - margin, margin, size)); // │ 左
return;
}
// ┬
if (left && right && !top && bottom) {
ctx.drawLine(line(0, margin, size, margin)); // ─ 上
ctx.drawLine(line(0, size - margin, margin, size - margin)); // ─ 下
ctx.drawLine(line(margin, size - margin, margin, size)); // │ 左
ctx.drawLine(line(size - margin, size - margin, size, size - margin)); // ─ 下
ctx.drawLine(line(size - margin, size - margin, size - margin, size)); // │ 右
return;
}
// ┴
if (left && right && top && !bottom) {
ctx.drawLine(line(0, size - margin, size, size - margin)); // ─ 下
ctx.drawLine(line(margin, 0, margin, margin)); // │ 左
ctx.drawLine(line(0, margin, margin, margin)); // ─ 上
ctx.drawLine(line(size - margin, 0, size - margin, margin)); // │ 右
ctx.drawLine(line(size - margin, margin, size, margin)); // ─ 上
return;
} }
} }

View file

@ -7,7 +7,7 @@
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"sourceMap": false, "sourceMap": false,
"target": "es6", "target": "es2017",
"module": "commonjs", "module": "commonjs",
"removeComments": false, "removeComments": false,
"noLib": false, "noLib": false,