Meta Description" name="description" />
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Hill Climb Monster Bridge</title>
<style>
body { margin: 0; overflow: hidden; background: #87CEEB; font-family: 'Arial Black', sans-serif; }
#stats { position: absolute; top: 15px; left: 15px; color: white; text-shadow: 2px 2px #000; z-index: 100; font-size: 18px; }
#f-bar { width: 120px; height: 12px; background: #444; border: 2px solid #fff; margin-top: 5px; }
#f-level { width: 100%; height: 100%; background: #ff0000; }
#controls { position: absolute; bottom: 30px; width: 100%; display: flex; justify-content: space-around; z-index: 100; }
.btn { width: 90px; height: 90px; background: rgba(0,0,0,0.7); border: 4px solid #fff; border-radius: 50%; color: #fff; display: flex; justify-content: center; align-items: center; font-weight: bold; user-select: none; }
</style>
</head>
<body>
<div id="stats">
COINS: <span id="c">0</span><br>
FUEL: <div id="f-bar"><div id="f-level"></div></div>
</div>
<div id="controls">
<div class="btn" id="bBtn">BRAKE</div>
<div class="btn" id="gBtn">GAS</div>
</div>
<canvas id="game"></canvas>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Sound System
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
function playSfx(f, t, d) {
const o = audioCtx.createOscillator(); const g = audioCtx.createGain();
o.type = t; o.frequency.setValueAtTime(f, audioCtx.currentTime);
o.connect(g); g.connect(audioCtx.destination);
g.gain.setValueAtTime(0.1, audioCtx.currentTime); o.start(); o.stop(audioCtx.currentTime + d);
}
let car = { x: 150, y: 0, vY: 0, rot: 0, speed: 0, fuel: 100, coins: 0 };
let terrain = [], items = [], scrollX = 0;
let gas = false, brake = false;
// Bridge Logic
const bridgeFreq = 200; // Har 200 units baad bridge aayega
function getH(x) {
let idx = Math.floor(x/30);
let baseH = terrain[idx] || canvas.height;
// Bridge lachak (Rope Bridge Physics)
if (idx % bridgeFreq > 150 && idx % bridgeFreq < 190) {
let distInBridge = (idx % bridgeFreq) - 150;
let dip = Math.sin((distInBridge / 40) * Math.PI) * 50;
// Agar gadi bridge par hai to zyada dabe
if (Math.abs((scrollX + car.x) - x) < 50) dip += 10;
return baseH + dip;
}
return baseH;
}
// World Generation
for (let i = 0; i < 10000; i++) {
let y = (canvas.height * 0.6) + Math.sin(i * 0.05) * 120 + Math.cos(i * 0.02) * 60;
terrain.push(y);
if (i % 40 === 0) items.push({ x: i * 30, y: y - 60, type: 'coin' });
if (i % 250 === 0) items.push({ x: i * 30, y: y - 60, type: 'fuel' });
if (i % 100 === 0) items.push({ x: i * 30, y: y - 100, type: 'tree' });
}
function update() {
if (gas && car.fuel > 0) {
car.speed += 0.45; car.fuel -= 0.2;
if (Math.random() > 0.9) playSfx(80 + car.speed * 5, 'sawtooth', 0.1);
} else { car.speed *= 0.96; }
if (brake) car.speed -= 0.8;
car.speed = Math.max(-4, Math.min(car.speed, 15));
scrollX += car.speed;
let gy = getH(scrollX + car.x);
let angle = Math.atan2(getH(scrollX + car.x + 20) - gy, 20);
if (car.y < gy - 55) {
car.vY += 0.7; car.rot += 0.06;
} else {
car.vY = 0; car.y = gy - 55; car.rot = angle;
}
car.y += car.vY;
items.forEach(it => {
if (!it.hit && Math.abs((scrollX + car.x) - it.x) < 50 && Math.abs(car.y - it.y) < 70) {
it.hit = true;
if (it.type === 'coin') { car.coins += 10; playSfx(1000, 'sine', 0.1); }
if (it.type === 'fuel') { car.fuel = 100; playSfx(500, 'square', 0.2); }
}
});
document.getElementById('c').innerText = car.coins;
document.getElementById('fuel-fill').style.width = car.fuel + "%";
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Ground & Rope Bridge
ctx.fillStyle = "#8B4513"; ctx.beginPath(); ctx.moveTo(0, canvas.height);
for (let i = 0; i < canvas.width; i += 10) {
let xPos = scrollX + i;
let idx = Math.floor(xPos/30);
if (idx % bridgeFreq > 150 && idx % bridgeFreq < 190) {
ctx.strokeStyle = "#5d4037"; ctx.lineWidth = 5;
ctx.strokeRect(i, getH(xPos), 10, 5); // Bridge planks
} else {
ctx.lineTo(i, getH(xPos));
}
}
ctx.lineTo(canvas.width, canvas.height); ctx.fill();
// Grass Layer
ctx.strokeStyle = "#2ecc71"; ctx.lineWidth = 15; ctx.beginPath();
for (let i = 0; i < canvas.width; i += 15) {
let idx = Math.floor((scrollX + i)/30);
if (!(idx % bridgeFreq > 150 && idx % bridgeFreq < 190)) ctx.lineTo(i, getH(scrollX + i) - 5);
else ctx.moveTo(i, getH(scrollX + i));
}
ctx.stroke();
// Items
items.forEach(it => {
if (it.hit) return;
let sx = it.x - scrollX;
if (sx > -100 && sx < canvas.width + 100) {
if (it.type === 'tree') {
ctx.fillStyle = "#5d4037"; ctx.fillRect(sx - 10, it.y + 30, 20, 70);
ctx.fillStyle = "#1b5e20"; ctx.beginPath(); ctx.arc(sx, it.y, 40, 0, Math.PI*2); ctx.fill();
} else {
ctx.fillStyle = it.type === 'coin' ? "#FFD700" : "#ff4444";
ctx.beginPath(); ctx.arc(sx, it.y, 12, 0, Math.PI*2); ctx.fill();
}
}
});
// Monster Truck
ctx.save(); ctx.translate(car.x, car.y); ctx.rotate(car.rot);
ctx.fillStyle = "#e74c3c"; ctx.fillRect(-45, -30, 90, 40); // Body
ctx.fillStyle = "#81ecec"; ctx.fillRect(10, -25, 25, 15); // Glass
ctx.fillStyle = "yellow"; ctx.fillRect(38, -10, 10, 8); // Light
ctx.fillStyle = "#222";
ctx.beginPath(); ctx.arc(-35, 25, 25, 0, Math.PI*2); ctx.fill(); // Huge Wheels
ctx.beginPath(); ctx.arc(35, 25, 25, 0, Math.PI*2); ctx.fill();
ctx.restore();
}
const g = document.getElementById('gBtn'), b = document.getElementById('bBtn');
const press = (e) => { e.preventDefault(); gas = true; if(audioCtx.state==='suspended')audioCtx.resume(); };
g.ontouchstart = press; g.ontouchend = () => gas = false;
b.ontouchstart = (e) => { e.preventDefault(); brake = true; }; b.ontouchend = () => brake = false;
function loop() { update(); draw(); requestAnimationFrame(loop); }
loop();
</script>
</body>
</html>
1
1
8KB
8KB
190.0ms
200.0ms
190.0ms