Meta Description" name="description" />
<!DOCTYPE html>
<html lang="bn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>সোমেন আলটিমেট ফুল-স্ক্রিন ৩ডি রেসার</title>
<style>
* {
box-sizing: border-box;
user-select: none;
-webkit-user-select: none;
}
body, html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: #0b2e13;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
#gameCanvas {
width: 100%;
height: 100%;
display: block;
}
.ui-screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(11, 46, 19, 0.9);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 10;
}
.menu-title {
font-size: 3rem;
color: #00ff66;
margin-bottom: 5px;
font-weight: bold;
text-shadow: 0 0 20px rgba(0,255,102,0.6);
}
.menu-subtitle {
font-size: 1.2rem;
color: #fff;
margin-bottom: 30px;
}
.mode-container {
display: flex;
flex-direction: column;
gap: 15px;
width: 80%;
max-width: 300px;
}
.mode-btn {
padding: 15px;
font-size: 18px;
font-weight: bold;
border: 2px solid #00ff66;
border-radius: 30px;
background: rgba(0, 255, 102, 0.1);
color: #00ff66;
cursor: pointer;
box-shadow: 0 0 15px rgba(0, 255, 102, 0.3);
transition: 0.2s;
text-align: center;
}
.mode-btn:active {
background: #00ff66;
color: #000;
box-shadow: 0 0 25px #00ff66;
}
.game-controls {
position: absolute;
bottom: 30px;
left: 0;
width: 100%;
display: flex;
justify-content: space-between;
padding: 0 40px;
pointer-events: none;
}
.ctrl-btn {
width: 90px;
height: 90px;
background: rgba(0, 255, 102, 0.2);
border: 3px solid #00ff66;
border-radius: 50%;
color: #00ff66;
font-size: 40px;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 0 20px rgba(0, 255, 102, 0.4);
pointer-events: auto;
touch-action: manipulation;
}
.ctrl-btn:active {
background: #00ff66;
color: #000;
}
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<!-- স্টার্ট মেনু -->
<div id="mainMenu" class="ui-screen">
<div class="menu-title">SOUMEN RACER</div>
<div class="menu-subtitle">মোড সিলেক্ট করে রেস শুরু করো ভাই!</div>
<div class="mode-container">
<div class="mode-btn" onclick="selectMode('solo')">👤 SOLO MODE (More Slow 🐢)</div>
<div class="mode-btn" onclick="selectMode('medium')">⚡ MEDIUM MODE (Fast)</div>
<div class="mode-btn" onclick="selectMode('fast')">🔥 FAST MODE (Insane)</div>
</div>
</div>
<!-- গেম ওভার স্ক্রিন -->
<div id="gameOverScreen" class="ui-screen" style="display: none;">
<div class="menu-title" style="color: #ff1744; text-shadow: 0 0 20px rgba(255,23,68,0.6);">ক্র্যাশ! গেম ওভার</div>
<div id="finalScore" class="menu-subtitle" style="font-size: 1.5rem;"></div>
<div class="mode-container">
<div class="mode-btn" style="border-color: #ffcc00; color: #ffcc00;" onclick="showMenu()">🔄 মেনুতে ফিরে যান</div>
</div>
</div>
<!-- অন-স্ক্রিন গেমপ্যাড -->
<div class="game-controls">
<div class="ctrl-btn" id="leftBtn">←</div>
<div class="ctrl-btn" id="rightBtn">→</div>
</div>
<script>
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
const mainMenu = document.getElementById("mainMenu");
const gameOverScreen = document.getElementById("gameOverScreen");
const finalScoreText = document.getElementById("finalScore");
const leftBtn = document.getElementById("leftBtn");
const rightBtn = document.getElementById("rightBtn");
let bikeX, bikeSpeed, score, gameState, obstacles, gameTick, baseSpeed, speedMultiplier;
let currentMode = 'solo';
const horizonY = 220;
let bikeY;
let isLeftPressed = false;
let isRightPressed = false;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
bikeY = canvas.height - 120;
if(gameState === 'PLAYING') bikeX = canvas.width / 2;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
leftBtn.addEventListener("touchstart", (e) => { e.preventDefault(); isLeftPressed = true; });
leftBtn.addEventListener("touchend", () => isLeftPressed = false);
rightBtn.addEventListener("touchstart", (e) => { e.preventDefault(); isRightPressed = true; });
rightBtn.addEventListener("touchend", () => isRightPressed = false);
function showMenu() {
gameOverScreen.style.display = "none";
mainMenu.style.display = "flex";
gameState = 'WELCOME';
}
function selectMode(mode) {
currentMode = mode;
mainMenu.style.display = "none";
gameOverScreen.style.display = "none";
// Solo মোডের গতি ৪ করা হলো (আগে ৬ ছিল), যা গেমপ্লে আরও স্লো এবং সহজ করবে
if (mode === 'solo') baseSpeed = 4;
else if (mode === 'medium') baseSpeed = 10;
else if (mode === 'fast') baseSpeed = 15;
initGame();
gameState = 'PLAYING';
}
function initGame() {
bikeX = canvas.width / 2;
bikeSpeed = 0;
score = 0;
obstacles = [];
gameTick = 0;
speedMultiplier = 1;
}
// থ্রিডি টেক্সট (SOUMEN) ড্রয়িং ফাংশন
function draw3DText(text, x, y, size) {
ctx.save();
ctx.font = "bold " + size + "px Impact, Arial Black, sans-serif";
ctx.textAlign = "center";
// ৩ডি লেয়ারিং এফেক্ট (পেছন থেকে সামনে একাধিক স্তর তৈরি করা)
let depth = 12;
for (let i = 0; i < depth; i++) {
ctx.fillStyle = "rgba(0, 100, 40, " + (0.05 + (i / depth) * 0.1) + ")";
ctx.fillText(text, x - depth + i, y + depth - i);
}
// মূল সামনের উজ্জ্বল স্তর
ctx.shadowBlur = 20;
ctx.shadowColor = "#00ff66";
ctx.fillStyle = "rgba(255, 255, 255, 0.25)";
ctx.fillText(text, x, y);
ctx.restore();
}
function draw3DScene() {
gameTick++;
// আকাশ ও পাহাড়
let skyGrad = ctx.createLinearGradient(0, 0, 0, horizonY);
skyGrad.addColorStop(0, "#00d4ff");
skyGrad.addColorStop(1, "#090979");
ctx.fillStyle = skyGrad;
ctx.fillRect(0, 0, canvas.width, horizonY);
ctx.fillStyle = "#101052";
ctx.beginPath();
ctx.moveTo(0, horizonY);
ctx.lineTo(canvas.width * 0.25, horizonY - 60);
ctx.lineTo(canvas.width * 0.5, horizonY);
ctx.lineTo(canvas.width * 0.75, horizonY - 40);
ctx.lineTo(canvas.width, horizonY);
ctx.fill();
// ঘাস ও ফুল
let speedOffset = Math.floor(gameTick * (baseSpeed * 0.05)) % 2;
for (let y = horizonY; y < canvas.height; y += 8) {
let isLight = (Math.floor(y / 8) % 2 === speedOffset);
ctx.fillStyle = isLight ? "#2e7d32" : "#1b5e20";
ctx.fillRect(0, y, canvas.width, 8);
let percent = (y - horizonY) / (canvas.height - horizonY);
if (Math.sin(y + gameTick * 0.08) > 0.75) {
ctx.fillStyle = (Math.floor(y) % 2 === 0) ? "#ffeb3b" : "#ff4081";
ctx.beginPath();
ctx.arc(30 + percent * (canvas.width * 0.2) + (y % 40), y + 4, 3 + percent * 5, 0, Math.PI * 2);
ctx.arc(canvas.width - 30 - percent * (canvas.width * 0.2) - (y % 40), y + 4, 3 + percent * 5, 0, Math.PI * 2);
ctx.fill();
}
}
// ব্যাকগ্রাউন্ডে থ্রিডি "SOUMEN" নাম এক্সিকিউশন
let textSize = canvas.width * 0.13;
draw3DText("SOUMEN", canvas.width / 2, horizonY + 35, textSize);
// ৩ডি চওড়া হাইওয়ে রুট
ctx.fillStyle = "#37474f";
ctx.beginPath();
ctx.moveTo(canvas.width / 2 - 30, horizonY);
ctx.lineTo(canvas.width / 2 + 30, horizonY);
ctx.lineTo(canvas.width / 2 + (canvas.width * 0.42), canvas.height);
ctx.lineTo(canvas.width / 2 - (canvas.width * 0.42), canvas.height);
ctx.closePath();
ctx.fill();
// হোয়াইট ডিভাইডার লাইন
ctx.strokeStyle = "#ffffff";
for (let y = horizonY; y < canvas.height; y += 15) {
if ((Math.floor(y / 15) % 2 === speedOffset)) {
let percent = (y - horizonY) / (canvas.height - horizonY);
ctx.lineWidth = 1 + percent * 10;
ctx.beginPath();
ctx.moveTo(canvas.width / 2, y);
ctx.lineTo(canvas.width / 2, y + 12);
ctx.stroke();
}
}
// লাল-সাদা বর্ডার (Kerbs)
for (let y = horizonY; y < canvas.height; y += 6) {
let percent = (y - horizonY) / (canvas.height - horizonY);
let roadWidth = 60 + percent * (canvas.width * 0.84);
let leftX = (canvas.width / 2) - (roadWidth / 2);
let rightX = (canvas.width / 2) + (roadWidth / 2);
let kerbWidth = 4 + percent * 25;
ctx.fillStyle = (Math.floor(y / 6) % 2 === speedOffset) ? "#ffffff" : "#d32f2f";
ctx.fillRect(leftX - kerbWidth, y, kerbWidth, 6);
ctx.fillRect(rightX, y, kerbWidth, 6);
}
}
// প্লেয়ারের স্পোর্টস বাইক
function drawPlayerBike(x, y) {
ctx.save();
ctx.shadowBlur = 20;
ctx.shadowColor = "#00ff66";
ctx.fillStyle = "#111";
ctx.fillRect(x - 16, y + 15, 32, 40);
ctx.fillStyle = "#00ff66";
ctx.fillRect(x - 3, y + 20, 6, 30);
ctx.fillStyle = "#1a1a1a";
ctx.strokeStyle = "#00ff66";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(x - 24, y + 15);
ctx.lineTo(x - 14, y - 25);
ctx.lineTo(x + 14, y - 25);
ctx.lineTo(x + 24, y + 15);
ctx.closePath();
ctx.fill(); ctx.stroke();
ctx.fillStyle = "#00ff66";
ctx.beginPath();
ctx.moveTo(x - 16, y - 10);
ctx.lineTo(x, y - 35);
ctx.lineTo(x + 16, y - 10);
ctx.closePath();
ctx.fill();
ctx.fillStyle = "#ff1744";
ctx.fillRect(x - 10, y - 40, 20, 7);
ctx.fillStyle = "#00ff66";
ctx.fillRect(x - 36, y - 45, 12, 5);
ctx.fillRect(x + 24, y - 45, 12, 5);
ctx.restore();
}
function drawObstacles() {
let currentSpeed = baseSpeed * speedMultiplier;
for (let i = obstacles.length - 1; i >= 0; i--) {
let obs = obstacles[i];
obs.z -= 0.0015 * currentSpeed;
if (obs.z <= 0) {
obstacles.splice(i, 1);
score += 10;
if (score % 70 === 0) speedMultiplier += 0.08; // স্পিড বাড়ার হারও সামান্য কমানো হলো
continue;
}
let percent = 1 - obs.z;
if (percent < 0) percent = 0;
let targetY = horizonY + percent * (canvas.height - horizonY);
let roadWidth = 60 + percent * (canvas.width * 0.84);
let targetX = (canvas.width / 2) + (obs.trackOffset * roadWidth);
let obsWidth = 15 + percent * 110;
let obsHeight = 10 + percent * 65;
ctx.save();
ctx.shadowBlur = 15;
ctx.shadowColor = "#ff3d00";
ctx.fillStyle = "#3e2723";
ctx.strokeStyle = "#ff3d00";
ctx.lineWidth = 2.5;
ctx.fillRect(targetX - obsWidth / 2, targetY - obsHeight, obsWidth, obsHeight);
ctx.fillStyle = "#ff3d00";
ctx.fillRect(targetX - obsWidth / 2 + 5, targetY - obsHeight + 8, obsWidth * 0.2, 6);
ctx.fillRect(targetX + obsWidth / 2 - obsWidth * 0.2 - 5, targetY - obsHeight + 8, obsWidth * 0.2, 6);
ctx.restore();
if (percent > 0.84 && percent < 0.98) {
let bikeLeft = bikeX - 30;
let bikeRight = bikeX + 30;
let obsLeft = targetX - obsWidth / 2;
let obsRight = targetX + obsWidth / 2;
if (bikeRight > obsLeft && bikeLeft < obsRight) {
gameState = 'GAMEOVER';
finalScoreText.innerText = "সোমেন, আপনার ফাইনাল স্কোর: " + score;
gameOverScreen.style.display = "flex";
}
}
}
}
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (gameState === 'WELCOME') {
draw3DScene();
}
else if (gameState === 'PLAYING') {
draw3DScene();
if (isLeftPressed) bikeSpeed = -8;
else if (isRightPressed) bikeSpeed = 8;
else bikeSpeed = 0;
bikeX += bikeSpeed;
let maxTrackBound = canvas.width * 0.38;
if (bikeX < canvas.width / 2 - maxTrackBound) bikeX = canvas.width / 2 - maxTrackBound;
if (bikeX > canvas.width / 2 + maxTrackBound) bikeX = canvas.width / 2 + maxTrackBound;
// স্লো মোডে গাড়ি আসার ফ্রিকোয়েন্সি ব্যালেন্স করার লজিক
let spawnInterval = currentMode === 'solo' ? 55 : 40;
if (gameTick % spawnInterval === 0) {
let offset = (Math.random() * 0.74) - 0.37;
obstacles.push({ z: 1.0, trackOffset: offset });
}
drawObstacles();
drawPlayerBike(bikeX, bikeY);
ctx.fillStyle = "#ffffff";
ctx.font = "bold 20px sans-serif";
ctx.textAlign = "left";
ctx.fillText("👤 রেসার: সোমেন", 30, 45);
ctx.fillText("🏆 স্কোর: " + score, 30, 80);
let displayModeName = currentMode.toUpperCase();
ctx.fillText("🎮 মোড: " + displayModeName, 30, 115);
ctx.textAlign = "right";
ctx.fillText("⚡ গতি: " + Math.floor(baseSpeed * speedMultiplier * 18) + " KM/H", canvas.width - 30, 45);
}
requestAnimationFrame(gameLoop);
}
showMenu();
gameLoop();
</script>
</body>
</html>
1
1
16KB
16KB
491.0ms
584.0ms
491.0ms