logo
By Lawrence

5 minutes

Aim and Fire

In the last lesson, the ship turned to face wherever WASD pushed it. Run left, and it points left. That feels right at first. But say you want to back away from an enemy while you keep shooting at it. You can't: facing and firing are the same action. A twin-stick shooter splits them apart — one stick moves the body, the other points the gun, and the two never have to agree.

A keyboard has no second analog stick, so the arrow keys become one. Hold an arrow and the ship fires that way, in one of eight directions, no matter where WASD is pushing it. Everything you need is already in the TwinStickShooter component from last lesson: fireRate, bulletSpeed, bulletColor, bulletRadius, and muzzleFlash. The Player block does not change at all — this is the firing half those settings were waiting for.

Aim with the arrow keys

The movement half read WASD into a (mvx, mvz) pair. The firing half reads the arrows into its own separate pair. Both read from the same set of keys the input listener fills:

src/components/TwinStickShooter/TwinStickShooter.ts
let shx = 0, shz = 0
if (this.keys.has('ArrowUp')) shz += 1
if (this.keys.has('ArrowDown')) shz -= 1
if (this.keys.has('ArrowLeft')) shx -= 1
if (this.keys.has('ArrowRight')) shx += 1
const slen = Math.hypot(shx, shz)

Hold the up and right arrows together. You get shx = 1, shz = 1, and slen = Math.hypot(1, 1) ≈ 1.414, a clean diagonal. Press nothing and slen is 0. That zero is the flag for "not firing this frame." Now the key part: shx and shz come from ArrowLeft, ArrowRight, ArrowUp, and ArrowDown, while mvx and mvz came from KeyA, KeyD, KeyW, and KeyS — different keys, read in the same frame. So you can hold W+A and the down and right arrows at once, and the ship glides up-left while it shoots down-right. The two sticks are independent because they never share an input.

Continue reading

Unlock the Full Course

Every lesson, the runnable examples, and the finished build — yours to keep.

$9one-time

Was this page helpful?

We read every note — tell us what's working and what isn't.

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search