BASIC CODE:-
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Indian Pro Racer 3D - Ultra</title>
<style>
body { margin: 0; overflow: hidden; background: #1a1a1a; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
#ui {
position: absolute; top: 20px; left: 20px; color: white;
background: rgba(0, 0, 0, 0.7); padding: 20px; border-radius: 12px;
border-left: 5px solid #ff4500; pointer-events: none;
}
.stats { font-size: 24px; font-weight: bold; color: #00ffcc; }
#speedometer { position: absolute; bottom: 30px; right: 30px; color: white; font-size: 40px; font-weight: bold; text-shadow: 2px 2px #000; }
</style>
</head>
<body>
<div id="ui">
<div style="font-size: 1.5em; margin-bottom: 10px;">🇮🇳 Indian Road Sim v2.0</div>
<p><b>W/A/S/D</b> or <b>Arrows</b> to Drive</p>
<div class="stats" id="score">Distance: 0m</div>
</div>
<div id="speedometer"><span id="speed-val">0</span> km/h</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// --- CONFIG & GLOBALS ---
let scene, camera, renderer, playerCar, clock;
let npcVehicles = [];
let environmentObjects = [];
let keys = {};
let speed = 0;
const maxSpeed = 0.8;
const accel = 0.015;
const friction = 0.97;
let distanceTravelled = 0;
init();
animate();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x87CEEB);
scene.fog = new THREE.FogExp2(0x87CEEB, 0.015);
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
clock = new THREE.Clock();
// Lighting
const ambient = new THREE.AmbientLight(0xffffff, 0.7);
scene.add(ambient);
const sun = new THREE.DirectionalLight(0xffffff, 1.0);
sun.position.set(50, 100, 50);
sun.castShadow = true;
scene.add(sun);
// Create Player Car
playerCar = createVehicle('car', 0xff0000, true);
scene.add(playerCar);
// Create Initial Ground/Road
createRoad(0);
createRoad(200);
// Event Listeners
window.addEventListener('keydown', e => keys[e.code] = true);
window.addEventListener('keyup', e => keys[e.code] = false);
window.addEventListener('resize', onWindowResize);
}
// --- MODEL CREATION FUNCTIONS ---
function createVehicle(type, color, hasDriver = false) {
const group = new THREE.Group();
// Chassis
const body = new THREE.Mesh(
new THREE.BoxGeometry(type==='truck'? 2.5 : 1.8, type==='truck'? 2 : 0.8, type==='truck'? 6 : 4),
new THREE.MeshStandardMaterial({ color: color })
);
body.position.y = type==='truck'? 1.5 : 0.6;
body.castShadow = true;
group.add(body);
// Cabin
if(type === 'car') {
const cabin = new THREE.Mesh(
new THREE.BoxGeometry(1.4, 0.7, 1.8),
new THREE.MeshStandardMaterial({ color: 0x333333, transparent: true, opacity: 0.8 })
);
cabin.position.set(0, 1.3, -0.2);
group.add(cabin);
if(hasDriver) {
const head = new THREE.Mesh(new THREE.SphereGeometry(0.2), new THREE.MeshStandardMaterial({color: 0xffdbac}));
head.position.set(0.3, 1.3, 0); // Indian driver seat (Right side)
group.add(head);
}
} else if (type === 'truck') {
const cargo = new THREE.Mesh(
new THREE.BoxGeometry(2.5, 1.5, 4),
new THREE.MeshStandardMaterial({ color: 0x2255ff }) // Blue Cargo
);
cargo.position.set(0, 1.8, -1);
group.add(cargo);
}
// Wheels
const wheelGeo = new THREE.CylinderGeometry(0.4, 0.4, 0.4, 12);
const wheelMat = new THREE.MeshStandardMaterial({ color: 0x111111 });
const wheelPos = type === 'truck' ? [1.3, -1.3, 1, -1, 2.5, -2.5] : [1, -1, 1.5, -1.5];
for(let i=0; i < wheelPos.length; i+=2) {
const w1 = new THREE.Mesh(wheelGeo, wheelMat);
w1.rotation.z = Math.PI/2;
w1.position.set(wheelPos[0], 0.4, wheelPos[i+2] || wheelPos[i+1]);
group.add(w1);
const w2 = w1.clone();
w2.position.x *= -1;
group.add(w2);
}
return group;
}
function createHouse(x, z) {
const colors = [0xffcc00, 0xff66aa, 0x00ccff, 0x88ff88];
const house = new THREE.Group();
const base = new THREE.Mesh(
new THREE.BoxGeometry(6, 5, 6),
new THREE.MeshStandardMaterial({ color: colors[Math.floor(Math.random()*colors.length)] })
);
base.position.set(x, 2.5, z);
house.add(base);
const roof = new THREE.Mesh(
new THREE.ConeGeometry(5, 3, 4),
new THREE.MeshStandardMaterial({ color: 0x882222 })
);
roof.position.set(x, 6.5, z);
roof.rotation.y = Math.PI/4;
house.add(roof);
scene.add(house);
environmentObjects.push(house);
}
function createTree(x, z) {
const tree = new THREE.Group();
const trunk = new THREE.Mesh(new THREE.CylinderGeometry(0.3, 0.3, 2), new THREE.MeshStandardMaterial({color: 0x4d2600}));
trunk.position.set(x, 1, z);
const leaves = new THREE.Mesh(new THREE.SphereGeometry(1.5), new THREE.MeshStandardMaterial({color: 0x005500}));
leaves.position.set(x, 3, z);
tree.add(trunk, leaves);
scene.add(tree);
environmentObjects.push(tree);
}
function createRoad(zPos) {
const roadGeo = new THREE.PlaneGeometry(20, 200);
const roadMat = new THREE.MeshStandardMaterial({ color: 0x333333 });
const road = new THREE.Mesh(roadGeo, roadMat);
road.rotation.x = -Math.PI / 2;
road.position.z = zPos;
road.receiveShadow = true;
scene.add(road);
// Road Lines
const lineGeo = new THREE.PlaneGeometry(0.5, 10);
const lineMat = new THREE.MeshStandardMaterial({ color: 0xffffff });
for(let i=0; i<10; i++) {
const line = new THREE.Mesh(lineGeo, lineMat);
line.rotation.x = -Math.PI/2;
line.position.set(0, 0.02, zPos + (i*20) - 90);
scene.add(line);
}
// Side Grass
const grassGeo = new THREE.PlaneGeometry(100, 200);
const grassMat = new THREE.MeshStandardMaterial({ color: 0x228B22 });
const grass = new THREE.Mesh(grassGeo, grassMat);
grass.rotation.x = -Math.PI/2;
grass.position.set(0, -0.1, zPos);
scene.add(grass);
// Add Houses and Trees on sides
for(let i=0; i<5; i++) {
createHouse(15 + Math.random()*10, zPos - 100 + (i*40));
createHouse(-15 - Math.random()*10, zPos - 100 + (i*40));
createTree(10, zPos - 80 + (i*40));
createTree(-10, zPos - 80 + (i*40));
}
}
// --- TRAFFIC ENGINE ---
function spawnTraffic() {
if(npcVehicles.length < 15) {
const types = ['car', 'truck', 'car'];
const type = types[Math.floor(Math.random()*types.length)];
const color = Math.random() * 0xffffff;
const v = createVehicle(type, color);
v.position.z = playerCar.position.z - 150 - (Math.random() * 100);
v.position.x = (Math.random() > 0.5 ? 4.5 : -4.5); // Lane logic
v.userData = { speed: 0.2 + Math.random() * 0.3 };
scene.add(v);
npcVehicles.push(v);
}
}
// --- CORE LOOP ---
function updatePhysics() {
// Player Movement
if (keys['ArrowUp'] || keys['KeyW']) speed += accel;
if (keys['ArrowDown'] || keys['KeyS']) speed -= accel;
speed *= friction;
if (speed > maxSpeed) speed = maxSpeed;
if (speed < -0.1) speed = -0.1;
if (Math.abs(speed) > 0.01) {
if (keys['ArrowLeft'] || keys['KeyA']) playerCar.rotation.y += 0.04;
if (keys['ArrowRight'] || keys['KeyD']) playerCar.rotation.y -= 0.04;
}
playerCar.translateZ(-speed);
distanceTravelled += speed;
// Camera follow
const offset = new THREE.Vector3(0, 4, 10).applyMatrix4(playerCar.matrixWorld);
camera.position.lerp(offset, 0.1);
camera.lookAt(playerCar.position.x, playerCar.position.y + 1, playerCar.position.z - 5);
// NPC Movement
npcVehicles.forEach((v, index) => {
v.position.z -= v.userData.speed;
// Cleanup
if(v.position.z > playerCar.position.z + 50) {
scene.remove(v);
npcVehicles.splice(index, 1);
}
// Collision Simple
if(playerCar.position.distanceTo(v.position) < 2.5) {
speed = -0.2; // Crash effect
}
});
// Infinite World Logic
if(Math.floor(distanceTravelled / 200) > (window.lastChunk || 0)) {
window.lastChunk = Math.floor(distanceTravelled / 200);
createRoad(playerCar.position.z - 400);
}
spawnTraffic();
// UI Updates
document.getElementById('score').innerText = `Distance: ${Math.floor(distanceTravelled)}m`;
document.getElementById('speed-val').innerText = Math.floor(speed * 250);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
updatePhysics();
renderer.render(scene, camera);
}
</script>*/
</body>
</html>