RoadEdge
Since 0.6
The road's edges at one distance: what {@link RoadLine.edge} returns.
Every number is metres from the centre line, always positive (the left edge is the mirror of the right).
Signature
export interface RoadEdge {
/** Edge of the driving surface: `at(s).halfWidth`. */
readonly halfWidth: number
/** Outer edge of the kerb (`halfWidth` when the road has no kerb). */
readonly kerbOuter: number
/** The wall here, or null when the road has none or `s` is in a `gapsAt` range. A car's centre stays inside `inner - radius`. */
readonly barrier: {
/** The wall's inner face, the side facing the road. */
readonly inner: number
/** The wall's outer face. */
readonly outer: number
/** Height above the road surface. */
readonly height: number
/** Whether the left side has a wall here. */
readonly left: boolean
/** Whether the right side has a wall here. */
readonly right: boolean
} | null
}
Import: import type { RoadEdge } from "@argus/api"
Members
| Member | Signature | Description |
|---|---|---|
halfWidth | readonly halfWidth: number | Edge of the driving surface: at(s).halfWidth. |
kerbOuter | readonly kerbOuter: number | Outer edge of the kerb (halfWidth when the road has no kerb). |
barrier | readonly barrier: { | The wall here, or null when the road has none or s is in a gapsAt range. A car's centre stays inside inner - radius. |
inner | readonly inner: number | The wall's inner face, the side facing the road. |
outer | readonly outer: number | The wall's outer face. |
height | readonly height: number | Height above the road surface. |
left | readonly left: boolean | Whether the left side has a wall here. |
right | readonly right: boolean | Whether the right side has a wall here. |
Example
The tested fixture fixtures/recipes/jump-pad-and-elevator/scenes/behaviors/elevator.ts.
import type { Behavior } from "@argus/api"
/**
* A lift: a kinematic slab that rides between two heights and waits at each end.
*
* It only moves itself, by `position`. Whoever stands on it is carried by the engine — the character
* controller follows moving ground on its own — so there is no rider list and no parenting here.
*/
interface State {
/** +1 going up, -1 going down, 0 waiting. */
heading: number
/** Seconds left to wait at the current end. */
wait: number
/** Where the next leg goes once the wait is over. */
next: number
}
interface Props {
/** Height of the slab's origin at the bottom and the top, metres. */
bottom?: number
top?: number
/** Metres per second. Default 1.5. */
speed?: number
/** Seconds to wait at each end. Default 1. */
pause?: number
}
export default {
init(ctx) {
if (typeof ctx.state.heading !== "number") ctx.state = { heading: 0, wait: ctx.props.pause ?? 1, next: 1 }
},
update(ctx, dt) {
const bottom = ctx.props.bottom ?? 0
const top = ctx.props.top ?? 4
const p = ctx.entity.position
if (ctx.state.heading === 0) {
ctx.state.wait -= dt
if (ctx.state.wait <= 0) ctx.state.heading = ctx.state.next
return
}
let y = p[1] + ctx.state.heading * (ctx.props.speed ?? 1.5) * dt
const end = ctx.state.heading > 0 ? top : bottom
if ((ctx.state.heading > 0 && y >= end) || (ctx.state.heading < 0 && y <= end)) {
y = end
ctx.state.next = -ctx.state.heading
ctx.state.heading = 0
ctx.state.wait = ctx.props.pause ?? 1
}
// `position`, not `teleport`: this is a move, so it is smoothed between ticks and the rider is
// carried by exactly the distance the slab travelled.
ctx.entity.position = [p[0], y, p[2]]
},
} satisfies Behavior<State, Props>