Chan Can Kick

Three fighters. Five rooms. Ten lanterns, a clock, and a gate that won't open until nine are lit. Between you and the pagoda's summit: ninjas that strike back — watch for the raised blade, that's your warning — and the Green Yamo, who bounds after you in great springy leaps and slams. Every Bruce Lee player knows the Yamo. Nobody has ever been rid of him.

Pick your fighter with ← → and press Z / Space to begin. This is the strict C64 church of controls: ↑ jumps, ↑↓ climb ladders, and fire — Z / Space / X — fights. Standing still it's a punch: fast, short, feet planted. On the move or in the air it's a FLYING KICK — your fighter leaves the ground and lunges, and you steer the landing. A landed blow floors a ninja or the Yamo; they lie down, blink, get up, and resume. Nobody here ever really dies.

Lantern night at the dojo: a punch mid-flight, a ninja squared up, the Yamo bounding in

How it's made — and yours to remix

Everything above is two files, both open in the SOURCE panel — edit and hit RUN ▶ to play your changes immediately:

  • rooms.js is the world as pure data — and not just the tiles. The five rooms with their exits and ladders, yes, but also RULES (the clock, the points table, the win targets — the engine's Rules module eats it whole) and UI (which HUD readouts exist and where they sit: move the score to the bottom-right by editing one string). Goals, time, score, placement: all JSON.
  • main.js is the game. The character's whole look is one function, paintFighter(), handed to the engine as player.sprite — the engine's placeholder sprite is replaced wholesale, and every pose (run, jump, climb, punch, the horizontal flying-kick silhouette) is drawn from state. No look is hard-coded anywhere: redraw the fighter by editing one function, or assign your own callback and draw anything.
  • The ninjas are a five-state machine — chase, windup, strike, recover, down — where only the strike hurts and the windup is the tell. The Yamo hops on a spring and slams. Both are game code passed through the World's spawnEntity factory, with one game-side extra — knockdown() — wired to the player's attack-hit event. The punch and the kick themselves are a moveset: two table rows (stance, envelope, reach, lunge) the engine runs; the game only decides what a landed hit means. The engine never heard of ninjas — but it lands every blow on them.

The action event does the fight-choreography: its payload says whether you were moving, airborne or standing when you pressed fire, and punch-versus-flying-kick is one if on that. The kick itself is three lines — a maxSpeed boost, a velocity, a hop — which is the entire secret of feeling airborne.