simvx.core.ui.touch_controller¶
The on-screen controller, which is a controller.
TouchController draws a stick and buttons on the glass and publishes what the
player does with them as a real pad. A game that binds Controller.A and
Controller.LEFT_STICK gets touch play by adding one node
and writing nothing else, because nothing downstream knows the pad is drawn::
def on_ready(self):
self.add_child(TouchController())
It is a pad in every way a game can observe. While it is visible it appears
in Input.controllers and fires controller_connected like any controller, so a
lobby enumerating pads sees it; its :attr:~simvx.core.input.enums. ControllerSource is VIRTUAL, which is what a lobby filters on when it wants
only physical ones. It leaves the mapping the moment it is hidden.
Both pads at once is not a special case. With a controller plugged in and
this on screen, Input.controllers holds two entries with different sources,
and a binding that names no unit resolves against every pad at once:
any pad’s press counts and the largest-magnitude axis wins. So a player who
picks up the controller mid-game keeps playing, two thumbs and a stick do not
fight, and a game that genuinely wants one pad pins a binding to it with
Controller.A.on(pad) or pairs it to a player.
It never switches the input method. A device-sourced pad does that; this one does not, precisely so it cannot hide itself under the player’s thumb. It does go away when a real controller is used, which is the other half of the same rule.
It is a canvas layer, not a control. An on-screen pad that scrolled with
the world would be a defect rather than a choice, so the screen pinning is
built in rather than being a wrapper the game has to remember; layer is the
ordinary :class:~simvx.core.nodes_2d.canvas.CanvasLayer knob for putting it
above or below the rest of the HUD.
Module Contents¶
Classes¶
Which controls a :class: |
|
An on-screen controller, published as a controller. |
Data¶
API¶
- simvx.core.ui.touch_controller.__all__¶
[‘TouchController’, ‘TouchControllerLayout’]
- simvx.core.ui.touch_controller.VIRTUAL_CONTROLLER_NAME¶
‘On-screen controller’
- simvx.core.ui.touch_controller.VIRTUAL_CONTROLLER_GUID¶
‘simvx:touch-controller’
- class simvx.core.ui.touch_controller.TouchControllerLayout[source]¶
Bases:
enum.StrEnumWhich controls a :class:
TouchControllerputs on the glass.A layout is a choice of controls, never a set of coordinates: the geometry follows the window and the touch-target floor, so a game says what it needs a player to be able to do and nothing about where.
What differs between them is only how the player moves, and whether there is a second stick to aim with. A, B and Start are on all three, because a real pad has face buttons whatever its stick arrangement and a touch player must always be able to reach the pause menu.
Members: STICK_AND_BUTTONS: An analogue left stick. The default, and what most games with a character and an action want. TWIN_STICK: A right stick as well, for a game that aims with one. DPAD_AND_BUTTONS: A four-way D-pad in place of the left stick, for a grid or platform game where an analogue reading is noise.
Initialization
Initialize self. See help(type(self)) for accurate signature.
- STICK_AND_BUTTONS¶
‘stick_and_buttons’
- TWIN_STICK¶
‘twin_stick’
- DPAD_AND_BUTTONS¶
‘dpad_and_buttons’
- __new__(*values)¶
- __add__()¶
- __contains__()¶
- __delattr__()¶
- __dir__()¶
- __eq__()¶
- __format__()¶
- __ge__()¶
- __getattribute__()¶
- __getitem__()¶
- __getnewargs__()¶
- __getstate__()¶
- __gt__()¶
- __hash__()¶
- __iter__()¶
- __le__()¶
- __len__()¶
- __lt__()¶
- __mod__()¶
- __mul__()¶
- __ne__()¶
- __reduce__()¶
- __reduce_ex__()¶
- __repr__()¶
- __rmod__()¶
- __rmul__()¶
- __setattr__()¶
- __sizeof__()¶
- __str__()¶
- __subclasshook__()¶
- capitalize()¶
- casefold()¶
- center()¶
- count()¶
- encode()¶
- endswith()¶
- expandtabs()¶
- find()¶
- format()¶
- format_map()¶
- index()¶
- isalnum()¶
- isalpha()¶
- isascii()¶
- isdecimal()¶
- isdigit()¶
- isidentifier()¶
- islower()¶
- isnumeric()¶
- isprintable()¶
- isspace()¶
- istitle()¶
- isupper()¶
- join()¶
- ljust()¶
- lower()¶
- lstrip()¶
- partition()¶
- removeprefix()¶
- removesuffix()¶
- replace()¶
- rfind()¶
- rindex()¶
- rjust()¶
- rpartition()¶
- rsplit()¶
- rstrip()¶
- split()¶
- splitlines()¶
- startswith()¶
- strip()¶
- swapcase()¶
- title()¶
- translate()¶
- upper()¶
- zfill()¶
- __deepcopy__(memo)¶
- __copy__()¶
- name()¶
- value()¶
- class simvx.core.ui.touch_controller.TouchController(**kwargs)[source]¶
Bases:
simvx.core.nodes_2d.canvas.CanvasLayerAn on-screen controller, published as a controller.
Add one and a game that already reads
Controllerbuttons and sticks bindings is playable with two thumbs; there is nothing else to wire up.- Attr:
layoutsays how the player moves and :attr:buttonswhich buttons they get, and neither takes a coordinate.
Example: def on_ready(self): self.add_child(TouchController()) # or, for a twin-stick game with four face buttons: self.add_child(TouchController( layout=”twin_stick”, buttons=(Controller.A, Controller.B, Controller.X, Controller.Y), ))
Initialization
- layout¶
‘Property(…)’
- buttons¶
‘Property(…)’
- layer¶
‘Property(…)’
- auto_hide¶
‘Property(…)’
- visible¶
‘Property(…)’
- property controller: simvx.core.input.devices.ControllerDevice | None[source]¶
This pad as a :class:
~simvx.core.input.devices.ControllerDevice, or None.None while the pad is not on screen, when it is not in
Input.controllerseither.
- property pointer_types: frozenset[simvx.core.input.enums.PointerType] | None[source]¶
The kinds of pointer the drawn controls answer, fingers alone by default.
A mouse click in the pad’s area passes through to the game, so a desktop game can shoot where the stick is drawn. A game tested with a mouse, or played with a pen, widens it:
pad.pointer_types = frozenset({PointerType.TOUCH, PointerType.MOUSE}). None answers every pointer.
- class Band¶
Bases:
enum.IntEnum- BACKGROUND¶
None
- WORLD¶
0
- UI¶
1000
- OVERLAY¶
2000
- __abs__()¶
- __add__()¶
- __and__()¶
- __bool__()¶
- __ceil__()¶
- __delattr__()¶
- __dir__()¶
- __divmod__()¶
- __eq__()¶
- __float__()¶
- __floor__()¶
- __floordiv__()¶
- __format__()¶
- __ge__()¶
- __getattribute__()¶
- __getnewargs__()¶
- __getstate__()¶
- __gt__()¶
- __hash__()¶
- __index__()¶
- __int__()¶
- __invert__()¶
- __le__()¶
- __lshift__()¶
- __lt__()¶
- __mod__()¶
- __mul__()¶
- __ne__()¶
- __neg__()¶
- __new__()¶
- __or__()¶
- __pos__()¶
- __pow__()¶
- __radd__()¶
- __rand__()¶
- __rdivmod__()¶
- __reduce__()¶
- __reduce_ex__()¶
- __repr__()¶
- __rfloordiv__()¶
- __rlshift__()¶
- __rmod__()¶
- __rmul__()¶
- __ror__()¶
- __round__()¶
- __rpow__()¶
- __rrshift__()¶
- __rshift__()¶
- __rsub__()¶
- __rtruediv__()¶
- __rxor__()¶
- __setattr__()¶
- __sizeof__()¶
- __str__()¶
- __sub__()¶
- __subclasshook__()¶
- __truediv__()¶
- __trunc__()¶
- __xor__()¶
- as_integer_ratio()¶
- bit_count()¶
- bit_length()¶
- conjugate()¶
- class denominator¶
- class imag¶
- is_integer()¶
- class numerator¶
- class real¶
- to_bytes()¶
- __deepcopy__(memo)¶
- __copy__()¶
- name()¶
- value()¶
- offset¶
‘Property(…)’
- rotation¶
‘Property(…)’
- scale_val¶
‘Property(…)’
- follow_viewport¶
‘Property(…)’
- environment¶
‘Property(…)’
- post_processed¶
‘Property(…)’
- property transform_render_dirty: bool¶
- strict_errors: ClassVar[bool]¶
True
- dev_checks: ClassVar[bool]¶
None
- dev_warnings: ClassVar[bool]¶
None
- freeze_check_interval: ClassVar[float]¶
1.0
- script_error_raised¶
‘Signal(…)’
- dynamic: bool¶
False
- update_mode¶
‘Property(…)’
- focus_mode¶
‘Property(…)’
- drag_threshold¶
‘Property(…)’
- focus_entered¶
‘Signal(…)’
- focus_exited¶
‘Signal(…)’
- __properties__: ClassVar[dict[str, simvx.core.descriptors.Property]]¶
None
- classmethod __init_subclass__(**kwargs)¶
- property name: str¶
- property visible_in_tree: bool¶
- property input_player: simvx.core.input.players.InputPlayer¶
- property input_context: simvx.core.input.contexts.InputContext | None¶
- reset_error() None¶
- add_child(node: simvx.core.node.T) simvx.core.node.T¶
- remove_child(node: simvx.core.node.Node) None¶
- reparent(new_parent: simvx.core.node.Node)¶
- node_at(path, default=_NO_DEFAULT)¶
- find(target, *, direct: bool = False)¶
- find_all(target, *, direct: bool = False)¶
- expect(target, *, direct: bool = False)¶
- ancestor(target)¶
- walk(*, include_self: bool = True) collections.abc.Iterator[simvx.core.node.Node]¶
- property path: str¶
- property is_scene_root: bool¶
- add_to_group(group: str)¶
- remove_from_group(group: str)¶
- is_in_group(group: str) bool¶
- on_ready() None¶
- on_update(dt: float) None¶
- on_fixed_update(dt: float) None¶
- on_draw(canvas) None¶
- on_draw_3d(gizmos) None¶
- on_picked(event: simvx.core.input.events.PickEvent) bool | None¶
- start_coroutine(gen: simvx.core.descriptors.Coroutine) simvx.core.descriptors.CoroutineHandle¶
- stop_coroutine(gen_or_handle)¶
- property focused: bool¶
- property focus_rect: tuple[float, float, float, float] | None¶
- drag_threshold_for(pointer_type: simvx.core.input.enums.PointerType | str) float¶
- grab_focus() None¶
- release_focus() None¶
- capture_pointer(pointer_id: int | None = None) None¶
- release_pointer(pointer_id: int | None = None) None¶
- queue_redraw() None¶
- property render_dirty: bool¶
- clear_children()¶
- destroy()¶
- property destroying: bool¶
- call_deferred(method: collections.abc.Callable[..., Any], *args: Any) None¶
- property app¶
- property tree: simvx.core.scene_tree.SceneTree¶
- property viewport_size: simvx.core.math.types.Vec2¶
- property viewport_insets: tuple[float, float, float, float]¶
- property physics¶
- property physics_2d¶
- __getitem__(key: str)¶
- classmethod get_properties() dict[str, simvx.core.descriptors.Property]¶
- __repr__()¶