Meta Description" name="description" />
<!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>Bharat Dash: Slow Motion</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body { margin: 0; overflow: hidden; background: #87CEEB; font-family: 'Inter', sans-serif; touch-action: none; }
canvas { display: block; }
.ui-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; }
.interactive { pointer-events: auto; }
.saffron-gradient { background: linear-gradient(to right, #FF9933, #FFCC33); }
@keyframes pulse-slow { 0%, 100% { opacity: 1; } 50% { opacity: 0.7; } }
.animate-pulse-slow { animation: pulse-slow 3s infinite ease-in-out; }
</style>
</head>
<body>
<div id="ui-container" class="ui-overlay flex flex-col items-center justify-between p-6">
<div class="w-full flex justify-between items-start">
<div class="bg-black/40 backdrop-blur-md p-4 rounded-2xl border border-white/20">
<p class="text-white/70 text-xs font-bold uppercase tracking-wider">Slow Distance</p>
<p id="score-val" class="text-white text-3xl font-black italic">0m</p>
</div>
<div class="bg-white/90 p-3 rounded-full flex items-center gap-2 shadow-lg">
<span class="text-yellow-500 text-xl">πͺ</span>
<span id="coin-val" class="text-slate-900 font-black text-xl">0</span>
</div>
</div>
<div id="menu-screen" class="interactive flex flex-col items-center gap-4">
<div class="text-center">
<h1 class="text-6xl font-black text-white drop-shadow-2xl italic">RELAXED<br><span class="text-[#FF9933]">RUN</span></h1>
<p class="text-white font-medium mt-2 drop-shadow-md">MODI JI'S STEADY PROGRESS</p>
</div>
<button onclick="startGame()" class="saffron-gradient text-white px-12 py-5 rounded-full font-black text-2xl shadow-2xl hover:scale-105 transition-transform">
START SLOW RUN
</button>
<p class="text-white/80 text-sm font-bold uppercase tracking-widest animate-pulse-slow">Pace: Steady & Smooth</p>
</div>
<div id="game-over-screen" class="hidden interactive flex flex-col items-center gap-6 bg-black/80 fixed inset-0 justify-center">
<h2 class="text-5xl font-black text-white italic">STAY STEADY</h2>
<button onclick="restartGame()" class="saffron-gradient text-white px-12 py-5 rounded-full font-black text-2xl shadow-xl">
RETRY
</button>
</div>
</div>
<script>
/**
* SLOWED DOWN CONFIG
*/
const CONFIG = {
LANE_WIDTH: 4,
LANE_POSITIONS: [-4, 0, 4],
INITIAL_SPEED: 0.4, // Reduced from 0.8
MAX_SPEED: 0.8, // Reduced from 2.8
ACCELERATION: 0.00005, // Significantly reduced
JUMP_FORCE: 0.22, // Lower gravity feel
GRAVITY: 0.008, // Slower falling
LANE_CHANGE_SPEED: 0.08, // Smooth lane change (Reduced from 0.2)
FACE_TEXTURE_URL: "https://i.ibb.co/Xky9H6mN/1000038170.png"
};
let state = {
running: false,
score: 0,
coins: 0,
lane: 1,
speed: CONFIG.INITIAL_SPEED,
playerY: 0,
vVelocity: 0,
isJumping: false,
isRolling: false,
distance: 0
};
let scene, camera, renderer, player, faceTexture;
let trackSegments = [];
let obstacles = [];
let collectibles = [];
function init() {
scene = new THREE.Scene();
scene.fog = new THREE.Fog(0x87CEEB, 20, 100);
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 6, 12);
camera.lookAt(0, 2, 0);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);
const loader = new THREE.TextureLoader();
faceTexture = loader.load(CONFIG.FACE_TEXTURE_URL);
scene.add(new THREE.AmbientLight(0xffffff, 0.8));
const sun = new THREE.DirectionalLight(0xffffff, 0.8);
sun.position.set(5, 15, 5);
scene.add(sun);
createCharacter();
setupTrack();
animate();
}
function createCharacter() {
player = new THREE.Group();
const kurtaMat = new THREE.MeshPhongMaterial({ color: 0xFFFFFF });
// Kurta & Vest
const body = new THREE.Mesh(new THREE.BoxGeometry(1.2, 1.8, 0.8), kurtaMat);
body.position.y = 1.3;
player.add(body);
const vest = new THREE.Mesh(new THREE.BoxGeometry(1.3, 1.3, 0.9), new THREE.MeshPhongMaterial({ color: 0xFF9933 }));
vest.position.y = 1.55;
player.add(vest);
// Head with Face
const headGeo = new THREE.BoxGeometry(1.2, 1.2, 1.2);
const skinMat = new THREE.MeshPhongMaterial({ color: 0xFFDBAC });
const head = new THREE.Mesh(headGeo, [skinMat, skinMat, skinMat, skinMat, new THREE.MeshPhongMaterial({ map: faceTexture }), skinMat]);
head.position.y = 2.8;
player.add(head);
// Hair & Beard
const hair = new THREE.Mesh(new THREE.BoxGeometry(1.3, 0.5, 1.3), new THREE.MeshPhongMaterial({ color: 0xFFFFFF }));
hair.position.y = 3.2;
player.add(hair);
const beard = new THREE.Mesh(new THREE.BoxGeometry(0.9, 0.4, 0.5), new THREE.MeshPhongMaterial({ color: 0xFFFFFF }));
beard.position.set(0, 2.3, 0.4);
player.add(beard);
scene.add(player);
}
function setupTrack() {
for (let i = 0; i < 15; i++) {
const group = new THREE.Group();
const road = new THREE.Mesh(new THREE.PlaneGeometry(15, 20), new THREE.MeshPhongMaterial({ color: 0x555555 }));
road.rotation.x = -Math.PI / 2;
group.add(road);
group.position.z = -i * 20;
scene.add(group);
trackSegments.push(group);
}
}
function spawnObstacle(z) {
if (Math.random() < 0.4) { // Lower frequency for relaxed play
const lane = Math.floor(Math.random() * 3);
const obs = new THREE.Mesh(new THREE.BoxGeometry(3, 1.5, 1), new THREE.MeshPhongMaterial({ color: 0x333333 }));
obs.position.set(CONFIG.LANE_POSITIONS[lane], 0.75, -z);
scene.add(obs);
obstacles.push(obs);
}
}
function update() {
if (!state.running) return;
state.speed = Math.min(CONFIG.MAX_SPEED, state.speed + CONFIG.ACCELERATION);
state.distance += state.speed * 0.1;
document.getElementById('score-val').innerText = Math.floor(state.distance) + 'm';
// SLOW Lane Change Logic
const targetX = CONFIG.LANE_POSITIONS[state.lane];
player.position.x += (targetX - player.position.x) * CONFIG.LANE_CHANGE_SPEED;
// SLOW Gravity Logic
if (state.isJumping || state.playerY > 0) {
state.vVelocity -= CONFIG.GRAVITY;
state.playerY += state.vVelocity;
if (state.playerY <= 0) { state.playerY = 0; state.isJumping = false; }
}
player.position.y = state.playerY;
trackSegments.forEach(seg => {
seg.position.z += state.speed;
if (seg.position.z > 20) {
seg.position.z -= 300;
spawnObstacle(Math.abs(seg.position.z));
}
});
obstacles.forEach((obs, idx) => {
obs.position.z += state.speed;
if (player.position.distanceTo(obs.position) < 2.2) gameOver();
if (obs.position.z > 20) { scene.remove(obs); obstacles.splice(idx, 1); }
});
}
function animate() {
requestAnimationFrame(animate);
update();
renderer.render(scene, camera);
}
function handleInput(dir) {
if (!state.running) return;
if (dir === 'left' && state.lane > 0) state.lane--;
if (dir === 'right' && state.lane < 2) state.lane++;
if (dir === 'up' && !state.isJumping) {
state.isJumping = true;
state.vVelocity = CONFIG.JUMP_FORCE;
}
}
window.addEventListener('keydown', e => {
if (e.key === 'ArrowLeft') handleInput('left');
if (e.key === 'ArrowRight') handleInput('right');
if (e.key === 'ArrowUp') handleInput('up');
});
function startGame() { document.getElementById('menu-screen').classList.add('hidden'); state.running = true; }
function gameOver() { state.running = false; document.getElementById('game-over-screen').classList.remove('hidden'); }
function restartGame() { location.reload(); }
init();
</script>
</body>
</html>
5
4
251KB
996KB
1,518.0ms
1,508.0ms
1,518.0ms