Skip to content

Controls (Virtual Gamepad)

Provides ready-to-use joystick and action buttons for touch devices. Runs entirely client-side with zero external dependencies.

Two usage modes are available:

  1. JS API — Programmatic control via gameTegra.controls.*
  2. Custom Elements<gametegra-joystick> and <gametegra-buttons> HTML tags

controls.show

Shows controls on screen. By default creates an analog joystick (left) + A/B buttons (right).

js
// Default: analog joystick + A/B buttons
gameTegra.controls.show()

// Custom configuration
gameTegra.controls.show({
  joystick: { type: 'dpad' },
  buttons: [
    { code: 'fire',  label: 'Fire',  icon: 'crosshair' },
    { code: 'jump',  label: 'Jump',  icon: 'arrow_up' },
  ],
  opacity: 0.8,
  theme: 'dark',
})

// Render into your own container
gameTegra.controls.show({
  target: 'game-controls',
})

Parameters (ControlsConfig):

FieldTypeRequiredDefaultDescription
targetstringNonullHTML element ID — renders inside that element if provided, otherwise fixed overlay
joystickboolean | objectNotruefalse=disabled, true=analog, or object like { type: 'dpad' }
buttonsarray | falseNo[A, B]Button list or false (no buttons)
opacitynumberNo0.7Control opacity (0-1)
themestringNo'dark''dark' or 'light'

Joystick Config:

FieldTypeRequiredDefaultDescription
typestringNo'analog''analog' or 'dpad'
sizenumberNo120Diameter (px)
deadZonenumberNo0.150-1 range — center sensitivity in analog mode
diagonalsbooleanNotruefalse → only 4 directions (up/down/left/right)

Button Config:

FieldTypeRequiredDescription
codestringYesEvent code (e.g. 'fire', 'jump')
labelstringNoText displayed on the button
iconstringNoBuilt-in icon name, raw SVG string, or null

Built-in Icons: circle, cross, crosshair, arrow_up, lightning, stop, shield, sword


controls.on

Listens for a specific control code.

js
// Listen for button events
const unsub = gameTegra.controls.on('fire', (e) => {
  console.log(e.type) // 'press' or 'release'
})

// Listen for joystick direction
gameTegra.controls.on('up', (e) => {
  console.log('Moving up')
})

// Joystick released
gameTegra.controls.on('idle', (e) => {
  console.log('Joystick idle')
})

// Stop listening
unsub()

Parameters:

FieldTypeRequiredDescription
codestringYesEvent code to listen for
handlerfunctionYesCallback function

Return Type: () => void — function to stop listening

Event Object:

FieldTypeDescription
codestringEvent code (e.g. 'fire', 'up', 'idle')
typestring'press', 'release', or 'move'
timestampnumberTimestamp in milliseconds

Joystick Direction Codes: up, down, left, right, up_left, up_right, down_left, down_right, idle


controls.onAny

Listens for all control events with a single handler.

js
const unsub = gameTegra.controls.onAny((e) => {
  console.log(`${e.code}: ${e.type}`)
})

controls.hide

Removes controls from screen but preserves event listeners. Can be shown again with show().

js
gameTegra.controls.hide()

controls.destroy

Completely destroys controls — DOM, CSS, and all listeners are cleaned up.

js
gameTegra.controls.destroy()

Custom Elements

When the SDK loads, <gametegra-joystick> and <gametegra-buttons> custom elements are automatically registered. They can be used directly in HTML.

html
<!-- Analog joystick (default) -->
<gametegra-joystick></gametegra-joystick>

<!-- D-Pad -->
<gametegra-joystick type="dpad"></gametegra-joystick>

<!-- Custom size -->
<gametegra-joystick type="analog" size="150"></gametegra-joystick>

<!-- Custom buttons -->
<gametegra-buttons buttons='[{"code":"fire","label":"Fire","icon":"crosshair"},{"code":"jump","label":"Jump","icon":"arrow_up"}]'>
</gametegra-buttons>

Custom elements use the same event system — listen with gameTegra.controls.on().

Multi-Touch

Joystick and buttons can be used simultaneously. Each tracks independent touch identifiers.

Target Mode

When a target parameter is provided, controls render inside the specified HTML element instead of a fixed overlay. This lets you position them within a specific area of your game.


Full Example

js
// Show controls
gameTegra.controls.show({
  joystick: { type: 'analog', deadZone: 0.2 },
  buttons: [
    { code: 'fire',  label: 'Fire',  icon: 'crosshair' },
    { code: 'jump',  label: 'Jump',  icon: 'arrow_up' },
    { code: 'shield', label: 'Shield', icon: 'shield' },
  ],
  theme: 'dark',
  opacity: 0.8,
})

// Listen for directions
gameTegra.controls.on('up', () => player.moveUp())
gameTegra.controls.on('down', () => player.moveDown())
gameTegra.controls.on('left', () => player.moveLeft())
gameTegra.controls.on('right', () => player.moveRight())
gameTegra.controls.on('idle', () => player.stop())

// Listen for buttons
gameTegra.controls.on('fire', (e) => {
  if (e.type === 'press') player.startFiring()
  if (e.type === 'release') player.stopFiring()
})

gameTegra.controls.on('jump', (e) => {
  if (e.type === 'press') player.jump()
})

// Log all events
gameTegra.controls.onAny((e) => {
  console.log(`[${e.code}] ${e.type}`)
})

// Clean up when game ends
gameTegra.controls.destroy()

Simple D-Pad Example

js
gameTegra.controls.show({
  joystick: { type: 'dpad' },
  buttons: [{ code: 'action', label: 'A', icon: 'circle' }],
})

gameTegra.controls.on('up',    () => move('up'))
gameTegra.controls.on('down',  () => move('down'))
gameTegra.controls.on('left',  () => move('left'))
gameTegra.controls.on('right', () => move('right'))
gameTegra.controls.on('action', (e) => {
  if (e.type === 'press') doAction()
})