SharedSplit
Since 0.7
{@link ViewsHandle.shared}'s split options: when the shared camera splits into one view per target, and when it merges back.
Absent or invalid numbers keep the default.
Signature
export interface SharedSplit {
/**
* How two targets split the window: `"auto"` (the default) is `"left-right"` in a window wider than
* it is tall and `"top-bottom"` otherwise. Three targets always split as `"three"`, four as `"grid"`.
*/
layout?: "auto" | "left-right" | "top-bottom"
/**
* Split once the targets' spread (the widest distance between two of them, metres) is beyond this.
* Default: the spread at which the shared camera reaches `maxDistance` (at `maxFov`, if given).
*/
beyond?: number
/** Merge once the spread is back under this, metres. Default: three quarters of `beyond`; never above it. */
back?: number
/** Seconds of game time a split's or a merge's condition must hold, unbroken, before it happens. Default 0.5. */
hold?: number
}
Import: import type { SharedSplit } from "@argus/api"
Members
| Member | Signature | Description |
|---|---|---|
layout | layout?: "auto" | "left-right" | "top-bottom" | How two targets split the window: "auto" (the default) is "left-right" in a window wider than it is tall and "top-bottom" otherwise. Three targets always split as "three", four as "grid". |
beyond | beyond?: number | Split once the targets' spread (the widest distance between two of them, metres) is beyond this. Default: the spread at which the shared camera reaches maxDistance (at maxFov, if given). |
back | back?: number | Merge once the spread is back under this, metres. Default: three quarters of beyond; never above it. |
hold | hold?: number | Seconds of game time a split's or a merge's condition must hold, unbroken, before it happens. Default 0.5. |
Example
The tested fixture fixtures/recipes/game-over-restart/scenes/behaviors/game-over-restart.ts.
import type { Behavior } from "@argus/api"
/**
* A round that ends on a results screen, whose Retry button restarts the scene.
*
* Space scores until the clock runs out; then the results go up with the score written into them.
*
* Two rules decide the shape. `push`'s props are the *reason* a screen went up, not what it
* draws — a screen is described once, at load — so the values it shows are written after the
* push with `ctx.ui.set("<screen>:<id>", "text", …)`. And `ctx.session.restart()` rebuilds the
* scene at the end of the tick: every behaviour's state, the HUD and the screen stack go back to
* how the scene starts, so nothing here has to be reset by hand.
*/
interface State {
score: number
left: number
over: boolean
}
interface Props {
/** Length of a round in seconds. Default 5. */
roundSeconds?: number
}
const RESULTS = "results"
export default {
init(ctx) {
if (typeof ctx.state.score !== "number") ctx.state.score = 0
if (typeof ctx.state.left !== "number") ctx.state.left = ctx.props.roundSeconds ?? 5
if (typeof ctx.state.over !== "boolean") ctx.state.over = false
ctx.events.on("ui-activated", (event) => {
if (event.data.screen === RESULTS && event.data.id === "retry" && ctx.state.over) ctx.session.restart()
})
},
update(ctx, dt) {
if (ctx.state.over) return
if (ctx.input !== null && ctx.input.pressed("score")) ctx.state.score += 1
ctx.state.left = Math.max(0, ctx.state.left - dt)
ctx.hud.score(ctx.state.score)
ctx.hud.timer(ctx.state.left)
if (ctx.state.left > 0) return
ctx.state.over = true
ctx.ui.push(RESULTS, { reason: "round-over" })
ctx.ui.set("results:score", "text", `${ctx.state.score}`)
ctx.events.emit("round-over", { score: ctx.state.score })
},
} satisfies Behavior<State, Props>