- commit
- 3e9e948636baa8304691f41b32862d264506c7c5
- parent
- 27d2bd72c10cb88d9f5d90d57ee973cd4344d945
- author
- Dami <dami.etoile@gmail.com>
| M | src/ | 10 | ++++++---- |
| M | src/ | 14 | +++++++------- |
| M | tests/ | 21 | +++++++++++++++++++++ |
| M | tests/ | 5 | +++++ |
| M | tests/ | 4 | ++-- |
@@ -280,10 +280,12 @@ function drawAutomataCue(ctx, action, cx, cy, cell, colors) {
280280 const dx = action.dx || 0;281281 const dy = action.dy || 0;282282 const size = Math.min(10, cell * 0.13);283- const tipX = cx + dx * size / 2;284- const tipY = cy + dy * size / 2;285- const tailX = cx - dx * size / 2;286- const tailY = cy - dy * size / 2;283+ const edgeX = cx + dx * cell * 0.435;284+ const edgeY = cy + dy * cell * 0.435;285+ const tipX = edgeX + dx * size / 2;286+ const tipY = edgeY + dy * size / 2;287+ const tailX = edgeX - dx * size / 2;288+ const tailY = edgeY - dy * size / 2;287289 const wingX = dy * size / 2;288290 const wingY = dx * size / 2;289291 ctx.beginPath();@@ -265,15 +265,15 @@ export function drawAutomataStrip(
265265 const action = system.pattern[patternIndex];266266 const beatX = beatStart + beatIndex * (22 + beatGap);267267 const current = patternIndex === phase;268- const next = patternIndex === (phase + 1) % system.pattern.length;269- ctx.globalAlpha = current || next ? 1 : 0.4;270- ctx.fillStyle = next ? "#C6F432" : "#191816";271- ctx.strokeStyle = current || next ? "#C6F432" : "#4A4640";272- ctx.lineWidth = next ? 2 : 1;268+ const played = patternIndex === (phase + system.pattern.length - 1) % system.pattern.length;269+ ctx.globalAlpha = current || played ? 1 : 0.4;270+ ctx.fillStyle = current ? "#C6F432" : "#191816";271+ ctx.strokeStyle = current || played ? "#C6F432" : "#4A4640";272+ ctx.lineWidth = current ? 2 : 1;273273 ctx.fillRect(beatX, rowY + 1, 22, 22);274- if (!next) ctx.strokeRect(beatX + 0.5, rowY + 1.5, 21, 21);274+ if (!current) ctx.strokeRect(beatX + 0.5, rowY + 1.5, 21, 21);275275 const cue = automataCue(action);276- ctx.fillStyle = next ? "#0F0E0D" : current ? "#F2EEE6" : "#8E877C";276+ ctx.fillStyle = current ? "#0F0E0D" : played ? "#F2EEE6" : "#8E877C";277277 ctx.font = `${current ? "800" : "600"} 14px Recursive, monospace`;278278 ctx.textAlign = "center";279279 ctx.fillText(cue, beatX + 11, rowY + 13);@@ -189,3 +189,24 @@ test('drawBoard renders automaton wait as two centered bottom-gutter bars', () =
189189 assert.equal(cueRects.length, 2);190190 assert.ok(cueRects.every(call => call[2] > 10 + 50 * 1.5), 'wait bars belong in the bottom gutter');191191 });192+193+test('drawBoard moves the automaton chevron to the active carrier cell', () => {194+ const ctx = context();195+ const automatonState = {196+ ...state,197+ objects: [...state.objects, { id: 'bell', kind: 'object', noun: 'BELL', x: 2, y: 1 }],198+ automata: [{ id: 'bell-clock', subject: 'BELL', property: 'TICK', phase: 0, active: true, pattern: [{ action: 'move', dx: -1, dy: 0 }] }],199+ };200+ drawBoard(ctx, automatonState, {201+ x: 20,202+ y: 10,203+ cell: 50,204+ game: { properties: object => object.id === 'bell' ? ['TICK'] : [] },205+ });206+ const cueFills = ctx.calls.filter(call => call[0] === 'fill' && call[1] === '#C6F432');207+ assert.equal(cueFills.length, 1);208+ const cuePoints = ctx.calls209+ .filter(call => call[0] === 'moveTo' || call[0] === 'lineTo')210+ .flatMap(call => [call[1], call[2]]);211+ assert.ok(cuePoints.some(value => value >= 20 + 2 * 50 && value <= 20 + 2 * 50 + 50 * 0.13), 'left-facing cue stays inside the outer cell gutter');212+});@@ -64,6 +64,11 @@ try {
6464 await scene('gift');6565 await page.keyboard.press('Enter');6666 await scene('index');67+ // Wait for the index opening beat to settle before selecting its first node.68+ await page.waitForTimeout(700);69+ await page.keyboard.press('Enter');70+ // The index presents a world card before entering the selected proof.71+ await page.waitForTimeout(350);6772 await page.keyboard.press('Enter');6873 await scene('proof');6974 @@ -92,8 +92,8 @@ test('drawAutomataStrip uses one actor tile, directional beat cells, and a sente
9292 assert.equal(text.includes('ACTIVE'), false);9393 const beatRects = ctx.calls.filter((call) => call[0] === 'fillRect' && call[3] === 22);9494 assert.equal(beatRects.length, 3);95- assert.equal(beatRects[0][5], '#191816', 'just-played beat stays an outlined trail');96- assert.equal(beatRects[1][5], '#C6F432', 'next beat is the filled target');95+ assert.equal(beatRects[0][5], '#C6F432', 'current board cue is the filled target');96+ assert.equal(beatRects[1][5], '#191816', 'other beats stay in the outlined trail');9797 assert.equal(result.height, 24);9898 });9999