31 lines
1.2 KiB
JavaScript
31 lines
1.2 KiB
JavaScript
// m06 view: the picture is plain data (a list of shapes); drawing it is somebody else's job (m07).
|
|
|
|
/** Pixels per board cell. */
|
|
export const CELL = 20
|
|
|
|
const rect = (x, y, w, h, color) => ({ tag: 'Rect', x, y, w, h, color })
|
|
const text = (x, y, str, size, align) => ({ tag: 'Text', x, y, text: str, color: '#ffffff', size, align })
|
|
|
|
// One cell, inset by 1px so neighbouring segments show a gap.
|
|
const cell = (p, color) => rect(p.x * CELL + 1, p.y * CELL + 1, CELL - 2, CELL - 2, color)
|
|
|
|
const overlay = (state) => {
|
|
const cx = (state.width * CELL) / 2
|
|
const cy = (state.height * CELL) / 2
|
|
const banner = (title, hint) => [text(cx, cy, title, 32, 'center'), text(cx, cy + 30, hint, 16, 'center')]
|
|
switch (state.status) {
|
|
case 'Paused': return banner('Paused', 'Press Space to resume')
|
|
case 'GameOver': return banner('Game Over', 'Press R to restart')
|
|
case 'Won': return banner('You Win!', 'Press R to restart')
|
|
default: return []
|
|
}
|
|
}
|
|
|
|
export const view = (state) => [
|
|
rect(0, 0, state.width * CELL, state.height * CELL, '#111111'),
|
|
...(state.apple === null ? [] : [cell(state.apple, '#e53935')]),
|
|
...state.snake.map((p, i) => cell(p, i === 0 ? '#7cb342' : '#43a047')),
|
|
text(6, 18, `Score: ${state.score}`, 16, 'left'),
|
|
...overlay(state),
|
|
]
|