feat(js): m10 extensions (pause, restart, speed-up via Frame) with tests
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
25141ce86d
commit
fd7c5f2acf
+11
-1
@@ -4,12 +4,21 @@ import { pure } from './io.js'
|
||||
/** Milliseconds between game steps. */
|
||||
export const TICK_MS = 150
|
||||
|
||||
/** Milliseconds between animation frames (m10). */
|
||||
export const FRAME_MS = 25
|
||||
|
||||
/**
|
||||
* Stream of everything that can happen to the game: `Action.Tick` every TICK_MS (from `interval`),
|
||||
* merged with the `Action` for each key press that `keyToAction` recognises (from `keyDowns`).
|
||||
*/
|
||||
export const classicActions = { step: () => todo('m09') }
|
||||
|
||||
/**
|
||||
* (m10) Like `classicActions`, but the clock emits `Action.Frame` every FRAME_MS instead of `Tick` every TICK_MS;
|
||||
* key presses are translated by `keyToAction` as before (now including pause and restart).
|
||||
*/
|
||||
export const speedActions = { step: () => todo('m10') }
|
||||
|
||||
/**
|
||||
* Fold a stream of actions into a stream of game states: start from `newGame(seed)`, apply `update` to each action
|
||||
* (scan), and emit the initial state first (startWith) so there is something to draw before anything happens.
|
||||
@@ -21,6 +30,7 @@ export const render = (state) => todo('m09')
|
||||
|
||||
/**
|
||||
* The whole program as a value, `IO<Stream<IO<unit>>>`: ask for a random seed, then turn the stream of
|
||||
* states (built from `classicActions`) into a stream of drawings (`render`). Nothing runs here.
|
||||
* states (built from `classicActions` in m09, from `speedActions` after m10) into a stream of drawings (`render`).
|
||||
* Nothing runs here.
|
||||
*/
|
||||
export const main = pure({ step: () => todo('m09') })
|
||||
|
||||
+14
-2
@@ -1,9 +1,21 @@
|
||||
import { todo } from './todo.js'
|
||||
|
||||
/**
|
||||
* How many frames pass between game steps (m10): `max(2, 8 - floor(score / 3))`.
|
||||
* Score 0-2 -> 8, 3-5 -> 7, ..., 18 and up -> 2.
|
||||
*/
|
||||
export const movesEvery = (score) => todo('m10')
|
||||
|
||||
/**
|
||||
* The one function that says how the game changes: `(state, action) -> state`.
|
||||
* `Tick` runs a game step (`tick`), `Turn` asks to change direction (`turn`);
|
||||
* every other action returns the state unchanged for now.
|
||||
*
|
||||
* m05: `Tick` runs a game step (`tick`), `Turn` asks to change direction (`turn`);
|
||||
* every other action returns the state unchanged.
|
||||
*
|
||||
* (m10) `TogglePause` switches Playing <-> Paused and does nothing in any other status.
|
||||
* (m10) `Restart` gives `newGame(state.seed)`, whatever the status.
|
||||
* (m10) `Frame` does nothing unless Playing; otherwise it adds 1 to `frame`, and when the new `frame` is a multiple of
|
||||
* `movesEvery(score)` it also runs a game step (`tick`) on that incremented state.
|
||||
*/
|
||||
export const update = (state, action) => todo('m05')
|
||||
|
||||
|
||||
+2
-1
@@ -2,7 +2,8 @@ import { todo } from './todo.js'
|
||||
|
||||
/**
|
||||
* Translate a keyboard key name (as in `KeyboardEvent.key`) into the game action it triggers, or `null`.
|
||||
* `ArrowUp`/`w`/`W` -> `Action.Turn('Up')`, `ArrowDown`/`s`/`S` -> Down, `ArrowLeft`/`a`/`A` -> Left,
|
||||
* m09: `ArrowUp`/`w`/`W` -> `Action.Turn('Up')`, `ArrowDown`/`s`/`S` -> Down, `ArrowLeft`/`a`/`A` -> Left,
|
||||
* `ArrowRight`/`d`/`D` -> Right. Any other key -> `null`.
|
||||
* (m10) `' '` (Space) -> `Action.TogglePause`, `r`/`R` -> `Action.Restart`.
|
||||
*/
|
||||
export const keyToAction = (key) => todo('m09')
|
||||
|
||||
Reference in New Issue
Block a user