tow-game/js/input.js
Erich Blume 41efdecd93 Initial prototype: TOW trailer-reversing trainer
Browser game teaching how to reverse a car with a trailer. Vanilla JS,
no build step, runs from file:// in Safari.

- Bicycle-model car kinematics + trailer articulation (jackknife behavior)
- WASD controls with steering input smoothing; rendered steering wheel and
  rig-angle HUD
- Tron-style vector rendering, OBB/SAT collision
- Four hand-built maps (dock, lot, roadside, driveway) plus a validated
  procedurally-generated 5th map

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 18:39:03 -07:00

47 lines
1.8 KiB
JavaScript

/* input.js — keyboard state. WASD / arrow keys drive; held A/D feeds the
* steering smoothing in physics.js. R / N / [1-4] are edge-triggered actions. */
(function (TOW) {
'use strict';
function Input() {
this.up = false; this.down = false; this.left = false; this.right = false;
this.actions = []; // queue of one-shot actions: 'reset','next','prev','map:N'
var self = this;
function set(code, val, e) {
switch (code) {
case 'KeyW': case 'ArrowUp': self.up = val; e.preventDefault(); break;
case 'KeyS': case 'ArrowDown': self.down = val; e.preventDefault(); break;
case 'KeyA': case 'ArrowLeft': self.left = val; e.preventDefault(); break;
case 'KeyD': case 'ArrowRight': self.right = val; e.preventDefault(); break;
}
}
window.addEventListener('keydown', function (e) {
if (e.repeat) { set(e.code, true, e); return; }
set(e.code, true, e);
switch (e.code) {
case 'KeyR': self.actions.push('reset'); break;
case 'KeyN': self.actions.push('next'); break;
case 'KeyP': self.actions.push('prev'); break;
case 'Digit1': self.actions.push('map:0'); break;
case 'Digit2': self.actions.push('map:1'); break;
case 'Digit3': self.actions.push('map:2'); break;
case 'Digit4': self.actions.push('map:3'); break;
case 'Digit5': self.actions.push('map:4'); break;
}
});
window.addEventListener('keyup', function (e) { set(e.code, false, e); });
// releasing focus shouldn't leave a key "stuck" down
window.addEventListener('blur', function () {
self.up = self.down = self.left = self.right = false;
});
}
Input.prototype.drainActions = function () {
var a = this.actions; this.actions = []; return a;
};
TOW.Input = Input;
})(window.TOW = window.TOW || {});