theme
The look of BLOCKBUSTER 767's screens, in one place: the palette, the typefaces, the metrics every screen sizes itself from, and the style fragments the cards share.
theme
The look of BLOCKBUSTER 767's screens, in one place: the palette, the typefaces, the metrics every screen sizes itself from, and the style fragments the cards share.
local Theme = require("game.ui.theme")
local m = Theme.metrics()
{ type = "label", style = { fontSize = m.fs.title, fontFamily = Theme.font.display, color = Theme.color.cream } }
The metrics rule
Nothing is a pixel number chosen for one screen. Theme.metrics() reads the
live ui.screenSize() and derives everything from it:
- Type and rhythm are a share of the SHORTER side, so a phone held either way and a television read the same.
- Both are additionally capped against the HEIGHT. A card is a column, and a wide screen is also a short one; without that cap the card that fits a 3:4 frame runs off the bottom of a 16:9 one.
- The two big pictures —
hero(the toy on a card) andstrip(the skyline along its foot) — are budgeted straight out of the height they have to fit in. cardWcaps a card to a readable single column instead of letting it stretch across a wide monitor.
Theme.metricsFor(w, h) computes the same table for a shape the engine is not
currently running at — which is how a card is laid out and looked at for a
screen other than the one in front of you.
The palette
Warm shadow, painted wood, poster paint on the toy, crayon accents, and the gold
of a sticker star. Theme.color names them; Theme.font names the four voices
(a poster face for the logo, a heavy face for headings, a plain face for reading,
a mono for numbers, and the round childlike face the Kid speaks in).
The fragments
cardBackdrop (the playroom wash a card is printed on; its see argument is
the share of the ROOM that shows through, and the scrim's opacity is 1 - see),
panel (a raised surface with a lit top rim), row (a menu row at rest or with
the focus on it), chip (the small rounded plastic label a keycap, a pad glyph
and a touch hint are all made of), stat (a number with its name under it), and
the three motions: enterDrop, enterRise, pulse.
Nothing here animates for ever, and pulse breathes on opacity alone. A
keyframe that animates transform: scale re-measures the widget's box every
frame, which relays out the whole tree it sits in; two HUD widgets each held one
of those permanently and one frame in ten was over budget because of it.
pulse(iterations) counts — eight breaths by default — so even the opacity
animation ends.
No entrance starts from nothing. An entrance holds its first keyframe until
its delay elapses and the UI clock is the game clock, so a card opened while
something is holding engine.timeScale down would sit on that first frame.
They start dimmed and slightly displaced instead, so the worst a stalled clock
can do is leave a card looking a shade soft.
Scoped to this part · feeds back into the world's score.