export function render(ctx, level, index) { ctx.fillStyle = 'white'; const [x0, y0] = level.path[index]; const [x1, y1] = level.path[index+1] || level.path[index]; const angle = Math.atan2(y1-y0, x1-x0); clearBlack(ctx); drawGrid(ctx); drawPath(ctx, level.path); drawShip(ctx, [x0, y0], angle); level.resources .filter(({ collected }) => collected === false) .forEach(({ position}) => drawMark(ctx, '+', position[0], position[1])); drawMark(ctx, '※', level.home[0], level.home[1]); } export function clearBlack(ctx) { const { width, height } = ctx.canvas; ctx.fillStyle = 'black'; ctx.fillRect(-width, -height, 2*width, 2*height); } export function drawShip(ctx, pos, angle) { const transform = ctx.getTransform(); const { width, height } = ctx.canvas; const [x, y] = pos; ctx.translate(x, y); ctx.rotate(angle); ctx.fillStyle = 'white'; const STEP = 0.4; ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(-STEP, -STEP); ctx.lineTo(2*STEP, 0); ctx.lineTo(-STEP, STEP); ctx.lineTo(0, 0); ctx.fill(); ctx.setTransform(transform); } export function drawGrid(ctx) { ctx.scale(1, -1); ctx.strokeStyle = 'white'; ctx.fillStyle = 'white'; const { width, height } = ctx.canvas; ctx.font = `0.4px monospace`; ctx.lineWidth = 4 / Math.max(width, height); const drawLine = (start, end) => { ctx.beginPath(); ctx.moveTo(start[0], start[1]); ctx.lineTo(end[0], end[1]); ctx.stroke(); } const drawXLabel = (x, y) => { ctx.textAlign = 'right'; ctx.textBaseline = 'bottom'; ctx.fillText(`${x} `, x, y); } const drawYLabel = (x, y) => { ctx.rotate(Math.PI/2); ctx.textAlign = 'right'; ctx.textBaseline = 'bottom'; ctx.fillText(`${y} `, y, x); ctx.rotate(-Math.PI/2); } const drawGrid = (start, end, step) => { [...Array(1+Math.floor((end-start)/step)).keys()].forEach(z => { z = (step*z)+start; drawLine([z, start], [z, end]); drawLine([start, z], [end, z]); drawXLabel(z, end); drawYLabel(end, z); }); } drawGrid(-10, 10, 2); ctx.scale(1, -1); } export function drawPath(ctx, path) { const [ start, ...line ] = path; ctx.strokeStyle = 'white'; ctx.lineWidth = 0.04; ctx.beginPath(); ctx.moveTo(start[0], start[1]); line.forEach(p => ctx.lineTo(p[0], p[1])); ctx.stroke(); } export function drawMark(ctx, mark, x, y) { ctx.strokeStyle = 'white'; ctx.fillStyle = 'white'; ctx.font = `0.5px monospace`; ctx.lineWidth = 0.1; ctx.beginPath(); if (mark === '+') { ctx.arc(x, y, 0.4, 0, 2*Math.PI); } else { ctx.moveTo(x+0.4, y); ctx.lineTo(x, y+0.4); ctx.lineTo(x-0.4, y); ctx.lineTo(x, y-0.4); ctx.closePath(); } ctx.stroke(); ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(mark, x-0.02, y-0.12); }