# Melonjs Input

Use this skill for keyboard, pointer, mouse, touch and gamepad input in melonJS.

- Repository: https://github.com/melonjs/melonJS (6430 stars)
- Category: Testing
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add melonjs/melonJS --skill melonjs-input -g -a claude-code -y`
Codex: `npx skills add melonjs/melonJS --skill melonjs-input -g -a codex -y`
Cursor: `npx skills add melonjs/melonJS --skill melonjs-input -g -a cursor -y`
Gemini CLI: `npx skills add melonjs/melonJS --skill melonjs-input -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add melonjs/melonJS`

## Description

Use this skill for keyboard, pointer, mouse, touch and gamepad input in melonJS. Covers the bindKey action indirection, registerPointerEvent on regions, the isKinematic requirement that silently blocks pointer events, which of several overlapping objects receives an event and how to consume it, world vs screen pointer coordinates, and gamepad mapping onto the same actions. Triggers on: input, bindKey, isKeyPressed, KEY, registerPointerEvent, releasePointerEvent, pointerdown, pointerup, pointermove, POINTERMOVE, gamepad, bindGamepad, triggerKeyEvent, virtual gamepad, touch controls, joystick, gamepad-plugin, KEYDOWN, KEYUP, press any key, splash screen, click, touch, drag, hit test, event propagation, stop propagating, overlapping, which object gets the click.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Input: keyboard, pointer and gamepad

## Keyboard goes through named actions

Do not poll key codes. Bind a key to an **action string**, then poll the action, this is what lets gamepad and virtual controls map onto the same handling.

```js
import { input } from "melonjs";

input.bindKey(input.KEY.LEFT,  "left");
input.bindKey(input.KEY.RIGHT, "right");
input.bindKey(input.KEY.X,     "jump", true);   // true = locked: one press per keydown

// in update()
if (input.isKeyPressed("left"))  { /* … */ }
if (input.isKeyPressed("jump"))  { /* fires once per press, not per frame */ }
```

The third argument to `bindKey` is `lock` (default `false`). Without it,
`isKeyPressed` stays true for as long as the key is held, correct for movement,
wrong for jump or fire. A locked action stays consumed until the key is released
or you call `input.unlockKey("jump")`. Use `input.keyStatus(action)` when you
want the raw held/not-held state regardless of locking.

### A poll can miss a press entirely

`isKeyPressed` is sampled once per frame, and `keyup` decrements the key's
counter the moment it arrives, locked or not. A press that goes down and up
between two frames therefore leaves the counter back at zero and is never
seen. At 60fps that is anything under ~16ms: rare from a human finger, routine
from a synthetic event, and more likely the slower the frame rate.

For a screen where a missed press is a dead end, a splash, a "press any key",
a notice to acknowledge, listen for the event instead, which cannot be missed:

```js
import { event } from "melonjs";

// action is the bound action name, or undefined for an unbound key
const onKey = (action) => { if (action === "menuSelect") continue(); };
event.on(event.KEYDOWN, onKey);      // in onResetEvent
event.off(event.KEYDOWN, onKey);     // in onDestroyEvent, it does not self-remove
```

The rest: https://github.com/melonjs/melonJS/blob/HEAD/packages/melonjs/skills/melonjs-input/SKILL.md
