M src/codebox.js => src/codebox.js +6 -0
@@ 54,6 54,12 @@ const systemDefinitions = {
tick: {
outputs: ['t'],
},
+ literal: {
+ outputs: ['v'],
+ },
+ literalFloat: {
+ outputs: ['v'],
+ },
}
const utilityDefinitions = {
M src/game.js => src/game.js +10 -1
@@ 72,7 72,7 @@ export function drawBox(box) {
tint: hsv(.8, .1, .95),
fontSize: FONT_SIZE
})
- boxText.text = box.type;
+ boxText.text = `${box.type} ${box.label}`;
boxText.x = TILE_SIZE * .1
boxText.y = TILE_SIZE * .1
@@ 145,11 145,15 @@ export function addBox(data, gameData, gs) {
inputQueue: [],
inputs: {},
outputs: [],
+ clicked: false,
+ label: '',
};
+ const boxData = data.literalValue ? { value: data.literalValue } : boxDef.data;
const box = {
...defaults,
...data,
...boxDef,
+ data: boxData,
pos,
}
gameData.codeBoxes.push(box);
@@ 212,6 216,11 @@ export function evaluateNewPieces (newKey, gameData, gs) {
}
// Just evaluate all boxes every frame for now
newPieces = newPieces.concat(codeBoxes.flatMap(box => {
+ const clicked = box.clicked;
+ box.clicked = false;
+ if (box.type === 'literal' && clicked) {
+ return emit(box.data.value, box, box.outputs[0]);
+ }
if (!box.triggered) {
return []
}
M src/lang.js => src/lang.js +4 -0
@@ 122,6 122,10 @@ export function interpret (expression, initial = null) {
const value = r.stack[1];
return { push: [value.mod(limit)], pop: 2 }
}
+ else if (code === 'flr') {
+ const value = r.stack[0];
+ return { push: [Math.floor(value)], pop: 1 }
+ }
else if (code === 'jcn') {
const condition = r.stack[1];
const branch = r.stack[0];
M src/main.js => src/main.js +12 -2
@@ 159,7 159,16 @@ function initUI() {
const codeBoxButton = document.createElement('button');
codeBoxButton.textContent = 'Add';
codeBoxButton.addEventListener('click', () => {
- addBox({pos: new Vec(width / TILE_SIZE / 2, height / TILE_SIZE - 15), type: codeTypeDropdown.value}, gameData, gs)
+ const pos = new Vec(width / TILE_SIZE / 2, height / TILE_SIZE - 15);
+ if (['literal', 'literalFloat'].includes(codeTypeDropdown.value)) {
+ let literalValue = prompt('provide a literal value');
+ if (codeTypeDropdown.value === 'literalFloat') {
+ literalValue = parseFloat(literalValue);
+ }
+ addBox({pos, type: 'literal', literalValue, label: literalValue}, gameData, gs)
+ } else {
+ addBox({pos, type: codeTypeDropdown.value}, gameData, gs)
+ }
});
toolbarEl.appendChild(codeBoxButton);
}
@@ 239,7 248,7 @@ def clear:
s: parse(`val #speed kep`),
i: parse(`
#step get #speed get add #last len mod dup #step kep
-#last swp at
+flr #last swp at
#mag get mul
@@ 453,6 462,7 @@ function mousedown (e) {
startOutput: outputClicked,
};
} else if (boxClicked) {
+ boxClicked.clicked = true;
gameData.moving = {
type: 'box',
object: boxClicked,