Score: 0 | Speed Lv: 1 | Jump Lv: 1

Game Over

Press R to Restart

'; document.body.appendChild(adDiv); /* ========================= MAIN LOOP ========================= */ let spawnTimer=0, upgradeTimer=0; function animate(){ requestAnimationFrame(animate); if(!gameOver){ speed+=0.00015; score+=speed*2; player.position.x=lanes[currentLane]; if(isJumping){jumpVelocity+=gravity; player.position.y+=jumpVelocity; if(player.position.y<=1){player.position.y=1; isJumping=false;}} obstacles.forEach(o=>{o.position.z+=speed*2.2; if(hit(player,o)) endGame();}); upgrades.forEach(u=>{u.position.z+=speed*2.2; u.rotation.y+=0.05; if(hit(player,u,1.3,1.5,1)){ if(u.userData.type==="speed"){speedLevel++; speed+=0.04;} else{jumpLevel++; jumpStrength+=0.08;} scene.remove(u); upgrades.splice(upgrades.indexOf(u),1); } }); obstacles=obstacles.filter(o=>o.position.z<=10); upgrades=upgrades.filter(u=>u.position.z<=10); spawnTimer+=speed; upgradeTimer+=speed; if(spawnTimer>5){spawnObstacle(); spawnTimer=0;} if(upgradeTimer>18){spawnUpgrade(); upgradeTimer=0;} camera.position.z=player.position.z+7; camera.position.x=player.position.x*0.3; camera.lookAt(player.position.x,1.4,player.position.z-5); document.getElementById("hud").textContent="Score: "+Math.floor(score)+" | Speed Lv: "+speedLevel+" | Jump Lv: "+jumpLevel; } // Position ad above player in screen space const vector = player.position.clone(); vector.project(camera); const x = (vector.x*0.5+0.5)*window.innerWidth; const y = (-vector.y*0.5+0.5)*window.innerHeight - 50; adDiv.style.left = x + "px"; adDiv.style.top = y + "px"; renderer.render(scene,camera); } animate(); /* ========================= RESIZE ========================= */ window.addEventListener("resize",()=>{ camera.aspect=window.innerWidth/window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth,window.innerHeight); });