<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Javascript on Vijay Kodam</title><link>https://vijay.eu/tags/javascript/</link><description>Recent content in Javascript on Vijay Kodam</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 10 Jun 2026 12:00:00 +0300</lastBuildDate><atom:link href="https://vijay.eu/tags/javascript/index.xml" rel="self" type="application/rss+xml"/><item><title>Retro Racer</title><link>https://vijay.eu/projects/retro-racer/</link><pubDate>Wed, 10 Jun 2026 12:00:00 +0300</pubDate><guid>https://vijay.eu/projects/retro-racer/</guid><description>&lt;div class="retro-racer"&gt;
&lt;h1 class="racer-title"&gt;Retro Racer&lt;/h1&gt;
&lt;p class="racer-subtitle"&gt;A 3D arcade racer. One lap, against the clock.&lt;/p&gt;
&lt;div class="racer-frame"&gt;
&lt;canvas id="racerCanvas"&gt;&lt;/canvas&gt;
&lt;div class="racer-banner hidden" id="racerBanner" aria-live="polite"&gt;&lt;/div&gt;
&lt;div class="racer-hud" aria-live="off"&gt;
&lt;div class="hud-item"&gt;
&lt;span class="hud-label"&gt;Time&lt;/span&gt;
&lt;span class="hud-value" id="hudTime"&gt;0:00.0&lt;/span&gt;
&lt;/div&gt;
&lt;div class="hud-item hud-item--speed"&gt;
&lt;span class="hud-label"&gt;Speed&lt;/span&gt;
&lt;span class="hud-value" id="hudSpeed"&gt;0 km/h&lt;/span&gt;
&lt;/div&gt;
&lt;div class="hud-item"&gt;
&lt;span class="hud-label"&gt;Progress&lt;/span&gt;
&lt;span class="hud-value" id="hudProgress"&gt;0%&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="racer-overlay" id="racerStart"&gt;
&lt;h2&gt;Retro Racer&lt;/h2&gt;
&lt;p&gt;Complete one lap as fast as you can. Dodge traffic and stay on the road - grass and crashes will slow you down.&lt;/p&gt;
&lt;p&gt;Arrow keys or WASD to drive. On touch devices, hold gas/brake with your left thumb and steer with your right.&lt;/p&gt;
&lt;button class="racer-btn" id="racerStartBtn" type="button" disabled&gt;Start Race&lt;/button&gt;
&lt;p class="racer-loading" id="racerLoading"&gt;Loading 3D assets...&lt;/p&gt;
&lt;p class="racer-best" id="racerStartBest"&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="racer-overlay hidden" id="racerResults"&gt;
&lt;h2&gt;Finish!&lt;/h2&gt;
&lt;p class="racer-result-time" id="racerResultTime"&gt;&lt;/p&gt;
&lt;p class="racer-best" id="racerResultBest"&gt;&lt;/p&gt;
&lt;button class="racer-btn" id="racerAgainBtn" type="button"&gt;Race Again&lt;/button&gt;
&lt;/div&gt;
&lt;div class="racer-cinematic hidden" id="racerCinematic" aria-hidden="true"&gt;
&lt;div class="racer-letterbox racer-letterbox--top"&gt;&lt;/div&gt;
&lt;div class="racer-letterbox racer-letterbox--bottom"&gt;&lt;/div&gt;
&lt;div class="racer-flyby-label"&gt;
&lt;span class="racer-flyby-name"&gt;Mazda Miata&lt;/span&gt;
&lt;span class="racer-flyby-sub"&gt;MX-5 NA&lt;/span&gt;
&lt;/div&gt;
&lt;button class="racer-skip-btn" id="racerSkipBtn" type="button"&gt;Skip &amp;rsaquo;&amp;rsaquo;&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="racer-touch"&gt;
&lt;div class="touch-cluster touch-cluster--drive" aria-label="Speed controls (left thumb)"&gt;
&lt;button class="touch-btn touch-btn--gas" id="racerBtnGas" type="button" aria-label="Accelerate"&gt;GAS&lt;/button&gt;
&lt;button class="touch-btn touch-btn--brake" id="racerBtnBrake" type="button" aria-label="Brake"&gt;BRAKE&lt;/button&gt;
&lt;/div&gt;
&lt;div class="touch-cluster touch-cluster--steer" aria-label="Steering controls (right thumb)"&gt;
&lt;button class="touch-btn touch-btn--arrow" id="racerBtnLeft" type="button" aria-label="Steer left"&gt;&amp;larr;&lt;/button&gt;
&lt;button class="touch-btn touch-btn--arrow" id="racerBtnRight" type="button" aria-label="Steer right"&gt;&amp;rarr;&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class="racer-note"&gt;Built with vanilla JavaScript and &lt;a href="https://threejs.org/" rel="noopener"&gt;three.js&lt;/a&gt;. Car models "&lt;a href="https://sketchfab.com/3d-models/mazda-miata-mx-5-na-d51fcd44b74f4daf8012c41e0400c041" rel="noopener"&gt;Mazda Miata MX-5 NA&lt;/a&gt;" and "&lt;a href="https://sketchfab.com/3d-models/toyota-ae86-trueno-fe02fba6302e450ea8424591493341ea" rel="noopener"&gt;Toyota AE86 Trueno&lt;/a&gt;" by Lexyc16 on Sketchfab (CC-BY 4.0). Textures and lighting from &lt;a href="https://polyhaven.com/" rel="noopener"&gt;Poly Haven&lt;/a&gt; (CC0). Your best lap time is stored locally in your browser.&lt;/p&gt;
&lt;/div&gt;</description></item><item><title>Tesla Wrap Maker</title><link>https://vijay.eu/projects/tesla-wrap/</link><pubDate>Sat, 09 May 2026 00:00:00 +0300</pubDate><guid>https://vijay.eu/projects/tesla-wrap/</guid><description>&lt;p&gt;Design custom Tesla wraps in the browser, download the PNG for Paint Shop, and preview supported models in 3D.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://vijay.eu/tesla-wrap/" class="button"&gt;Open Tesla Wrap Maker&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://vijay.eu/images/tesla_wrap_screenshot.png" alt="Tesla Wrap Maker screenshot"&gt;&lt;/p&gt;</description></item><item><title>Note Quest</title><link>https://vijay.eu/projects/note-quest/</link><pubDate>Thu, 26 Feb 2026 00:00:00 +0200</pubDate><guid>https://vijay.eu/projects/note-quest/</guid><description>&lt;p&gt;Learn to read music notes on the grand staff! Pick the correct note name for each question.&lt;/p&gt;
&lt;p&gt;Created using Claude Code CLI on 26th Feb 2026. V2 released on 8th Mar 2026.
&lt;link rel="stylesheet" href="https://vijay.eu/css/note-quest.css"&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/vexflow/build/cjs/vexflow.js"&gt;&lt;/script&gt;
&lt;div class="note-quest-wrapper"&gt;
&lt;div class="nq-screen start-screen active" id="nqStartScreen"&gt;
&lt;label class="nq-helper-toggle"&gt;
&lt;input type="checkbox" id="nqShowNoteNames"&gt; Show note names on staff
&lt;small class="nq-helper-hint"&gt;Auto for Levels 1–2, 4 · Ignored for 8–10&lt;/small&gt;
&lt;/label&gt;
&lt;div class="level-grid"&gt;
&lt;div class="level-row"&gt;
&lt;span class="row-label easy"&gt;Easy&lt;/span&gt;
&lt;div class="level-boxes"&gt;
&lt;button class="level-box easy" data-level="1"&gt;
&lt;span class="level-num"&gt;1&lt;/span&gt;
&lt;span class="level-detail"&gt;First Notes · Both clefs · F3,C4 / C4,G4&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box easy" data-level="2"&gt;
&lt;span class="level-num"&gt;2&lt;/span&gt;
&lt;span class="level-detail"&gt;Staff Basics · Both clefs · F3–G4&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box easy" data-level="3"&gt;
&lt;span class="level-num"&gt;3&lt;/span&gt;
&lt;span class="level-detail"&gt;Getting Comfortable · Both clefs · C3–C5&lt;/span&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="level-row"&gt;
&lt;span class="row-label medium"&gt;Medium&lt;/span&gt;
&lt;div class="level-boxes"&gt;
&lt;button class="level-box medium" data-level="4"&gt;
&lt;span class="level-num"&gt;4&lt;/span&gt;
&lt;span class="level-detail"&gt;Wider Range · Both clefs · A2–E5&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box medium" data-level="5"&gt;
&lt;span class="level-num"&gt;5&lt;/span&gt;
&lt;span class="level-detail"&gt;Grand Staff · Both clefs · C2–C6&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box medium" data-level="6"&gt;
&lt;span class="level-num"&gt;6&lt;/span&gt;
&lt;span class="level-detail"&gt;Expanding Range · Both clefs · A1–E6&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box medium" data-level="7"&gt;
&lt;span class="level-num"&gt;7&lt;/span&gt;
&lt;span class="level-detail"&gt;Full Staff · Both clefs · E2–C6&lt;/span&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="level-row"&gt;
&lt;span class="row-label hard"&gt;Hard&lt;/span&gt;
&lt;div class="level-boxes"&gt;
&lt;button class="level-box hard" data-level="8"&gt;
&lt;span class="level-num"&gt;8&lt;/span&gt;
&lt;span class="level-detail"&gt;Ledger Lines · Both clefs · C2–E6&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box hard" data-level="9"&gt;
&lt;span class="level-num"&gt;9&lt;/span&gt;
&lt;span class="level-detail"&gt;Extended Range · Both clefs · B1–E6&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box hard" data-level="10"&gt;
&lt;span class="level-num"&gt;10&lt;/span&gt;
&lt;span class="level-detail"&gt;Note Master · Both clefs · A1–E6&lt;/span&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nq-version"&gt;v2.1&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nq-screen" id="nqGameScreen"&gt;
&lt;div class="nq-header"&gt;
&lt;div class="nq-logo"&gt;Note Quest&lt;/div&gt;
&lt;div class="nq-progress" id="nqProgress"&gt;1 / 10&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nq-container"&gt;
&lt;div class="staff-card" id="nqStaffCard"&gt;&lt;/div&gt;
&lt;div class="choices" id="nqChoices"&gt;
&lt;button class="choice-btn" data-note="C"&gt;C&lt;/button&gt;
&lt;button class="choice-btn" data-note="D"&gt;D&lt;/button&gt;
&lt;button class="choice-btn" data-note="E"&gt;E&lt;/button&gt;
&lt;button class="choice-btn" data-note="F"&gt;F&lt;/button&gt;
&lt;button class="choice-btn" data-note="G"&gt;G&lt;/button&gt;
&lt;button class="choice-btn" data-note="A"&gt;A&lt;/button&gt;
&lt;button class="choice-btn" data-note="B"&gt;B&lt;/button&gt;
&lt;/div&gt;
&lt;div class="stats-bar"&gt;
&lt;span&gt;Streak: &lt;strong id="nqStreakDisplay"&gt;0&lt;/strong&gt;&lt;/span&gt;
&lt;span&gt;Score: &lt;strong id="nqScoreDisplay"&gt;0&lt;/strong&gt;&lt;/span&gt;
&lt;span id="nqTimerDisplay"&gt;0:00&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nq-screen results-screen" id="nqResultsScreen"&gt;
&lt;h2&gt;Round Complete!&lt;/h2&gt;
&lt;div class="stars" id="nqStarsDisplay"&gt;&lt;/div&gt;
&lt;div class="results-stats" id="nqResultsStats"&gt;&lt;/div&gt;
&lt;button class="play-again-btn"&gt;Play Again&lt;/button&gt;
&lt;/div&gt;
&lt;canvas id="nqConfetti"&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;script src="https://vijay.eu/js/note-quest.js"&gt;&lt;/script&gt;
&lt;/p&gt;</description></item><item><title>Tic Tac Toe</title><link>https://vijay.eu/projects/tic-tac-toe/</link><pubDate>Wed, 02 Jul 2025 15:20:07 +0300</pubDate><guid>https://vijay.eu/projects/tic-tac-toe/</guid><description>&lt;p&gt;Created it using Google Gemini CLI on 2nd Jul 2025
&lt;link rel="stylesheet" href="https://vijay.eu/css/tic-tac-toe.css"&gt;
&lt;div class="tic-tac-toe-container"&gt;
&lt;div id="game-setup"&gt;
&lt;div class="setup-section"&gt;
&lt;p class="setup-title"&gt;Game Mode&lt;/p&gt;
&lt;div class="button-group" id="game-mode-selector"&gt;
&lt;button class="btn-toggle active" data-mode="pvc"&gt;Player vs. Computer&lt;/button&gt;
&lt;button class="btn-toggle" data-mode="pvp"&gt;Player vs. Player&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="setup-section" id="first-move-container"&gt;
&lt;p class="setup-title"&gt;Who Goes First?&lt;/p&gt;
&lt;div class="button-group" id="first-move-selector"&gt;
&lt;button class="btn-toggle active" data-first-move="player"&gt;Player (X)&lt;/button&gt;
&lt;button class="btn-toggle" data-first-move="computer"&gt;Computer (O)&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;button id="start-game"&gt;Start Game&lt;/button&gt;
&lt;/div&gt;
&lt;div id="game-board" class="hidden"&gt;
&lt;div class="cell" data-index="0"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="1"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="2"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="3"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="4"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="5"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="6"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="7"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="8"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id="message" class="hidden"&gt;&lt;/div&gt;
&lt;button id="restart-game" class="hidden"&gt;Restart Game&lt;/button&gt;
&lt;/div&gt;
&lt;script src="https://vijay.eu/js/tic-tac-toe.js"&gt;&lt;/script&gt;
&lt;/p&gt;</description></item><item><title>Decibel Meter</title><link>https://vijay.eu/projects/decibel-meter/</link><pubDate>Wed, 12 Mar 2025 23:28:14 +0200</pubDate><guid>https://vijay.eu/projects/decibel-meter/</guid><description>&lt;p&gt;Built using Anthropic Claude Code CLI.&lt;/p&gt;
&lt;div class="decibel-meter-wrapper"&gt;
&lt;div class="speedometer-container"&gt;
&lt;div class="needle-container"&gt;
&lt;div class="needle" id="needle"&gt;&lt;/div&gt;
&lt;div class="needle-center"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="reading" id="reading"&gt;0 dB&lt;/div&gt;
&lt;div class="description" id="description"&gt;Please enable microphone&lt;/div&gt;
&lt;button id="startButton"&gt;Start Measuring&lt;/button&gt;
&lt;div class="sensitivity-control"&gt;
&lt;label for="sensitivity"&gt;Microphone Sensitivity: &lt;span id="sensitivityValue"&gt;&lt;/span&gt;&lt;/label&gt;
&lt;input type="range" id="sensitivity" min="1" max="5" step="0.5" value="2.0"&gt;
&lt;/div&gt;
&lt;div class="error" id="errorMessage"&gt;&lt;/div&gt;
&lt;div class="child-voice-legend"&gt;
&lt;div class="child-voice-title"&gt;Voice Level Guide for Kids&lt;/div&gt;
&lt;div class="voice-level-item"&gt;
&lt;div class="voice-level-color" style="background: #4CAF50;"&gt;&lt;/div&gt;
&lt;span class="voice-level-text"&gt;Whisper to Library Voice (0-40 dB)&lt;/span&gt;
&lt;/div&gt;
&lt;div class="voice-level-item"&gt;
&lt;div class="voice-level-color" style="background: #7CB342;"&gt;&lt;/div&gt;
&lt;span class="voice-level-text"&gt;Indoor Voice (40-60 dB)&lt;/span&gt;
&lt;/div&gt;
&lt;div class="voice-level-item"&gt;
&lt;div class="voice-level-color" style="background: #FFC107;"&gt;&lt;/div&gt;
&lt;span class="voice-level-text"&gt;Classroom Voice (60-70 dB)&lt;/span&gt;
&lt;/div&gt;
&lt;div class="voice-level-item"&gt;
&lt;div class="voice-level-color" style="background: #FF9800;"&gt;&lt;/div&gt;
&lt;span class="voice-level-text"&gt;Playground Voice (70-80 dB)&lt;/span&gt;
&lt;/div&gt;
&lt;div class="voice-level-item"&gt;
&lt;div class="voice-level-color" style="background: #FF5722;"&gt;&lt;/div&gt;
&lt;span class="voice-level-text"&gt;Too Loud! (80+ dB)&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;script src="https://vijay.eu/js/decibel-meter.js"&gt;&lt;/script&gt;
&lt;link rel="stylesheet" href="https://vijay.eu/css/decibel-meter.css"&gt;
&lt;ul&gt;
&lt;li&gt;No data is stored or transmitted - all processing happens locally in your browser.&lt;/li&gt;
&lt;li&gt;dB values are approximate. Calibration has not been done.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Classic Snake Game</title><link>https://vijay.eu/projects/snake-game/</link><pubDate>Sun, 16 Feb 2025 19:58:58 +0200</pubDate><guid>https://vijay.eu/projects/snake-game/</guid><description>
&lt;style&gt;
.game-container {
display: flex;
flex-direction: column;
align-items: center;
margin: 20px auto;
max-width: 100%;
}
.game-title {
font-size: 36px;
font-weight: bold;
margin-bottom: 20px;
text-align: center;
font-family: Arial, sans-serif;
}
.speed-selector {
margin: 10px 0;
padding: 10px;
display: flex;
gap: 10px;
justify-content: center;
}
.speed-btn {
padding: 8px 16px;
border: 2px solid #333;
border-radius: 5px;
background: white;
cursor: pointer;
font-family: Arial, sans-serif;
transition: all 0.3s ease;
}
.speed-btn.active {
background: #333;
color: white;
}
#gameCanvas {
border: 2px solid #333;
background: #f0f0f0;
max-width: 100%;
touch-action: none;
}
.controls {
display: none;
margin-top: 20px;
touch-action: none;
}
@media (max-width: 768px) {
.controls {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
width: 200px;
}
.control-btn {
padding: 15px;
background: #333;
color: white;
border: none;
border-radius: 5px;
font-size: 18px;
touch-action: none;
}
.control-btn:active {
background: #555;
}
#up { grid-column: 2; grid-row: 1; }
#left { grid-column: 1; grid-row: 2; }
#right { grid-column: 3; grid-row: 2; }
#down { grid-column: 2; grid-row: 3; }
}
.score {
font-size: 24px;
margin: 10px 0;
font-family: Arial, sans-serif;
}
.game-over {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 20px;
border-radius: 10px;
text-align: center;
z-index: 1000;
}
.restart-btn {
margin-top: 10px;
padding: 10px 20px;
background: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.restart-btn:hover {
background: #45a049;
}
&lt;/style&gt;
&lt;div class="game-container"&gt;
&lt;div class="speed-selector"&gt;
&lt;button class="speed-btn" data-speed="slow"&gt;Slow&lt;/button&gt;
&lt;button class="speed-btn active" data-speed="normal"&gt;Normal&lt;/button&gt;
&lt;button class="speed-btn" data-speed="fast"&gt;Fast&lt;/button&gt;
&lt;/div&gt;
&lt;div class="score"&gt;Score: &lt;span id="scoreValue"&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;canvas id="gameCanvas" width="400" height="400"&gt;&lt;/canvas&gt;
&lt;div class="controls"&gt;
&lt;button id="up" class="control-btn"&gt;↑&lt;/button&gt;
&lt;button id="left" class="control-btn"&gt;←&lt;/button&gt;
&lt;button id="right" class="control-btn"&gt;→&lt;/button&gt;
&lt;button id="down" class="control-btn"&gt;↓&lt;/button&gt;
&lt;/div&gt;
&lt;div class="game-over" id="gameOver"&gt;
&lt;h2&gt;Game Over!&lt;/h2&gt;
&lt;p&gt;Final Score: &lt;span id="finalScore"&gt;0&lt;/span&gt;&lt;/p&gt;
&lt;button class="restart-btn" onclick="restartGame()"&gt;Play Again&lt;/button&gt;
&lt;/div&gt;
&lt;p&gt;This classic snake game has been created using Anthropic Claude in a single prompt on 16 Feb 2025. Documenting it for future reference to track the speed of development in GenAI/LLMs. &lt;/p&gt;
&lt;/div&gt;
&lt;script&gt;
(function() {
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreElement = document.getElementById('scoreValue');
const finalScoreElement = document.getElementById('finalScore');
const gameOverElement = document.getElementById('gameOver');
const speedButtons = document.querySelectorAll('.speed-btn');
const gridSize = 20;
const tileCount = canvas.width / gridSize;
let snake = [{ x: 10, y: 10 }];
let food = { x: 15, y: 15 };
let dx = 0;
let dy = 0;
let score = 0;
let gameLoop;
const speeds = {
slow: 150,
normal: 100,
fast: 70
};
let currentSpeed = speeds.normal;
let baseSpeed = speeds.normal;
function setSpeed(speedType) {
baseSpeed = speeds[speedType];
currentSpeed = baseSpeed;
if (gameLoop) {
clearInterval(gameLoop);
gameLoop = setInterval(drawGame, currentSpeed);
}
speedButtons.forEach(btn =&gt; {
btn.classList.remove('active');
if (btn.dataset.speed === speedType) {
btn.classList.add('active');
}
});
}
speedButtons.forEach(button =&gt; {
button.addEventListener('click', () =&gt; {
setSpeed(button.dataset.speed);
});
});
function drawGame() {
clearCanvas();
moveSnake();
checkCollision();
drawFood();
drawSnake();
}
function clearCanvas() {
ctx.fillStyle = '#f0f0f0';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
function drawSnake() {
ctx.fillStyle = '#4CAF50';
snake.forEach(segment =&gt; {
ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize - 2, gridSize - 2);
});
}
function drawFood() {
ctx.fillStyle = '#FF0000';
ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize - 2, gridSize - 2);
}
function moveSnake() {
const head = { x: snake[0].x + dx, y: snake[0].y + dy };
snake.unshift(head);
if (head.x === food.x &amp;&amp; head.y === food.y) {
score += 10;
scoreElement.textContent = score;
generateFood();
increaseSpeed();
} else {
snake.pop();
}
}
function generateFood() {
food = {
x: Math.floor(Math.random() * tileCount),
y: Math.floor(Math.random() * tileCount)
};
if (snake.some(segment =&gt; segment.x === food.x &amp;&amp; segment.y === food.y)) {
generateFood();
}
}
function checkCollision() {
const head = snake[0];
if (head.x &lt; 0 || head.x &gt;= tileCount || head.y &lt; 0 || head.y &gt;= tileCount) {
gameOver();
}
for (let i = 1; i &lt; snake.length; i++) {
if (head.x === snake[i].x &amp;&amp; head.y === snake[i].y) {
gameOver();
}
}
}
function gameOver() {
clearInterval(gameLoop);
finalScoreElement.textContent = score;
gameOverElement.style.display = 'block';
}
window.restartGame = function() {
snake = [{ x: 10, y: 10 }];
food = { x: 15, y: 15 };
dx = 0;
dy = 0;
score = 0;
currentSpeed = baseSpeed;
scoreElement.textContent = '0';
gameOverElement.style.display = 'none';
gameLoop = setInterval(drawGame, currentSpeed);
}
function increaseSpeed() {
if (currentSpeed &gt; baseSpeed * 0.5) {
clearInterval(gameLoop);
currentSpeed -= 2;
gameLoop = setInterval(drawGame, currentSpeed);
}
}
document.addEventListener('keydown', (event) =&gt; {
switch(event.key) {
case 'ArrowUp':
if (dy === 0) { dx = 0; dy = -1; }
break;
case 'ArrowDown':
if (dy === 0) { dx = 0; dy = 1; }
break;
case 'ArrowLeft':
if (dx === 0) { dx = -1; dy = 0; }
break;
case 'ArrowRight':
if (dx === 0) { dx = 1; dy = 0; }
break;
}
});
const controlButtons = document.querySelectorAll('.control-btn');
controlButtons.forEach(button =&gt; {
button.addEventListener('touchstart', (e) =&gt; {
e.preventDefault();
switch(button.id) {
case 'up':
if (dy === 0) { dx = 0; dy = -1; }
break;
case 'down':
if (dy === 0) { dx = 0; dy = 1; }
break;
case 'left':
if (dx === 0) { dx = -1; dy = 0; }
break;
case 'right':
if (dx === 0) { dx = 1; dy = 0; }
break;
}
});
});
gameLoop = setInterval(drawGame, currentSpeed);
})();
&lt;/script&gt;</description></item></channel></rss>