Temple Run Github //free\\ -
## **3. GitHub Description**
// ----- GAME STATE ----- let gameRunning = true; let score = 0; let highScore = localStorage.getItem('templeHigh') ? parseInt(localStorage.getItem('templeHigh')) : 0; document.getElementById('highScoreValue').innerText = highScore; // ----- PLAYER ----- const LANE_COUNT = 3; const LANE_WIDTH = 120; const PLAYER_WIDTH = 48; const PLAYER_HEIGHT = 52; // lane positions (center X) const laneXs = [220, 400, 580]; let currentLane = 1; // 0=left,1=middle,2=right let playerY = canvas.height - 100; // ground Y let isJumping = false; let jumpVelocity = 0; const GRAVITY = 0.8; const JUMP_POWER = -12; let groundY = canvas.height - 100; // ----- OBSTACLES ----- let obstacles = []; let obstacleTimer = 0; const OBSTACLE_BASE_INTERVAL = 70; // frames const OBSTACLE_WIDTH = 40; const OBSTACLE_HEIGHT = 48; // ----- COINS ----- let coins = []; let coinTimer = 0; const COIN_BASE_INTERVAL = 45; const COIN_WIDTH = 28; const COIN_HEIGHT = 28; // ----- VISUALS / FX ----- let frame = 0; let cameraShake = 0; // ----- helper functions ----- function updateUI() document.getElementById('scoreValue').innerText = Math.floor(score); if(score > highScore) highScore = Math.floor(score); localStorage.setItem('templeHigh', highScore); document.getElementById('highScoreValue').innerText = highScore; function resetGame() gameRunning = true; score = 0; obstacles = []; coins = []; currentLane = 1; isJumping = false; jumpVelocity = 0; playerY = groundY; obstacleTimer = 15; // small delay after reset coinTimer = 8; cameraShake = 0; updateUI(); function addObstacle() let lane = Math.floor(Math.random() * LANE_COUNT); obstacles.push( x: laneXs[lane] - OBSTACLE_WIDTH/2, y: groundY + 8, // slightly above ground to look like standing width: OBSTACLE_WIDTH, height: OBSTACLE_HEIGHT, lane: lane, active: true ); function addCoin() let lane = Math.floor(Math.random() * LANE_COUNT); // avoid overlapping exactly with fresh obstacle? not critical, fun chaos coins.push( x: laneXs[lane] - COIN_WIDTH/2, y: groundY - 10, width: COIN_WIDTH, height: COIN_HEIGHT, lane: lane, collected: false ); function updateMovement() if(!gameRunning) return; // jump physics if(isJumping) playerY += jumpVelocity; jumpVelocity += GRAVITY; if(playerY >= groundY) playerY = groundY; isJumping = false; jumpVelocity = 0; // move obstacles + collision + score gain on pass for(let i=0; i<obstacles.length; i++) let obs = obstacles[i]; obs.x -= 5; // scroll speed // collision detection (only if not jumping over? simple version: if touching and not jumping) let playerRect = x: laneXs[currentLane] - PLAYER_WIDTH/2, y: playerY, w: PLAYER_WIDTH, h: PLAYER_HEIGHT ; let obsRect = x: obs.x, y: obs.y, w: obs.width, h: obs.height ; if(!isJumping && playerRect.x < obsRect.x+obsRect.w && playerRect.x+playerRect.w > obsRect.x && playerRect.y < obsRect.y+obsRect.h && playerRect.y+playerRect.h > obsRect.y) gameRunning = false; cameraShake = 12; // remove if offscreen if(obs.x + obs.width < 0) obstacles.splice(i,1); i--; // coins collection + scoring for(let i=0; i<coins.length; i++) let coin = coins[i]; coin.x -= 5; let playerRect = x: laneXs[currentLane] - PLAYER_WIDTH/2, y: playerY, w: PLAYER_WIDTH, h: PLAYER_HEIGHT ; let coinRect = x: coin.x, y: coin.y, w: COIN_WIDTH, h: COIN_HEIGHT ; if(playerRect.x < coinRect.x+coinRect.w && playerRect.x+playerRect.w > coinRect.x && playerRect.y < coinRect.y+coinRect.h && playerRect.y+playerRect.h > coinRect.y) // collect coin score += 10; updateUI(); coins.splice(i,1); i--; else if(coin.x + COIN_WIDTH < 0) coins.splice(i,1); i--; // dynamic spawn if(gameRunning) obstacleTimer--; if(obstacleTimer <= 0) let interval = Math.max(35, OBSTACLE_BASE_INTERVAL - Math.floor(score/500)); addObstacle(); obstacleTimer = interval; coinTimer--; if(coinTimer <= 0) let coinInterval = Math.max(25, COIN_BASE_INTERVAL - Math.floor(score/700)); addCoin(); coinTimer = coinInterval; // increase score over time (distance) score += 0.35; updateUI(); // camera shake fade if(cameraShake > 0) cameraShake -= 0.6; else cameraShake = 0; // ----- DRAW EVERYTHING ----- function draw() ctx.clearRect(0,0,canvas.width,canvas.height); // apply camera shake let shakeX = (Math.random() * cameraShake) - (cameraShake/2); let shakeY = (Math.random() * cameraShake*0.6) - (cameraShake*0.3); ctx.save(); ctx.translate(shakeX, shakeY); // ---- FLOOR & TEMPLE ATMOSPHERE ---- // stone floor pattern ctx.fillStyle = "#4a3728"; ctx.fillRect(0, groundY+20, canvas.width, canvas.height-groundY-10); ctx.fillStyle = "#6b4c3b"; for(let i=0;i<20;i++) ctx.fillRect(i*70, groundY+18, 35, 8); // background: temple wall ctx.fillStyle = "#2c2118"; ctx.fillRect(0,0,canvas.width, groundY-20); // torches for(let i=0;i<6;i++) ctx.fillStyle = "#c97e3a"; ctx.fillRect(50+i*150, groundY-70, 12, 60); ctx.fillStyle = "#ffaa44"; ctx.beginPath(); ctx.arc(56+i*150, groundY-76, 10, 0, Math.PI*2); ctx.fill(); ctx.fillStyle = "#ff6600"; ctx.beginPath(); ctx.arc(56+i*150, groundY-78, 5, 0, Math.PI*2); ctx.fill(); // ---- LANE MARKERS ---- ctx.strokeStyle = "#e8c468"; ctx.lineWidth = 3; for(let i=0; i<=LANE_COUNT; i++) let x = (i * LANE_WIDTH) + 100; ctx.beginPath(); ctx.setLineDash([12, 20]); ctx.moveTo(x, groundY-10); ctx.lineTo(x, groundY+35); ctx.stroke(); ctx.setLineDash([]); // ---- OBSTACLES (idols / pillars) ---- for(let obs of obstacles) // shadow ctx.fillStyle = "#2f241b"; ctx.fillRect(obs.x+4, obs.y+6, obs.width, obs.height); ctx.fillStyle = "#8b5a2b"; ctx.fillRect(obs.x, obs.y, obs.width, obs.height); ctx.fillStyle = "#b87c4f"; ctx.fillRect(obs.x+6, obs.y-8, obs.width-12, 12); ctx.fillStyle = "#d9a13b"; ctx.beginPath(); ctx.ellipse(obs.x+obs.width/2, obs.y-4, 12, 6, 0, 0, Math.PI*2); ctx.fill(); // scary eyes ctx.fillStyle = "#ff2200"; ctx.fillRect(obs.x+8, obs.y+15, 8, 8); ctx.fillRect(obs.x+obs.width-16, obs.y+15, 8, 8); // ---- COINS ---- for(let coin of coins) ctx.fillStyle = "#f5d742"; ctx.shadowBlur = 8; ctx.shadowColor = "#ffbf00"; ctx.beginPath(); ctx.ellipse(coin.x+COIN_WIDTH/2, coin.y+COIN_HEIGHT/2, COIN_WIDTH/2, COIN_HEIGHT/2, 0, 0, Math.PI*2); ctx.fill(); ctx.fillStyle = "#f5a623"; ctx.beginPath(); ctx.ellipse(coin.x+COIN_WIDTH/2, coin.y+COIN_HEIGHT/2, COIN_WIDTH/3, COIN_HEIGHT/3, 0, 0, Math.PI*2); ctx.fill(); ctx.fillStyle = "#ffffffcc"; ctx.font = "bold 18 monospace"; ctx.fillText("★", coin.x+6, coin.y+22); ctx.shadowBlur = 0; // ---- PLAYER (RUNNER) ---- let playerX = laneXs[currentLane] - PLAYER_WIDTH/2; let bobOffset = isJumping ? 0 : Math.sin(frame * 0.2) * 2; ctx.fillStyle = "#2c5f2d"; ctx.shadowBlur = 0; ctx.fillRect(playerX, playerY + bobOffset, PLAYER_WIDTH, PLAYER_HEIGHT); ctx.fillStyle = "#b87333"; ctx.fillRect(playerX+8, playerY+10 + bobOffset, 8, 16); ctx.fillRect(playerX+PLAYER_WIDTH-16, playerY+10 + bobOffset, 8, 16); ctx.fillStyle = "#f4c542"; ctx.beginPath(); ctx.arc(playerX+PLAYER_WIDTH/2, playerY-5 + bobOffset, 14, 0, Math.PI*2); ctx.fill(); ctx.fillStyle = "#000"; ctx.fillRect(playerX+12, playerY-2 + bobOffset, 6, 6); ctx.fillRect(playerX+PLAYER_WIDTH-18, playerY-2 + bobOffset, 6, 6); // scarf ctx.fillStyle = "#e34234"; ctx.fillRect(playerX+12, playerY+28+bobOffset, PLAYER_WIDTH-24, 8); // ---- GAME OVER MESSAGE ---- if(!gameRunning) ctx.font = "bold 42 'Courier New'"; ctx.shadowBlur = 0; ctx.fillStyle = "#ffbb66"; ctx.shadowColor = "black"; ctx.fillText("GAME OVER", canvas.width/2-130, 120); ctx.font = "24px monospace"; ctx.fillStyle = "#fadfaa"; ctx.fillText("tap RUN AGAIN", canvas.width/2-90, 190); // ---- SCORE ON CANVAS ---- ctx.font = "bold 24 'Courier New'"; ctx.fillStyle = "#ffeaac"; ctx.shadowBlur = 2; ctx.fillText("🏃 " + Math.floor(score), 25, 60); ctx.restore(); // end shake frame++; // ----- CONTROLS (keyboard)----- function handleKey(e) key === 'A') currentLane = Math.max(0, currentLane-1); else if(key === 'ArrowRight' // ----- ANIMATION LOOP ----- function gameLoop() updateMovement(); draw(); requestAnimationFrame(gameLoop); // event listeners window.addEventListener('keydown', handleKey); document.getElementById('resetBtn').addEventListener('click', () => resetGame(); ); // mobile friendly (simple touch for lane change) canvas.addEventListener('click', (e) => if(!gameRunning) return; let rect = canvas.getBoundingClientRect(); let clickX = (e.clientX - rect.left) * (canvas.width/rect.width); if(clickX < canvas.width/3) currentLane = Math.max(0, currentLane-1); else if(clickX > 2*canvas.width/3) currentLane = Math.min(LANE_COUNT-1, currentLane+1); else if(!isJumping) isJumping = true; jumpVelocity = JUMP_POWER; ); // init resetGame(); gameLoop(); )(); </script> </body> </html> # 🏃 Temple Run: Endless Chase A browser-based infinite runner inspired by the classic Temple Run. Dodge ancient obstacles, grab golden coins, and survive as long as you can!
Let me know if you'd like me to add **power-ups**, **mobile swipe controls**, or a **start screen**! </code></pre> temple run github
---
---
> **Temple Run** – an endless runner game in pure HTML/CSS/JS. Dodge obstacles, collect coins, survive the ancient temple. Works on desktop & mobile. No dependencies.
index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>Temple Run - GitHub Game</title> <style> * margin: 0; padding: 0; box-sizing: border-box; user-select: none; body background: linear-gradient(145deg, #0a2f1f 0%, #05180e 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; font-family: 'Courier New', 'Monaco', monospace; .game-container padding: 20px; border-radius: 28px; background: rgba(0,0,0,0.3); box-shadow: 0 20px 35px rgba(0,0,0,0.5); canvas display: block; margin: 0 auto; border-radius: 16px; box-shadow: 0 0 0 4px #d4af37, 0 0 0 8px #3e2a1f; cursor: pointer; .info-panel display: flex; justify-content: space-between; align-items: center; margin-top: 20px; padding: 12px 24px; background: #1e1a0c; border-radius: 60px; color: #f7e05e; text-shadow: 0 2px 0 #5a3e1a; font-weight: bold; font-size: 1.4rem; gap: 30px; flex-wrap: wrap; justify-content: center; .score-box, .high-box background: #000000aa; backdrop-filter: blur(4px); padding: 8px 20px; border-radius: 40px; letter-spacing: 1px; button background: #e25822; border: none; font-family: inherit; font-weight: bold; font-size: 1.2rem; padding: 8px 24px; border-radius: 60px; color: white; text-shadow: 0 1px 0 #7a2e0a; cursor: pointer; transition: 0.1s linear; box-shadow: 0 5px 0 #752e0a; button:active transform: translateY(2px); box-shadow: 0 2px 0 #752e0a; .controls display: flex; gap: 15px; background: #2d2418aa; padding: 8px 20px; border-radius: 60px; font-size: 0.9rem; .controls span background: #0f0f0fcc; padding: 5px 12px; border-radius: 40px; color: #ffd966; @media (max-width: 780px) .info-panel flex-direction: column; align-items: stretch; gap: 12px; .controls justify-content: center; .score-box, .high-box text-align: center; </style> </head> <body> <div> <div class="game-container"> <canvas id="gameCanvas" width="800" height="500"></canvas> <div class="info-panel"> <div class="score-box">🏆 SCORE: <span id="scoreValue">0</span></div> <div class="high-box">👑 BEST: <span id="highScoreValue">0</span></div> <button id="resetBtn">🔄 RUN AGAIN</button> <div class="controls"> <span>⬅️ A / ←</span> <span>➡️ D / →</span> <span>⬆️ W / ↑ (jump)</span> </div> </div> </div> <p style="text-align:center; margin-top:16px; color:#d4c9a3;">🏃♂️ Dodge obstacles | Collect coins | Survive the temple!</p> </div> <script> (function() // ----- CANVAS ----- const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); ## **3
The game includes: - 3-lane dodging - Jump mechanic - Coins + score - Persistent high score - Increasing difficulty - Camera shake on collision - Touch & keyboard support






