@debuffjp/input

中文文档
0.33.0发布于 2026/11/11MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 8967

Action-based keyboard, pointer and gamepad input for debuff

原始使用文档
文档目录3 节
  1. Binding names
  2. On-screen touch controls
  3. API

@debuffjp/input

Action-based input across keyboard, mouse/touch/pen (Pointer Events) and gamepads (standard mapping). No dependencies.

import { Input } from "@debuffjp/input";

const input = new Input(game, {
  bindings: {
    left: ["ArrowLeft", "KeyA", "PadLeft", "PadStickLeft"],
    right: ["ArrowRight", "KeyD", "PadRight", "PadStickRight"],
    jump: ["Space", "PadA", "Pointer"],
  },
});

// inside Scene.update
const dx = input.axis("left", "right");
if (input.pressed("jump")) jump();

Edges clear automatically after each simulation step, so a tap shorter than a frame is never missed.

Binding names

SourceNames
KeyboardKeyboardEvent.code: Space, KeyZ, ArrowUp, …
PointerPointer (primary mouse button, touch or pen), PointerRight, PointerMiddle (right and middle mouse buttons)
GamepadPadA PadB PadX PadY PadL1 PadR1 PadL2 PadR2 PadSelect PadStart PadL3 PadR3 PadUp PadDown PadLeft PadRight
Left stickPadStickUp PadStickDown PadStickLeft PadStickRight
On-screen controls (TouchControls, from 0.26)TouchStickUp TouchStickDown TouchStickLeft TouchStickRight, and Touch<name> for each button: TouchA, TouchJump, …

On-screen touch controls

From 0.26, TouchControls puts a stick and buttons on the screen for phones and tablets. They feed the same actions as keys and pads, so the game reads input.down("jump") whatever the player uses:

import { Input, TouchControls } from "@debuffjp/input";

const input = new Input(game, {
  bindings: {
    left: ["ArrowLeft", "PadStickLeft", "TouchStickLeft"],
    right: ["ArrowRight", "PadStickRight", "TouchStickRight"],
    jump: ["Space", "PadA", "TouchA"],
  },
});
const touch = new TouchControls(game, input, {
  stick: { x: 40, y: -40, zone: [0, 0, 160, -1] }, // floating: centres where the thumb lands on the left
  buttons: { A: { x: -32, y: -32 } },              // 32 units in from the bottom-right corner
});

// in render, outside draw.withCamera:
touch.draw(draw);
  • Positions are in logical units; a negative one counts from the right or bottom edge, so the layout holds when scale: "expand" changes the size. radius defaults to 24 for the stick and 16 for a button.
  • A stick with a zone floats: it centres wherever the thumb lands in that rectangle. Without one it stays put and takes touches within twice its radius. touch.stick.x and y are analog (-1 to 1); the four TouchStick directions count past deadzone (default 0.3).
  • Each contact belongs to the control it started on until the finger lifts, so a thumb can slide off a button and keep it held, and a quick tap between two steps still counts as pressed and released.
  • They show from the first touch (show: "touch"), so mouse and keyboard players never see them; show: "always" or "never", or set touch.visible yourself.
  • Their contacts are the pointer's too. Code that moves toward input.pointer should skip it while touch.holding, or check touch.owns(id) per contact.
  • draw() is plain translucent circles ({ color, alpha } to tint them). How the controls look is the game's call: read touch.stick (centre, knob, held) and touch.buttons (position, down) to draw your own.
  • Tests and agents drive them with input.pointer.touchStart(id, x, y), touchMove and touchEnd, and replays record them like any touch.

API

  • input.down(action), input.pressed(action), input.released(action), input.axis(neg, pos)
  • input.rebind(action, keys): replace an action's bindings (a controls menu), keeping captured keys in step. input.bindings is Input's own copy of the map you passed, so change it with rebind rather than in place.
  • input.pointer: x, y (logical), down, pressed, released, touches
  • input.pointer.kind: "mouse", "touch" or "pen", whichever made the latest press
  • input.pointer.touchesStarted, touchesEnded: contacts that started or ended this step (each with id, x, y, kind), so a game doesn't diff touches itself
  • input.pointer.right, input.pointer.middle: down, pressed, released for the right and middle mouse buttons
  • input.pointer.wheel, wheelX: wheel or trackpad scroll this step in CSS pixels (positive = down / right), reset every step. Pass captureWheel: true to stop the page scrolling under a game that zooms with the wheel.
  • input.keys: down(code), pressed(code), released(code)
  • input.pads: stickX, stickY, connected, deadzone
  • input.virtual: sources set by code each step, by binding name (TouchControls writes its controls here). From 0.26
  • Programmatic control for tests and on-screen buttons: keys.press/release, pointer.press/move/release/scroll/pressButton/releaseButton, and pointer.touchStart(id, x, y) / touchMove / touchEnd for multi-touch (the first contact also presses the primary pointer, as a real touch does)

版本与发布记录

@debuffjp/input 共发布 56 个版本,首次发布于 2026/10/16;过去 12 个月发布了 56 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.33.0latest2026/11/11今天
0.32.02026/11/074 天前
0.31.12026/11/065 天前
0.31.02026/11/065 天前
0.30.02026/11/056 天前
0.29.22026/11/056 天前

关于 @debuffjp/input 的常见问题

@debuffjp/input 是什么?

Action-based keyboard, pointer and gamepad input for debuff

如何安装 @debuffjp/input?

在项目目录运行 npm install @debuffjp/input,或使用 pnpm add / yarn add / bun add。

@debuffjp/input 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@debuffjp/input 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@debuffjp/input 可以商用吗?

@debuffjp/input 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@debuffjp/input 的下载量有多少?

根据 npm 官方下载统计,@debuffjp/input 在 2026/10/12 – 2026/11/10 这 30 天内被下载 8,967 次,日均约 299 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@debuffjp/input 还在维护吗?

最新版本 0.33.0 发布于 2026/11/11(今天);至今共发布 56 个版本,其中过去 12 个月发布了 56 个;首次发布于 2026/10/16。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。