Run Github: Temple

> **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.

## **4. How to Upload to GitHub**

---

// ----- 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) // ----- 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! temple run github

## **3. GitHub Description**

couchtuner.one is not a video hosting site. We simply provide links to videos that are hosted elsewhere. If you have any legal concerns, please contact the website that is hosting the video.
temple run github
Copyright © 2024