---
title: "vek reducer"
order: 2
author:
- name: "Declan Naughton ๐งฎ๐จโ๐ป๐ง"
url: "https://calcwithdec.dev/about.html"
description: "some visuals for 'main' model"
format:
html:
echo: false
resources:
- '../../models/main/*.js'
- '../../models/main/*.js.map'
- './models/**'
---
# Some visuals
```{ojs}
// https://observablehq.com/d/867e1424e1d093ab
viewof keys = {
let e = html`<div class='target' style='color:pink; background:#eee' tabIndex=1>Keyboard target</div>`;
let keys = [];
e.value = keys;
let gap = new Date();
e.addEventListener("keyup", (evt) => {
keys.push({
key: evt.key,
delay: new Date() - gap,
frame: mutable frame_val
});
gap = new Date();
e.dispatchEvent(new CustomEvent("input"));
evt.preventDefault(); // for revealjs? not enough
});
e.addEventListener("keydown", (evt) => {
evt.preventDefault();
});
return e;
}
keys
mutable frame_val = 0
{
frame_in;
mutable frame_val = frame_in;
}
import {Scrubber} from "@mbostock/scrubber"
keys_stream_in = [{ key: "ArrowRight", frame: 20 },
{ key: "ArrowUp", frame: 30 },
{ key: "ArrowLeft", frame: 45 },{ key: "ArrowLeft", frame: 48 },
{ key: "ArrowUp", frame: 60 },
{ key: "ArrowUp", frame: 64 },
{ key: "ArrowUp", frame: 100 },
{ key: "ArrowUp", frame: 200 },
{ key: "ArrowUp", frame: 300 },
{ key: "ArrowUp", frame: 301 },
{ key: "ArrowUp", frame: 304 }]
mutable key_stream_in2 = [{ key: "ArrowRight", frame: 20 }]
import {viewof keys as keys2} from 'd/867e1424e1d093ab'
keys2
//main.keys({frame_in,keys_stream_in})
viewof g_in = Inputs.range([-1,2], {value:1, step:0.01, label:'g_in'})
viewof s_in = Inputs.range([-6,6], {value:4, step:0.01, label:'s_in'})
viewof jump_limit_in = Inputs.range([0,3], {value:2, step:1, label:'jump_limit_in'})
```
gameplay (for fixed key stream) (workings are below)
```{ojs}
viewof frame_in = Scrubber(_.range(0,900), {delay: 100, autoplay:false})
viewof keys
main
viz_spec = ({
data: {name: 'data'},
datasets: {data: []},
"mark": {"type": "text", "align": "left", "tooltip": true},
encoding: {
x: {field: 'player_x', axis:{grid:false}, type:'quantitative', scale: {domain:[-30,50]}},
y: {value: 15, axis:{grid:false}, type:'quantitative', scale: {domain:[-5,50]}},
//y: {field: 'player_y', axis:{grid:false}, type:'quantitative', scale: {domain:[-5,50]}},
size: {value: 20},
text: {value: 'P'}
//text: {field: 'keys_annotation', type: 'nominal'}, // keys_annotation includes the emoji, will fix
},
height:150,
width: 200,
})
mutable state = ({player_x: 10, player_vx:1, key_left:0, key_right:0});
state
md`hello; s/t wrong here!`
main.player_x({player_x0_in: state.player_x,player_vx0_in: state.player_vx, key_left_in: false, key_right_in:false})
main.player_vx({player_x0_in: state.player_x,player_vx0_in: state.player_vx, key_left_in: false, key_right_in:false})
{
//frame_in;
//mutable state = {player_x: main.player_x({player_x0_in: state.player_x,player_vx0_in: state.player_vx, key_left_in: false, key_right_in:false}), player_vx:({player_x0_in: state.player_x,player_vx0_in: state.player_vx, key_left_in: false, key_right_in:false}), key_left:0, key_right:0};
}
md`this updates circularly; should be driven by frame_in`
md`will i pass frame_in in and keep history?`
{
//frame_in;
let frame
(function tick() {
mutable state = ({player_x: main.player_x({player_x0_in: state.player_x,player_vx0_in: state.player_vx, key_left_in: false, key_right_in:false}), player_vx:main.player_vx({player_x0_in: state.player_x,player_vx0_in: state.player_vx, key_left_in: true, key_right_in:false}), key_left:0, key_right:0});
viz.data("data", [mutable state]).resize().run();
frame = requestAnimationFrame(tick);
})();
invalidation.then(() => cancelAnimationFrame(frame));
}
{
//viz.data("data", [mutable state]).resize().run();
}
viz_data = [{}] /*calcuvegadata({
models: [main],
spec: viz_spec,
domains: { },
input_cursors: [{frame_in, keys_stream_in: keys.filter(d =>d.frame == frame_in) , g_in, s_in, jump_limit_in}]
})*/
viz_data
viewof viz = embed(viz_spec)
/*{
//console.log(Object.entries(main.player_x$m.cache).length)
frame_in; keys_stream_in; g_in; s_in; jump_limit_in;
viz.data("data", [state]).resize().run();
}*/
//mutable viz_data0 = [] // includes data in spec for when I Open in Vega Editor
//htl.html`<button onclick=${() => (mutable viz_data0 = viz_data)}>insert data -> vega editor (dev)</button>`
import { fps, color } from "@ondras/fps"
div = {
let node = html`<div>fps: ${Math.floor(fps)}</div>`;
node.style.fontSize = "1em";
node.style.color = color;
node.style.textShadow = "0 0 0.08em #000";
return node;
}
```
# Appendix
```{ojs}
import { calcuvegadata } from "baafa4b071a5b66a" // draft API!
import { calcuvizspec } from "@declann/little-calcu-helpers"
embed = require('vega-embed');
entrypoint = './models/vek-reducer.cul.js'//Inputs.select(['models/main/main.cul.js'], {label:'entrypoint'})
entrypoint_no_cul_js = entrypoint.slice(0,-7)
main = require(`${entrypoint_no_cul_js}.js`);
//import { player_x } from './models/vek-nomemo_esm/cul_scope_0.mjs'
/*md`player x?`
player_x*/
introspection_fetch = await fetch(`${entrypoint_no_cul_js}.introspection.json`)
introspection = introspection_fetch.json({typed:true})
introspection_nomemo_fetch = await fetch(`${entrypoint_no_cul_js}-nomemo.introspection.json`)
introspection_nomemo = introspection_nomemo_fetch.json({typed:true})
inputs = Object.values(introspection.cul_functions).filter(d => d.reason == 'input definition').map(d => d.name).sort()
formulae = Object.values(introspection.cul_functions).filter(d => d.reason == 'definition').map(d => d.name)
// formulae excluding pure inputs
formulae_not_inputs = Object.values(introspection.cul_functions).filter(d => d.reason == 'definition' && inputs.indexOf(d.name+'_in') == -1).map(d => d.name)
```