<!doctype html>
<title>Dodge the Blocks — সোজা খেলা</title>
<style>
html,body { height:100%; margin:0; background:#0b1020; color:#fff; font-family:Segoe UI,Roboto,Helvetica,Arial; }
#gameWrap { display:flex; flex-direction:column; align-items:center; padding:12px; gap:8px; }
canvas { background: linear-gradient(#071024,#091427); border-radius:12px; box-shadow:0 6px 20px rgba(0,0,0,0.6); touch-action:none; }
.hud { display:flex; gap:12px; align-items:center; }
.btn { background:#1f6feb; padding:6px 10px; border-radius:8px; cursor:pointer; user-select:none; }
.small { font-size:13px; opacity:0.9; }
#controls { display:flex; gap:8px; margin-top:8px; }
.hint { font-size:13px; opacity:0.8; }
</style>
Dodge the Blocks
Score: 0
Level: 1
Start
Restart
<canvas id="game" width="360" height="600"></canvas>
<div id="controls">
<div class="btn" id="leftBtn">◀️</div>
<div class="btn" id="rightBtn">▶️</div>
<div class="btn" id="slowBtn">Slow</div>
</div>
<div class="hint">
Keyboard: ← → or A D. Touch: press left/right buttons. Tap canvas to pause.
</div>
<script>
// ====== Game constants ======
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
const scoreEl = document.getElementById('score');
const levelEl = document.getElementById('level');
const startBtn = document.getElementById('startBtn');
const restartBtn = document.getElementById('restartBtn');
const leftBtn = document.getElementById('leftBtn');
const rightBtn = document.getElementById('rightBtn');
const slowBtn = document.getElementById('slowBtn');
let W = canvas.width, H = canvas.height;
let running = false, paused = false;
let score = 0, level = 1;
let player, obstacles, keys, lastSpawn, spawnInterval, speedMultiplier;
function resetGame() {
score = 0; level = 1;
player = { x: W/2 - 18, y: H - 70, w: 36, h: 36, speed: 5 };
obstacles = [];
keys = { left:false, right:false };
lastSpawn = 0;
spawnInterval = 900; // ms
speedMultiplier = 1;
updateHUD();
}
function updateHUD() {
scoreEl.textContent = score;
levelEl.textContent = level;
}
// ====== Spawning obstacles ======
function spawnObstacle() {
const ow = 24 + Math.random()*50;
const ox = Math.random() * (W - ow);
const speed = 1.2 + Math.random()*1.6 + (level-1) * 0.25;
obstacles.push({ x:ox, y:-ow, w:ow, h:ow, speed });
}
// ====== Collision check ======
function collide(a,b){
return !( a.x + a.w < b.x || a.x > b.x + b.w || a.y + a.h < b.y || a.y > b.y + b.h );
}
// ====== Game loop ======
let lastTime = performance.now();
function loop(now){
const dt = now - lastTime;
lastTime = now;
if(running && !paused){
update(dt);
draw();
}
requestAnimationFrame(loop);
}
function update(dt){
// movement
if(keys.left) player.x -= player.speed * speedMultiplier;
if(keys.right) player.x += player.speed * speedMultiplier;
// bounds
if(player.x < 6) player.x = 6;
if(player.x + player.w > W-6) player.x = W - 6 - player.w;
// spawn obstacles
lastSpawn += dt;
if(lastSpawn > spawnInterval){
spawnObstacle();
lastSpawn = 0;
// speed up a bit
if(spawnInterval > 350) spawnInterval *= 0.985;
}
// update obstacles
for(let i = obstacles.length-1; i >= 0; i--){
const ob = obstacles[i];
ob.y += ob.speed * speedMultiplier;
// passed bottom -> score
if(ob.y > H){
obstacles.splice(i,1);
score += 1;
if(score % 10 === 0){ level += 1; speedMultiplier += 0.08; }
updateHUD();
} else {
if(collide(player, ob)){
// game over
running = false;
restartBtn.style.display = 'inline-block';
startBtn.style.display = 'none';
alert('Game Over! Score: ' + score);
}
}
}
}
// ====== Drawing ======
function draw(){
ctx.clearRect(0,0,W,H);
// background grid
const g = 28;
ctx.globalAlpha = 0.06;
ctx.fillStyle = "#ffffff";
for(let x=0; x {
ctx.fillStyle = '#ff7b7b';
roundRect(ctx, ob.x, ob.y, ob.w, ob.h, 6, true, false);
});
// UI overlay
ctx.fillStyle = 'rgba(0,0,0,0.12)';
ctx.fillRect(6,6,120,30);
ctx.fillStyle = '#fff';
ctx.font = '14px sans-serif';
ctx.fillText('Score: ' + score, 12, 27);
}
function roundRect(ctx, x, y, w, h, r, fill, stroke) {
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.arcTo(x + w, y, x + w, y + h, r);
ctx.arcTo(x + w, y + h, x, y + h, r);
ctx.arcTo(x, y + h, x, y, r);
ctx.arcTo(x, y, x + w, y, r);
ctx.closePath();
if(fill) ctx.fill();
if(stroke) ctx.stroke();
}
// ====== Input handlers ======
document.addEventListener('keydown', e => {
if(e.key === 'ArrowLeft' || e.key.toLowerCase() === 'a') keys.left = true;
if(e.key === 'ArrowRight' || e.key.toLowerCase() === 'd') keys.right = true;
if(e.key === ' '){ paused = !paused; }
});
document.addEventListener('keyup', e => {
if(e.key === 'ArrowLeft' || e.key.toLowerCase() === 'a') keys.left = false;
if(e.key === 'ArrowRight' || e.key.toLowerCase() === 'd') keys.right = false;
});
// touch buttons
leftBtn.addEventListener('pointerdown', ()=> keys.left = true);
leftBtn.addEventListener('pointerup', ()=> keys.left = false);
rightBtn.addEventListener('pointerdown', ()=> keys.right = true);
rightBtn.addEventListener('pointerup', ()=> keys.right = false);
slowBtn.addEventListener('click', ()=>{
speedMultiplier = Math.max(0.5, speedMultiplier - 0.25);
setTimeout(()=> speedMultiplier = Math.min(3, speedMultiplier + 0.25), 3000);
});
// tap canvas to pause / resume
canvas.addEventListener('pointerdown', () => {
if(!running) return;
paused = !paused;
});
// Start/Restart
startBtn.addEventListener('click', ()=>{
resetGame();
running = true;
paused = false;
startBtn.style.display = 'none';
restartBtn.style.display = 'none';
});
restartBtn.addEventListener('click', ()=>{
resetGame();
running = true;
paused = false;
restartBtn.style.display = 'none';
});
// resize canvas for high DPI screens
function fixDPI() {
const ratio = Math.min(window.devicePixelRatio || 1, 2);
canvas.width = Math.floor(360 * ratio);
canvas.height = Math.floor(600 * ratio);
canvas.style.width = '360px';
canvas.style.height = '600px';
ctx.setTransform(ratio,0,0,ratio,0,0);
W = canvas.width / ratio; H = canvas.height / ratio;
}
window.addEventListener('resize', fixDPI);
fixDPI();
resetGame();
requestAnimationFrame(loop);
// Touch: allow dragging player directly
let dragging = false;
canvas.addEventListener('pointerdown', (e)=>{
const rect = canvas.getBoundingClientRect();
const x = (e.clientX - rect.left);
if(x < rect.width/2) { keys.left = true; keys.right = false; }
else { keys.right = true; keys.left = false; }
dragging = true;
});
window.addEventListener('pointerup', ()=>{
keys.left = keys.right = false;
dragging = false;
});
// Small tip: double-tap to start quickly
canvas.addEventListener('dblclick', ()=>{
if(!running){
startBtn.click();
}
});
</script>