Most arcade-style browser games lean on dark backgrounds and glowing neon colors, and for good reason, since that combination tends to make bright game elements pop. But there is another approach that gets far less attention: building a game around a clean, bright, almost minimal white interface instead. For this version of Neon Serpent, the Coding Stellix team took the classic snake game and rebuilt its visual identity around a soft white background, letting the color of the snake and its food carry all the visual energy instead of glowing edges and dark space.
This article walks through how that game was built, from the underlying grid logic to the decision to move away from a dark theme entirely.
Why Start With the Grid, Not the Colors
Before any visual decisions get made, a snake game needs its core logic sorted out, and that logic barely depends on color at all. The entire game world is represented as a grid of rows and columns, and every object in the game, whether it is a segment of the snake or a piece of food, is really just a pair of numbers identifying its position on that grid. This makes collision detection simple: two things collide only when their row and column match exactly, so there is no need for any pixel-based distance math anywhere in the core gameplay code.
The snake itself is stored as an ordered list of these grid positions, with the first entry representing the head. Every time the snake moves, a new head position gets calculated based on the current direction, and depending on whether that new position lands on food, the tail either stays in place, which makes the snake grow, or gets removed to keep the length the same.
Timing Movement Correctly
A common beginner mistake is moving the snake every animation frame, which happens far too often to be playable, since a typical screen updates dozens of times per second. Instead, the game keeps its own internal timer that only allows a movement step once a certain amount of time has passed. This interval is what actually defines how fast the snake feels to play, and it can be tuned independently of the rendering loop, which keeps running smoothly at full frame rate for visuals like particle effects even while the snake itself moves at a much slower, controlled pace.
Supporting Every Kind of Input
Since this game needed to work well on phones, tablets, and desktop browsers alike, it supports four separate input methods at once. Arrow keys and WASD both work for keyboard users. Swipe gestures are detected by tracking the start and end position of a touch interaction and calculating which direction had the larger movement. And for anyone who prefers tapping over swiping, a small directional pad sits in the corner of the play area. All four of these ultimately feed into the exact same direction-setting function, so no matter how the player chooses to interact, the underlying game logic stays identical.
Building in Difficulty Levels
Rather than locking the game to a single fixed speed, three difficulty presets are offered before the game starts: easy, medium, and hard. Each one bundles together a starting speed, a rate at which the snake speeds up as it eats, and how often a rare bonus item appears on the board. Bundling these settings together, instead of exposing each one as an individual slider, keeps the choice simple for the player while still making each difficulty level feel meaningfully different to actually play.
Choosing a Light Interface on Purpose
The most distinctive design decision in this version of the game was moving away from the dark, glowing aesthetic that most arcade games default to, and building the entire interface around a soft white background instead. This was not just a simple color swap. Every element that relied on a dark background for contrast needed to be reconsidered. The snake’s head, for example, originally used a very light, almost white color that worked well against a dark background but would have completely disappeared against white, so it was changed to a rich, saturated violet that stands out clearly no matter where it sits on the board. Grid lines, which were previously a faint white overlay, needed to switch to a faint violet tint instead, since white-on-white grid lines are invisible.
The result is an interface that feels closer to a clean productivity app than a typical dark arcade game, while still keeping the fun, colorful gradient trail that makes the snake satisfying to watch as it grows. This kind of light theme also tends to read better in bright environments, like outdoors or under strong classroom lighting, which matters more than people often expect for casual browser games.
Adding Sound the Simple Way
Rather than bundling external audio files, every sound in the game is generated on the fly using the Web Audio API. Short oscillator tones, layered with tiny delays between them, produce a distinct sound for eating food, grabbing a bonus orb, and losing the game. This keeps the entire project self contained in a single file with zero external dependencies, while still giving the player clear audio feedback for every meaningful action.
Making It Truly Responsive
For a grid-based game, being responsive means more than just shrinking things to fit a smaller screen. The play area has to stay a perfect square no matter what shape the browser window is, or the grid will look stretched and distorted. To solve this, the game measures both the available width and the available height of its container, picks whichever dimension is more restrictive, and calculates the largest cell size that would let the full grid fit inside that space. This calculation reruns automatically whenever the window resizes or a device changes orientation, so the board always looks correctly proportioned.
On top of that, text throughout the interface uses responsive sizing so that headings and labels shrink gracefully on very narrow phone screens instead of overlapping, and safe area padding was added so nothing important gets hidden behind notches or rounded screen corners on modern devices.
Final Thoughts
Rebuilding a familiar game like snake with an unfamiliar visual direction is a good reminder that a game’s identity comes from more than just its mechanics. The grid logic, the movement timing, and the collision detection are exactly the kind of things any snake game needs, but the decision to build it around a bright, clean white interface instead of the usual dark glow is what gives this particular version its own distinct feel.
This is exactly the kind of project Coding Stellix likes to explore, taking something familiar and rethinking one core assumption about it, then following that decision all the way through the design.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Neon Serpent | Coding Stellix</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Sora:wght@500;600;700;800&display=swap" rel="stylesheet">
<style>
:root{
--bg: #ffffff;
--bg2: #f4f2ff;
--grid: rgba(45,212,191,0.08);
--teal: #0d9488;
--teal-glow: rgba(13,148,136,0.35);
--violet: #7c3aed;
--violet-glow: rgba(124,58,237,0.35);
--coral: #e11d48;
--coral-glow: rgba(225,29,72,0.4);
--amber: #d97706;
--amber-glow: rgba(217,119,6,0.4);
--text: #241f38;
--muted: #6b6689;
--panel: rgba(124,58,237,0.05);
--border: rgba(124,58,237,0.14);
}
*{ margin:0; padding:0; box-sizing:border-box; }
html, body{
height:100%;
height:100dvh;
overflow:hidden;
font-family:'Sora', sans-serif;
color: var(--text);
-webkit-tap-highlight-color: transparent;
touch-action:none;
}
#app{
position:fixed;
inset:0;
display:flex;
flex-direction:column;
align-items:center;
background:
radial-gradient(circle at 20% 10%, rgba(45,212,191,0.10), transparent 45%),
radial-gradient(circle at 85% 90%, rgba(167,139,250,0.14), transparent 45%),
linear-gradient(180deg, var(--bg), var(--bg2));
padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
overflow:hidden;
}
#topbar{
width:100%;
max-width: 480px;
display:flex;
align-items:center;
justify-content:space-between;
margin-bottom: 10px;
}
#brand{
font-size: clamp(11px, 3vw, 13px);
font-weight:700;
}
#brand span{ color: var(--teal); text-shadow: 0 0 8px var(--teal-glow); }
#stat-row{ display:flex; gap:8px; }
.chip{
background: var(--panel);
border: 1px solid var(--border);
border-radius: 10px;
padding: 6px 12px;
text-align:center;
}
.chip .lbl{
font-size: 8px;
letter-spacing:1px;
text-transform:uppercase;
color: var(--muted);
font-weight:600;
}
.chip .val{ font-size: 15px; font-weight:700; }
#best-val{ color: var(--amber); }
#score-val{ color: var(--teal); }
#stage-wrap{
position:relative;
flex: 1 1 auto;
min-height:0;
width:100%;
max-width: 480px;
background: var(--panel);
border: 1px solid var(--border);
border-radius: 20px;
overflow:hidden;
display:flex;
align-items:center;
justify-content:center;
}
canvas{
display:block;
max-width:100%;
max-height:100%;
border-radius: 12px;
}
#footer-tag{
margin-top: 8px;
font-size: 10px;
letter-spacing: 1px;
text-transform: uppercase;
color: var(--muted);
text-align:center;
font-weight:600;
}
#footer-tag span{ color: var(--coral); }
/* dpad for mobile */
#dpad{
position:absolute;
bottom: 16px;
right: 16px;
display:grid;
grid-template-columns: 44px 44px 44px;
grid-template-rows: 44px 44px 44px;
gap: 4px;
opacity:0.85;
z-index:8;
}
#dpad button{
background: rgba(36,31,56,0.06);
border: 1px solid var(--border);
border-radius: 10px;
color: var(--text);
font-size: 16px;
display:flex;
align-items:center;
justify-content:center;
}
#dpad .up{ grid-column:2; grid-row:1; }
#dpad .left{ grid-column:1; grid-row:2; }
#dpad .down{ grid-column:2; grid-row:3; }
#dpad .right{ grid-column:3; grid-row:2; }
/* overlays */
.overlay{
position:fixed;
inset:0;
display:flex;
align-items:center;
justify-content:center;
text-align:center;
background: rgba(6,5,16,0.72);
backdrop-filter: blur(8px);
z-index:40;
padding: 20px;
transition: opacity 0.3s ease, visibility 0.3s ease;
}
.overlay.hidden{ opacity:0; visibility:hidden; pointer-events:none; }
.card{
background: #ffffff;
border: 1px solid var(--border);
border-radius: 22px;
padding: 34px 30px;
max-width: 380px;
width:100%;
box-shadow: 0 0 60px rgba(45,212,191,0.10);
}
.card .big-emoji{ font-size: 52px; margin-bottom: 8px; }
.card h1{ font-size: clamp(26px, 7vw, 32px); font-weight:800; margin-bottom:6px; }
.card h1 span{ color: var(--teal); text-shadow: 0 0 14px var(--teal-glow); }
.card p{
color: var(--muted);
font-size: 14px;
line-height:1.55;
margin-bottom: 22px;
font-weight:500;
}
.stat-line{ font-size:15px; margin-bottom:6px; font-weight:600; }
.stat-line b{ color: var(--teal); }
.btn{
font-family:'Sora', sans-serif;
font-size: 15px;
font-weight:700;
color: #0b0a17;
background: linear-gradient(90deg, var(--teal), var(--violet));
border:none;
border-radius: 50px;
padding: 13px 34px;
cursor:pointer;
box-shadow: 0 10px 24px rgba(45,212,191,0.25);
transition: transform 0.15s ease;
}
.btn:active{ transform: scale(0.95); }
#diff-row{
display:flex;
flex-wrap: wrap;
gap:10px;
justify-content:center;
margin-bottom: 22px;
}
.diff-btn{
font-family:'Sora', sans-serif;
font-size: 13px;
font-weight:700;
color: var(--text);
background: rgba(124,58,237,0.05);
border: 1px solid var(--border);
border-radius: 12px;
padding: 10px 8px;
cursor:pointer;
flex: 1 1 90px;
min-width: 90px;
transition: all 0.15s ease;
}
.diff-btn .sub{
display:block;
font-size: 9px;
font-weight:500;
color: var(--muted);
margin-top:2px;
}
.diff-btn.selected{
background: linear-gradient(90deg, var(--teal), var(--violet));
color: #0b0a17;
border-color: transparent;
box-shadow: 0 6px 18px rgba(45,212,191,0.25);
}
.diff-btn.selected .sub{ color: rgba(11,10,23,0.6); }
#diff-chip{ color: var(--violet); }
.hint{
margin-top: 18px;
font-size: 11px;
color: var(--muted);
letter-spacing: 0.5px;
font-weight:600;
}
@media (max-height:640px){
#topbar{ margin-bottom:6px; }
.chip{ padding:4px 9px; }
.chip .val{ font-size:12px; }
#footer-tag{ margin-top:4px; font-size:8px; }
#dpad{ transform: scale(0.85); bottom:8px; right:8px; }
}
@media (max-width:360px){
#stat-row{ gap:5px; }
.chip{ padding:5px 8px; }
.card{ padding: 24px 18px; }
.diff-btn{ min-width: 80px; padding: 8px 6px; }
}
</style>
</head>
<body>
<div id="app">
<div id="topbar">
<div id="brand">Coding <span>Stellix</span> β Neon Serpent</div>
<div id="stat-row">
<div class="chip"><div class="lbl">Level</div><div class="val" id="diff-chip">Medium</div></div>
<div class="chip"><div class="lbl">Score</div><div class="val" id="score-val">0</div></div>
<div class="chip"><div class="lbl">Best</div><div class="val" id="best-val">0</div></div>
</div>
</div>
<div id="stage-wrap">
<canvas id="game"></canvas>
<div id="dpad">
<button class="up" data-dir="up">β²</button>
<button class="left" data-dir="left">β</button>
<button class="down" data-dir="down">βΌ</button>
<button class="right" data-dir="right">βΆ</button>
</div>
</div>
<div id="footer-tag">Neon Serpent β’ Made by <span>Coding Stellix</span></div>
</div>
<!-- START -->
<div class="overlay" id="start-screen">
<div class="card">
<div class="big-emoji">πβ¨</div>
<h1>Neon <span>Serpent</span></h1>
<p>Guide your glowing serpent to eat orbs and grow longer. Avoid the walls and your own tail. Gold orbs are worth more but appear briefly β grab them fast!</p>
<div id="diff-row">
<button class="diff-btn" data-diff="easy">Easy<span class="sub">Slow & Calm</span></button>
<button class="diff-btn selected" data-diff="medium">Medium<span class="sub">Balanced</span></button>
<button class="diff-btn" data-diff="hard">Hard<span class="sub">Fast & Tense</span></button>
</div>
<button class="btn" id="start-btn">Start Slithering</button>
<div class="hint">ARROW KEYS / WASD / SWIPE / D-PAD</div>
</div>
</div>
<!-- END -->
<div class="overlay hidden" id="end-screen">
<div class="card">
<div class="big-emoji">π₯</div>
<h1>Game <span>Over</span></h1>
<p id="end-sub">Your serpent's run has ended.</p>
<div class="stat-line">Score: <b id="end-score">0</b></div>
<div class="stat-line" style="margin-bottom:22px;">Best: <b id="end-best">0</b></div>
<button class="btn" id="restart-btn">Play Again</button>
</div>
</div>
<script>
(function(){
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
const stageWrap = document.getElementById('stage-wrap');
const scoreVal = document.getElementById('score-val');
const bestVal = document.getElementById('best-val');
// ===== Sound engine =====
let audioCtx = null;
function ensureAudio(){
if(!audioCtx){
try { audioCtx = new (window.AudioContext || window.webkitAudioContext)(); }
catch(e){ audioCtx = null; }
}
if(audioCtx && audioCtx.state === 'suspended') audioCtx.resume();
}
function tone(freq,dur,type,gainVal,delay){
if(!audioCtx) return;
const t0 = audioCtx.currentTime + (delay||0);
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = type||'sine';
osc.frequency.setValueAtTime(freq,t0);
gain.gain.setValueAtTime(0,t0);
gain.gain.linearRampToValueAtTime(gainVal||0.15,t0+0.01);
gain.gain.exponentialRampToValueAtTime(0.001,t0+dur);
osc.connect(gain).connect(audioCtx.destination);
osc.start(t0); osc.stop(t0+dur+0.02);
}
const sfx = {
eat(){ tone(520,0.08,'triangle',0.13); tone(720,0.08,'triangle',0.08,0.04); },
gold(){ tone(660,0.1,'square',0.13); tone(990,0.12,'square',0.1,0.06); },
turn(){ tone(300,0.03,'sine',0.03); },
die(){ tone(260,0.2,'sawtooth',0.14); tone(150,0.3,'sawtooth',0.12,0.15); }
};
const COLS = 18, ROWS = 18;
let cell;
let W,H;
function resize(){
const avail = Math.min(stageWrap.clientWidth, stageWrap.clientHeight) - 12;
cell = Math.max(10, Math.floor(avail/COLS));
W = cell*COLS;
H = cell*ROWS;
canvas.width = W*devicePixelRatio;
canvas.height = H*devicePixelRatio;
canvas.style.width = W+'px';
canvas.style.height = H+'px';
ctx.setTransform(devicePixelRatio,0,0,devicePixelRatio,0,0);
}
window.addEventListener('resize', resize);
window.addEventListener('orientationchange', ()=>setTimeout(resize,150));
const DIFFICULTY = {
easy: { label:'Easy', start:0.17, min:0.11, decrease:0.0014, goldChance:0.016, goldTimer:6.0 },
medium: { label:'Medium', start:0.13, min:0.07, decrease:0.0020, goldChance:0.012, goldTimer:4.5 },
hard: { label:'Hard', start:0.09, min:0.05, decrease:0.0028, goldChance:0.009, goldTimer:3.2 }
};
let difficulty = DIFFICULTY.medium;
document.querySelectorAll('.diff-btn').forEach(btn=>{
btn.addEventListener('click', ()=>{
document.querySelectorAll('.diff-btn').forEach(b=>b.classList.remove('selected'));
btn.classList.add('selected');
difficulty = DIFFICULTY[btn.dataset.diff];
document.getElementById('diff-chip').textContent = difficulty.label;
});
});
let snake = [];
let dir = {x:1,y:0};
let nextDir = {x:1,y:0};
let food = null;
let goldFood = null;
let goldTimer = 0;
let score = 0;
let best = 0;
let running = false;
let stepTimer = 0;
let stepInterval = 0.13;
let particles = [];
try { best = parseInt(localStorage.getItem('neonSerpentBest')||'0',10) || 0; } catch(e){ best = 0; }
bestVal.textContent = best;
function randCell(){
return { x: Math.floor(Math.random()*COLS), y: Math.floor(Math.random()*ROWS) };
}
function cellFree(pos){
return !snake.some(s=>s.x===pos.x && s.y===pos.y);
}
function placeFood(){
let p;
do { p = randCell(); } while(!cellFree(p));
food = p;
}
function maybeSpawnGold(){
if(goldFood || Math.random() > difficulty.goldChance) return;
let p;
do { p = randCell(); } while(!cellFree(p) || (food && p.x===food.x && p.y===food.y));
goldFood = p;
goldTimer = difficulty.goldTimer;
}
function initGame(){
const cx = Math.floor(COLS/2), cy = Math.floor(ROWS/2);
snake = [{x:cx-1,y:cy},{x:cx-2,y:cy},{x:cx-3,y:cy}];
dir = {x:1,y:0};
nextDir = {x:1,y:0};
score = 0;
stepInterval = difficulty.start;
goldFood = null;
particles = [];
placeFood();
scoreVal.textContent = 0;
}
function setDir(nx,ny){
if(nx === -dir.x && ny === -dir.y) return; // no reverse
nextDir = {x:nx,y:ny};
}
window.addEventListener('keydown', (e)=>{
if(!running) return;
if(e.key==='ArrowUp'||e.key.toLowerCase()==='w') setDir(0,-1);
else if(e.key==='ArrowDown'||e.key.toLowerCase()==='s') setDir(0,1);
else if(e.key==='ArrowLeft'||e.key.toLowerCase()==='a') setDir(-1,0);
else if(e.key==='ArrowRight'||e.key.toLowerCase()==='d') setDir(1,0);
});
document.querySelectorAll('#dpad button').forEach(btn=>{
btn.addEventListener('pointerdown', (e)=>{
e.preventDefault();
const d = btn.dataset.dir;
if(d==='up') setDir(0,-1);
if(d==='down') setDir(0,1);
if(d==='left') setDir(-1,0);
if(d==='right') setDir(1,0);
});
});
// swipe controls
let touchStart = null;
stageWrap.addEventListener('pointerdown', (e)=>{ touchStart = {x:e.clientX,y:e.clientY}; });
stageWrap.addEventListener('pointerup', (e)=>{
if(!touchStart) return;
const dx = e.clientX - touchStart.x;
const dy = e.clientY - touchStart.y;
if(Math.abs(dx) > 24 || Math.abs(dy) > 24){
if(Math.abs(dx) > Math.abs(dy)) setDir(dx>0?1:-1, 0);
else setDir(0, dy>0?1:-1);
}
touchStart = null;
});
function spawnParticles(gx,gy,color){
const px = gx*cell + cell/2;
const py = gy*cell + cell/2;
for(let i=0;i<10;i++){
const ang = Math.random()*Math.PI*2;
const spd = 1+Math.random()*3;
particles.push({x:px,y:py,vx:Math.cos(ang)*spd,vy:Math.sin(ang)*spd,life:1,color});
}
}
function step(){
dir = nextDir;
const head = { x: snake[0].x + dir.x, y: snake[0].y + dir.y };
if(head.x < 0 || head.x >= COLS || head.y < 0 || head.y >= ROWS){
return die();
}
if(snake.some(s=>s.x===head.x && s.y===head.y)){
return die();
}
snake.unshift(head);
let grew = false;
if(food && head.x===food.x && head.y===food.y){
score += 10;
sfx.eat();
spawnParticles(food.x,food.y,'#2dd4bf');
placeFood();
grew = true;
stepInterval = Math.max(difficulty.min, stepInterval - difficulty.decrease);
} else if(goldFood && head.x===goldFood.x && head.y===goldFood.y){
score += 40;
sfx.gold();
spawnParticles(goldFood.x,goldFood.y,'#fbbf24');
goldFood = null;
grew = true;
}
if(!grew){
snake.pop();
}
scoreVal.textContent = score;
}
function die(){
sfx.die();
running = false;
if(score > best){
best = score;
try{ localStorage.setItem('neonSerpentBest', String(best)); }catch(e){}
}
bestVal.textContent = best;
document.getElementById('end-score').textContent = score;
document.getElementById('end-best').textContent = best;
document.getElementById('end-screen').classList.remove('hidden');
}
function update(dt){
if(running){
stepTimer += dt;
if(stepTimer >= stepInterval){
stepTimer = 0;
step();
}
if(goldFood){
goldTimer -= dt;
if(goldTimer <= 0) goldFood = null;
} else {
maybeSpawnGold();
}
}
for(const p of particles){
p.x += p.vx; p.y += p.vy;
p.vx *= 0.94; p.vy *= 0.94;
p.life -= dt*2;
}
particles = particles.filter(p=>p.life>0);
}
function draw(){
ctx.clearRect(0,0,W,H);
ctx.fillStyle = '#ffffff';
ctx.fillRect(0,0,W,H);
// grid
ctx.strokeStyle = 'rgba(124,58,237,0.08)';
ctx.lineWidth = 1;
for(let x=0;x<=COLS;x++){
ctx.beginPath(); ctx.moveTo(x*cell,0); ctx.lineTo(x*cell,H); ctx.stroke();
}
for(let y=0;y<=ROWS;y++){
ctx.beginPath(); ctx.moveTo(0,y*cell); ctx.lineTo(W,y*cell); ctx.stroke();
}
// food
if(food) drawOrb(food.x, food.y, '#2dd4bf', 'rgba(45,212,191,0.6)');
if(goldFood) drawOrb(goldFood.x, goldFood.y, '#fbbf24', 'rgba(251,191,36,0.7)');
// snake
snake.forEach((s,i)=>{
const t = 1 - i/snake.length;
const hue = 172 + (1-t)*100;
ctx.beginPath();
const cx = s.x*cell+cell/2, cy = s.y*cell+cell/2;
const rad = cell*0.42;
ctx.arc(cx,cy,rad,0,Math.PI*2);
ctx.fillStyle = i===0 ? '#4c1d95' : `hsl(${hue},75%,${48+t*8}%)`;
ctx.shadowColor = 'rgba(124,58,237,0.35)';
ctx.shadowBlur = i===0 ? 12 : 6;
ctx.fill();
ctx.shadowBlur = 0;
});
// particles
for(const p of particles){
ctx.beginPath();
ctx.arc(p.x,p.y,3*Math.max(p.life,0),0,Math.PI*2);
ctx.fillStyle = p.color;
ctx.globalAlpha = Math.max(p.life,0);
ctx.fill();
ctx.globalAlpha = 1;
}
}
function drawOrb(gx,gy,color,glow){
const cx = gx*cell+cell/2, cy = gy*cell+cell/2;
ctx.beginPath();
ctx.arc(cx,cy,cell*0.32,0,Math.PI*2);
ctx.fillStyle = color;
ctx.shadowColor = glow;
ctx.shadowBlur = 14;
ctx.fill();
ctx.shadowBlur = 0;
}
let lastTs = 0;
function loop(ts){
if(!lastTs) lastTs = ts;
const dt = Math.min((ts-lastTs)/1000, 0.05);
lastTs = ts;
update(dt);
draw();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
function startGame(){
ensureAudio();
resize();
initGame();
running = true;
document.getElementById('start-screen').classList.add('hidden');
document.getElementById('end-screen').classList.add('hidden');
}
document.getElementById('start-btn').addEventListener('click', startGame);
document.getElementById('restart-btn').addEventListener('click', startGame);
resize();
})();
</script>
</body>
</html>



