simvx.core.input.tick

What one physics tick was given: :class:TickInput and the pieces it holds.

A frame runs zero, one or several physics ticks, and an input edge belongs to exactly one moment. Held state is a question about now and answers the same whenever it is asked inside one tick; an edge is a question about a change, and handing the same change to three ticks makes a game jump three times on a fast monitor and not at all on a slow one.

So each tick is given a snapshot. Held state is the state at that tick. Edges are populated on the frame’s first tick and empty on the rest, so a frame running three ticks delivers each press once, to the first, and a frame that runs no tick carries its edges to the next frame’s first tick. Inside on_fixed_update the ordinary queries read this rather than the frame::

def on_fixed_update(self, dt):
    if Input.just_pressed("jump") and self.is_on_floor():   # once, whatever the framerate
        self.velocity.y = -450.0
    self.velocity.x = Input.value("move").x * 250.0         # the state at this tick

A TickInput holds no node references and nothing live: every field is a frozen set, an immutable mapping or a plain value, so it pickles, it can be recorded, and a test can hand one straight to a tick (tree.physics_tick(dt, tick_input=...)) rather than driving a device to produce it.

Module Contents

Classes

ActionState

What one action reads for one player.

InputEdge

One action opening or closing, with who it belonged to and when.

ControllerSnapshot

One pad as a tick was given it: the indices held and where each axis was.

TickInput

The input one physics tick sees, read through Input inside the tick.

Data

API

simvx.core.input.tick.__all__

[‘ActionState’, ‘ControllerSnapshot’, ‘InputEdge’, ‘TickInput’]

class simvx.core.input.tick.ActionState[source]

Bases: typing.NamedTuple

What one action reads for one player.

The three answers the three action queries give, kept together because they are written together: a button action bound to a trigger is open or not, reads as a bool, and has an analogue strength.

pressed: bool

None

value: bool | float | simvx.core.math.types.Vec2

None

strength: float

None

class simvx.core.input.tick.InputEdge[source]

Bases: typing.NamedTuple

One action opening or closing, with who it belonged to and when.

Four required fields rather than three and a default. The player matters because action state is per player, and a default of 0 on a co-op edge is wrong rather than absent. The time is the device event’s, on the monotonic clock every other input time is on, and a plausible-looking 0.0 would say the press happened at process start; a tick reading an edge one tick late is exactly the case that wants the real one.

action: str

None

pressed: bool

None

player: int

None

time: float

None

class simvx.core.input.tick.ControllerSnapshot[source]

Bases: typing.NamedTuple

One pad as a tick was given it: the indices held and where each axis was.

Indices as the pad reports them, which its layout names: the standard positions for a pad a mapping database laid out, the driver’s own for one it did not.

buttons: frozenset[int]

‘frozenset(…)’

axes: collections.abc.Mapping[int, float]

None

class simvx.core.input.tick.TickInput[source]

The input one physics tick sees, read through Input inside the tick.

Input.tick is this object while on_fixed_update is running and None everywhere else, so a tick can read the whole snapshot at once (to record it, to hand it to a replay) as well as query through Input.

The device half (keys, mouse_buttons, controllers, the pointer fields) is honest: it says what the machine was doing, whoever the input went to. actions and edges are routed: they are what this tree was given, resolved through its bindings.

keys: frozenset[int]

‘frozenset(…)’

mouse_buttons: frozenset[int]

‘frozenset(…)’

controllers: collections.abc.Mapping[int, simvx.core.input.tick.ControllerSnapshot]

‘field(…)’

actions: collections.abc.Mapping[tuple[int, str], simvx.core.input.tick.ActionState]

‘field(…)’

mouse_position: tuple[float, float]

(0.0, 0.0)

mouse_delta: tuple[float, float]

(0.0, 0.0)

scroll_delta: tuple[float, float]

(0.0, 0.0)

pointers: collections.abc.Mapping[int, simvx.core.input.events.PointerState]

‘field(…)’

edges: tuple[simvx.core.input.tick.InputEdge, ...]

()

time: float

‘field(…)’