Talos docs

RoadEdge

Since 0.6

The road's edges at one distance: what {@link RoadLine.edge} returns.

Plain text

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

MemberSignatureDescription
halfWidthreadonly halfWidth: numberEdge of the driving surface: at(s).halfWidth.
kerbOuterreadonly kerbOuter: numberOuter edge of the kerb (halfWidth when the road has no kerb).
barrierreadonly 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.
innerreadonly inner: numberThe wall's inner face, the side facing the road.
outerreadonly outer: numberThe wall's outer face.
heightreadonly height: numberHeight above the road surface.
leftreadonly left: booleanWhether the left side has a wall here.
rightreadonly right: booleanWhether 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>