feat: Simplification of UI and icons creation
This commit is contained in:
+47
-30
@@ -3,15 +3,13 @@
|
||||
|
||||
import { generatorQuote, isUnlocked, materialPurchase, upgradeVisible } from '../engine/engine.js';
|
||||
import { t } from '../services/i18n.js';
|
||||
import { $, h, icon, refreshStaticIcons } from './dom.js';
|
||||
import { $, h, icon, makeBuyable, refreshStaticIcons, setBuyable } from './dom.js';
|
||||
import { bump, floater, pop, purchased } from './fx.js';
|
||||
import { effectText, setText } from './text.js';
|
||||
|
||||
const SLIDER_STEPS = 1000;
|
||||
const MARKET_TOLERANCE = 1.15; // demand within ±15 % of output counts as balanced
|
||||
const TREND ={ '-1': '▼', 1: '▲' }; // last move of the material price
|
||||
|
||||
function setText(node, text) {
|
||||
if (node.textContent !== text) node.textContent = text;
|
||||
}
|
||||
const TREND = { '-1': '▼', 1: '▲' }; // last move of the material price
|
||||
|
||||
/**
|
||||
* @param actions callbacks into the game: make, buyMaterial, buyMarketing,
|
||||
@@ -44,6 +42,7 @@ export function createView(actions) {
|
||||
let ctx;
|
||||
let fmt;
|
||||
let buyAmount = 1;
|
||||
let current = null; // the state and derived values of the last refresh
|
||||
let generatorRows = new Map();
|
||||
let upgradeRows = new Map();
|
||||
let upgradeSignature = null;
|
||||
@@ -53,9 +52,22 @@ export function createView(actions) {
|
||||
|
||||
// ---------------------------------------------------------------- controls
|
||||
|
||||
el.make.addEventListener('click', () => actions.make());
|
||||
el.buyMaterial.addEventListener('click', () => actions.buyMaterial());
|
||||
el.buyMarketing.addEventListener('click', () => actions.buyMarketing());
|
||||
el.make.addEventListener('click', (event) => {
|
||||
if (!actions.make()) return;
|
||||
pop(el.make);
|
||||
// The "+N" rises from the pointer (or from the button when used with the keyboard).
|
||||
const at = event.clientX || event.clientY ? { x: event.clientX, y: event.clientY } : undefined;
|
||||
floater(el.make, `+${fmt.number(current.d.clickYield)}`, at);
|
||||
});
|
||||
el.buyMaterial.addEventListener('click', () => {
|
||||
if (actions.buyMaterial()) purchased(el.buyMaterial, '+');
|
||||
});
|
||||
el.buyMarketing.addEventListener('click', () => {
|
||||
if (actions.buyMarketing()) {
|
||||
purchased(el.buyMarketing, '+1');
|
||||
bump(el.buyMarketingInfo);
|
||||
}
|
||||
});
|
||||
|
||||
const priceFromSlider = () => {
|
||||
const { minPrice, maxPrice } = ctx.rules.market;
|
||||
@@ -78,24 +90,17 @@ export function createView(actions) {
|
||||
|
||||
// ------------------------------------------------------------------- lists
|
||||
|
||||
function effectText(effect) {
|
||||
const params = { value: fmt.number(effect.value) };
|
||||
if (effect.target) params.target = t(`theme.gen.${effect.target}.name`);
|
||||
if (effect.type === 'batch_discount') params.percent = fmt.number(Math.round((1 - effect.value) * 100));
|
||||
return t(`effect.${effect.type}`, params);
|
||||
/** What a click on a generator block buys right now (at least one). */
|
||||
function shownQuote(id) {
|
||||
const quote = generatorQuote(current.state, ctx, id, buyAmount);
|
||||
return quote.count > 0 ? quote : generatorQuote(current.state, ctx, id, 1);
|
||||
}
|
||||
|
||||
function generatorRow(g) {
|
||||
const owned = h('span', { class: 'badge' });
|
||||
const rate = h('span');
|
||||
const amount = h('span', { class: 'btn__label' });
|
||||
const amount = h('strong');
|
||||
const cost = h('small');
|
||||
const buy = h(
|
||||
'button',
|
||||
{ class: 'btn btn--buy', type: 'button', onclick: () => actions.buyGenerator(g.id, buyAmount) },
|
||||
amount,
|
||||
cost,
|
||||
);
|
||||
const root = h(
|
||||
'li',
|
||||
{ class: 'card', hidden: true },
|
||||
@@ -107,14 +112,20 @@ export function createView(actions) {
|
||||
h('p', { class: 'card__desc', text: t(`theme.gen.${g.id}.desc`) }),
|
||||
h('p', { class: 'card__meta' }, rate),
|
||||
),
|
||||
buy,
|
||||
h('div', { class: 'card__price' }, amount, cost),
|
||||
);
|
||||
makeBuyable(root, () => {
|
||||
const { count } = shownQuote(g.id);
|
||||
if (!actions.buyGenerator(g.id, buyAmount)) return;
|
||||
purchased(root, `+${fmt.number(count)}`);
|
||||
bump(owned);
|
||||
});
|
||||
el.generators.append(root);
|
||||
return { root, owned, rate, amount, cost, buy };
|
||||
return { root, owned, rate, amount, cost };
|
||||
}
|
||||
|
||||
function upgradeRow(u) {
|
||||
const cost = h('small');
|
||||
const cost = h('strong');
|
||||
const root = h(
|
||||
'li',
|
||||
{ class: 'card' },
|
||||
@@ -123,11 +134,16 @@ export function createView(actions) {
|
||||
'div',
|
||||
{ class: 'card__body' },
|
||||
h('h3', { class: 'card__title', text: t(`theme.upg.${u.id}`) }),
|
||||
h('p', { class: 'card__desc', text: effectText(u.effect) }),
|
||||
h('p', { class: 'card__desc', text: effectText(u.effect, fmt) }),
|
||||
),
|
||||
h('button', { class: 'btn btn--buy', type: 'button', onclick: () => actions.buyUpgrade(u.id) }, cost),
|
||||
h('div', { class: 'card__price' }, cost),
|
||||
);
|
||||
return { root, cost, buy: root.lastElementChild, upgrade: u };
|
||||
makeBuyable(root, () => {
|
||||
if (!actions.buyUpgrade(u.id)) return;
|
||||
purchased(root, '✓');
|
||||
bump(el.upgradeCount);
|
||||
});
|
||||
return { root, cost, upgrade: u };
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ public
|
||||
@@ -160,9 +176,9 @@ export function createView(actions) {
|
||||
|
||||
setText(row.owned, t('ui.owned', { count: fmt.number(owned) }));
|
||||
setText(row.rate, t('ui.rateEach', { rate: fmt.number(d.perGenerator[g.id]) }));
|
||||
setText(row.amount, t('ui.buyN', { count: fmt.number(quote.count) }));
|
||||
setText(row.amount, `×${fmt.number(quote.count)}`);
|
||||
setText(row.cost, money(quote.cost));
|
||||
row.buy.disabled = state.funds < quote.cost;
|
||||
setBuyable(row.root, state.funds >= quote.cost);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +193,7 @@ export function createView(actions) {
|
||||
}
|
||||
for (const row of upgradeRows.values()) {
|
||||
setText(row.cost, money(row.upgrade.cost));
|
||||
row.buy.disabled = state.funds < row.upgrade.cost;
|
||||
setBuyable(row.root, state.funds >= row.upgrade.cost);
|
||||
}
|
||||
setText(
|
||||
el.upgradeCount,
|
||||
@@ -222,6 +238,7 @@ export function createView(actions) {
|
||||
|
||||
/** @param flow { income } smoothed funds per second */
|
||||
function update(state, d, flow) {
|
||||
current = { state, d };
|
||||
setText(el.units, fmt.number(Math.floor(state.units)));
|
||||
setText(el.funds, money(state.funds));
|
||||
setText(el.material, fmt.number(Math.floor(state.material)));
|
||||
|
||||
Reference in New Issue
Block a user