Originally published on the Sorceress blog.
TL;DR: a fixed-tick grid, a growing body, food on empty cells, death on wall or self-collision. Under ~350 lines of vanilla JS.
Scope it first
"Snake" covers three builds: a Python turtle classroom demo, a multiplayer .io arena (weeks of backend), or a single-player browser snake — fixed grid, fixed tick, arrow/WASD turns, respawning food, growth on eat, death on wall or self. The last is the weekend build.
The grid loop in one minute
-
Input — read arrow/WASD presses into a one-slot
nextDirectionbuffer; reject reverses. - Tick — every N ms, take direction from the buffer, compute the next head cell, advance.
- Eat — if the next cell holds food, push a new head without dropping the tail, then respawn food on a random empty cell. Otherwise push head and shift tail.
- Collide — if the next cell is out of bounds or in the body, stop and show Game Over.
-
Score — increment on eat; optionally shrink
tickMsevery few points so tension ramps.
Portals, wrap-around walls and power-ups are polish added after one apple feels fair.
Two details that bite beginners
- One-slot direction buffer. Writing direction on keydown lets a fast double-tap reverse the snake into itself. Queue one turn per tick, validated against the current direction.
- Food respawn. Pick from the set of empty cells, not a random cell retried until free — the retry loop degenerates as the board fills.
Picking an engine
-
Vanilla JS + canvas — the default. Fill rects per segment, fixed tick, paint with
requestAnimationFrame. - DOM grid with CSS cells — accessible labels per tile; heavy at larger boards.
- Phaser 4 — Scene lifecycle and tweens; you still write the tick and reverse-guard.
Full guide: sorceress.games
This article was originally published by DEV Community and written by Sorceress.
Read original article on DEV Community