JavaScript Space Invaders: Derive the Edge from Live Targets

If a removed column still defines the formation edge, the surviving targets turn around too early. If a shot keeps traveling after a hit, it can score again against the next target.

Use live target IDs for both bounds and hits, consuming each bullet after its first valid contact.

The playable shooter has six rectangular targets and a player that moves horizontally. A simulation cooldown limits firing. A frozen-formation inspection isolates the first-hit rule: the center shot meets lower T6 before upper T3. Removing both right-column targets changes the permissible offset from 146 to 196. Layout and score follow the live set.

JavaScript Space Invaders: Derive the Edge from Live Targets
JavaScript Space Invaders: Derive the Edge from Live Targets
Open the full example ↗

Define the formation and player records

Use a 320 × 240 simulation field with x increasing right and y increasing down. Target positions are top-left coordinates. Each target is 24 wide and 16 high.

Target ID Base x Base y
T1 50 30
T2 100 30
T3 150 30
T4 50 60
T5 100 60
T6 150 60

Store horizontal and vertical offsets, both initially zero. Start moving right at 40 units per second. Each live target's current position is its base position plus those offsets. Never let a removed target contribute to current bounds.

The player is 24 × 12 at top-left (148, 216), moves in 12-unit steps using the buttons or fresh arrow keys, follows pointer positioning, and is clamped to x from 0 through 296. Targets and player do not wrap.

Reverse at the live edge and descend once

The original formation has left edge 50 and right edge 174. At horizontal offset 146, its right edge reaches 320. Clamp it there, descend 16, and change direction to left once for that boundary arrival.

Split movement at each boundary arrival. Descend once, reverse, then use any remaining time to move inward. Resolve the horizontal sweeps and the instantaneous landing separately; a target never follows a diagonal path through the turn.

Now remove both right-column targets, T3 and T6. The remaining base right edge is 124, so the permissible rightward offset becomes 196. A removed column must not leave a ghost edge at 174. Removing only T3 does not shrink the edge: T6 still reaches 174. Calculate the edge from every surviving rectangle, including the lower target when only the upper one is gone.

When a projectile changes the live set, recalculate bounds for subsequent formation movement. Do not retroactively undo a descent already resolved earlier in the update. If no targets remain, there is no formation edge to inspect: enter the terminal win path.

Check geometry without counting one shot twice

MDN's collision guide describes overlap tests for axis-aligned rectangles. This game checks moving rectangles for strict overlap; touching edges alone does not count as a hit.

Create a 4 × 8 player bullet just above the player: its top-left x is player x + 10, and y is 208. It moves upward at 180 units per second. Each fresh Fire activation may create one bullet if the 0.3-second simulation cooldown has elapsed. Ignore repeated keydown events and do not add automatic fire while held.

The game uses substeps no larger than 0.005 seconds, split again at a boundary or hit. It recalculates live bounds after removals. Inspect boundary descent loads a bullet at (298, 82) and offset 145.9; contact occurs at the 0.002500-second landing.

A bullet at the player centerline initially x = 158 spans x = 158 through 162. With the initial formation frozen, an upward shot meets lower target T6 before upper target T3. Consume that bullet at T6, remove T6, and add one point. T3 remains alive; the same shot never earns the second point.

Process contacts by earliest time, then bullet ID and target ID for ties. Skip a candidate if its bullet or target was already consumed. Another bullet can continue to a later still-live target after an earlier candidate becomes invalid; it cannot score against the removed target again.

Play and inspect the two shots

Start real-time play, move the player with Left/Right or a pointer over the field, and fire with the button or fresh Space while the board is focused. A 0.3-second simulation cooldown rejects repeated fire. Pause freezes formation, bullets and cooldown; Resume resets the clock reference.

For this comparison, press Reset and enable frozen inspection before Start. Leave the player centered, fire once, then press Advance 0.5 s twice. The lower T6 disappears and T3 remains. Fire another shot and repeat to remove T3; the rightward offset limit expands to 196. The boundary expands only after both right-column targets disappear. If a target reaches the player line, the player loses before a projectile hit at that same instant. Reset returns to six targets, zero score and Ready.

Copy this prompt

Create an original formation shooter with six rectangular targets on a logical 320 by 240 field. Draw the game above buttons and text showing phase, score, live target IDs, player position and formation bounds.

Each target is 24 by 16. Their initial top-left positions are T1 (50, 30), T2 (100, 30), T3 (150, 30), T4 (50, 60), T5 (100, 60) and T6 (150, 60). They share offsets initially set to zero. Move right at 40 units per second. At a field edge, clamp the offset, descend 16 units and reverse once. Calculate bounds using live targets only. The original rightward offset limit is 146. Removing T3 and T6 changes it to 196; removing either alone leaves it at 146.

The player is 24 by 12 at (148, 216), with x bounded from 0 to 296. Buttons and fresh focused arrow presses move it 12 units. Pointer movement maps to the displayed field. Fire creates a 4 by 8 projectile at player x plus 10, y = 208, moving upward at 180 units per second. Enforce a 0.3-second simulation cooldown.

Use substeps no larger than 0.005 seconds. Split horizontal collision sweeps at each boundary arrival and handle the instantaneous downward landing separately, preserving elapsed contact time. Consume each bullet at its first live target and score that target once. A formation landing at the player line loses before projectile contacts at that same instant. Removing all targets wins.

Provide Start, Pause, Resume, Reset, frozen-formation inspection and paused Advance 0.5 s. After Reset, enable frozen mode before Start and leave the player centered; a shot removes T6 before T3. Add a labeled boundary case at offset 145.9 with a bullet at (298, 82): contact occurs on landing at 0.002500 seconds. Keep one animation owner and pause on focus loss. Return one responsive, self-contained HTML file.

Remove the right column in two shots

Press Reset, enable frozen inspection before Start and leave the player centered. Fire and advance twice by 0.5 seconds. T6 disappears while T3 still defines the right edge. Fire again and repeat to remove T3. NOS can render the HTML shooter for this inspection. Compare the displayed limits of 146 and 196, then reset before returning to moving-target play.

Keep reading