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>
body {
margin: 0;
background: #0a1f0a;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
color: white;
font-family: sans-serif;
flex-direction: column;
overflow: hidden;
touch-action: manipulation;
}
.game-container {
position: relative;
width: 95vw;
max-width: 600px;
}
canvas {
background: #113311;
border: 4px solid #00ff66;
border-radius: 15px;
box-shadow: 0 0 35px rgba(0, 255, 102, 0.4);
display: block;
width: 100%;
height: auto;
aspect-ratio: 16 / 9;
}
.btn-ui {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 15px 40px;
font-size: 22px;
font-weight: bold;
background: linear-gradient(45deg, #00ff66, #00ffff);
color: #000;
border: none;
border-radius: 30px;
cursor: pointer;
box-shadow: 0 0 25px rgba(0, 255, 102, 0.7);
z-index: 10;
}
.controls {
display: flex;
justify-content: space-around;
width: 100%;
max-width: 400px;
margin-top: 20px;
}
.btn {
width: 80px;
height: 80px;
background: rgba(0, 255, 102, 0.1);
border: 3px solid #00ff66;
border-radius: 50%;
color: #00ff66;
font-size: 38px;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 0 15px rgba(0, 255, 102, 0.3);
user-select: none;
touch-action: manipulation;
}
.btn:active {
background: #00ff66;
color: #000;
box-shadow: 0 0 30px rgba(0, 255, 102, 0.9);
}
</style>
</head>
<body>
<div class="game-container">
<canvas id="gameCanvas" width="800" height="450"></canvas>
<button id="startBtn" class="btn-ui" onclick="startGame()">রেস শুরু করুন 🏁</button>
<button id="restartBtn" class="btn-ui" style="display:none;" onclick="resetGame()">আবার খেলুন 🔄</button>
</div>
<div class="controls">
<div class="btn" id="leftBtn">←</div>
<div class="btn" id="rightBtn">→</div>
</div>
<script>
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
const startBtn = document.getElementById("startBtn");
const restartBtn = document.getElementById("restartBtn");
const leftBtn = document.getElementById("leftBtn");
const rightBtn = document.getElementById("rightBtn");
let bikeX, bikeSpeed, score, gameState, obstacles, gameTick, speedMultiplier;
let roadSegments = [];
const bikeY = 360; // ৩ডি পার্সপেক্টিভে বাইক থাকবে নিচের দিকে
let isLeftPressed = false;
let isRightPressed = false;
gameState = 'WELCOME';
// টাচ কন্ট্রোল (বাঁয়ে এবং ডানে যাওয়ার জন্য)
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 init() {
bikeX = canvas.width / 2;
bikeSpeed = 0;
score = 0;
obstacles = [];
gameTick = 0;
speedMultiplier = 1;
}
function startGame() {
startBtn.style.display = "none";
gameState = 'PLAYING';
init();
}
function resetGame() {
restartBtn.style.display = "none";
gameState = 'PLAYING';
init();
}
// ৩ডি পার্সপেক্টিভ ট্র্যাক এবং ঘাসের টেক্সচার আঁকার ফাংশন
function draw3DScene() {
gameTick++;
// ১. আকাশ ও দিগন্ত (Sky & Horizon)
let skyGrad = ctx.createLinearGradient(0, 0, 0, 180);
skyGrad.addColorStop(0, "#051205");
skyGrad.addColorStop(1, "#113311");
ctx.fillStyle = skyGrad;
ctx.fillRect(0, 0, canvas.width, 180);
// ২. ঘাসযুক্ত জমি (3D Pseudo Grass Texturing)
// গতির সাথে ঘাসের রঙের স্ট্রিপগুলো পরিবর্তন হবে
let grassToggle = Math.floor(gameTick * 0.2) % 2;
for (let y = 180; y < canvas.height; y += 10) {
let isLight = (Math.floor(y / 10) % 2 === grassToggle);
ctx.fillStyle = isLight ? "#1a4d1a" : "#143d14";
ctx.fillRect(0, y, canvas.width, 10);
}
// ৩. ব্যাকগ্রাউন্ডে বিশাল বড় করে "SOUMEN" নাম (Horizon Text Effect)
ctx.save();
ctx.textAlign = "center";
ctx.shadowBlur = 25;
ctx.shadowColor = "#00ff66";
ctx.fillStyle = "rgba(0, 255, 102, 0.15)";
ctx.font = "bold 110px Impact, Arial Black, sans-serif";
ctx.fillText("SOUMEN", canvas.width / 2, 160);
ctx.restore();
// ৪. ৩ডি প্রজেকশন রোড (Perspective Road)
// রাস্তাটি দিগন্ত (Horizon) থেকে শুরু হয়ে সামনের দিকে চওড়া হবে
ctx.fillStyle = "#2b2b2b"; // পিচ রাস্তা
ctx.beginPath();
ctx.moveTo(canvas.width / 2 - 40, 180); // দিগন্তে সরু রাস্তা
ctx.lineTo(canvas.width / 2 + 40, 180);
ctx.lineTo(canvas.width / 2 + 250, canvas.height); // সামনে চওড়া রাস্তা
ctx.lineTo(canvas.width / 2 - 250, canvas.height);
ctx.closePath();
ctx.fill();
// রাস্তার পাশের ৩ডি লাল-সাদা কার্ব/বর্ডার (Kerbs)
let kerbToggle = Math.floor(gameTick * 0.4) % 2;
for (let y = 180; y < canvas.height; y += 8) {
let percent = (y - 180) / (canvas.height - 180);
let roadWidth = 80 + percent * 420;
let leftX = (canvas.width / 2) - (roadWidth / 2);
let rightX = (canvas.width / 2) + (roadWidth / 2);
let kerbWidth = 5 + percent * 20;
ctx.fillStyle = (Math.floor(y / 8) % 2 === kerbToggle) ? "#ffffff" : "#ff0000";
// বামের বর্ডার
ctx.fillRect(leftX - kerbWidth, y, kerbWidth, 8);
// ডানের বর্ডার
ctx.fillRect(rightX, y, kerbWidth, 8);
}
}
// ৩ডি স্পোর্টস বাইকের পিছনের ভিউ (Player Rear View)
function drawPlayerBike(x, y) {
ctx.save();
ctx.shadowBlur = 15;
ctx.shadowColor = "#00ff66";
// পিছনের চাকা (চওড়া রেসিং টায়ার)
ctx.fillStyle = "#111";
ctx.fillRect(x - 12, y + 15, 24, 30);
// রিম অ্যালয় লাইট
ctx.fillStyle = "#00ff66";
ctx.fillRect(x - 2, y + 20, 4, 20);
// বাইকের মূল বডি ও চ্যাসিস (স্পোর্টস রেসার টেল)
ctx.fillStyle = "#0d0d0d";
ctx.strokeStyle = "#00ff66";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(x - 18, y + 15);
ctx.lineTo(x - 10, y - 15); // সিটের উঁচু অংশ
ctx.lineTo(x + 10, y - 15);
ctx.lineTo(x + 18, y + 15);
ctx.closePath();
ctx.fill(); ctx.stroke();
// সায়ান/সবুজ বডি প্যানেল ও নিয়ন লাইট
ctx.fillStyle = "#00ff66";
ctx.beginPath();
ctx.moveTo(x - 12, y - 5);
ctx.lineTo(x, y - 25); // টেল লাইটের দিকে
ctx.lineTo(x + 12, y - 5);
ctx.closePath();
ctx.fill();
// রিয়ার ইন্ডিকেটর এবং লাল ব্রেক লাইট
ctx.fillStyle = "#ff0033";
ctx.fillRect(x - 8, y - 28, 16, 5);
// সাইড মিরর (লুকিং গ্লাস)
ctx.fillStyle = "#00ff66";
ctx.fillRect(x - 28, y - 35, 8, 4);
ctx.fillRect(x + 20, y - 35, 8, 4);
ctx.restore();
}
// ৩ডি ট্র্যাকে সামনের বাধা/শত্রু গাড়ি আঁকার লজিক
function drawObstacles() {
for (let i = obstacles.length - 1; i >= 0; i--) {
let obs = obstacles[i];
obs.z -= 0.015 * speedMultiplier; // সামনে এগিয়ে আসার হার
// যখন বাধাটি একদম সামনে চলে আসবে (z কমবে মানে কাছে আসবে)
if (obs.z <= 0) {
obstacles.splice(i, 1);
score += 10;
if (score % 50 === 0) speedMultiplier += 0.2;
continue;
}
// ৩ডি প্রজেকশন ক্যালকুলেশন
let percent = 1 - obs.z; // ০ থেকে ১ এর মধ্যে (দিগন্ত থেকে সামনে)
if (percent < 0) percent = 0;
let targetY = 180 + percent * (canvas.height - 180);
let roadWidth = 80 + percent * 420;
// বাধার X পজিশন রাস্তার চওড়ার উপর ভিত্তি করে নির্ধারিত হবে
let targetX = (canvas.width / 2) + (obs.trackOffset * roadWidth);
// দূরত্বের ওপর ভিত্তি করে বাধার সাইজ বা স্কেল বড় হবে
let obsWidth = 15 + percent * 85;
let obsHeight = 10 + percent * 50;
// শত্রু গাড়ির ৩ডি ডিজাইন (পিছন থেকে ভিউ)
ctx.save();
ctx.shadowBlur = 10;
ctx.shadowColor = "#ff0055";
ctx.fillStyle = "#20000a";
ctx.strokeStyle = "#ff0055";
ctx.lineWidth = 2;
ctx.fillRect(targetX - obsWidth / 2, targetY - obsHeight, obsWidth, obsHeight);
// শত্রু গাড়ির লাল টেইল লাইট
ctx.fillStyle = "#ff0055";
ctx.fillRect(targetX - obsWidth / 2 + 4, targetY - obsHeight + 5, obsWidth * 0.2, 4);
ctx.fillRect(targetX + obsWidth / 2 - obsWidth * 0.2 - 4, targetY - obsHeight + 5, obsWidth * 0.2, 4);
ctx.restore();
// কলিশন (সংঘর্ষ) চেক - যখন বাধাটি প্লেয়ারের ঠিক কাছাকাছি আসবে
if (percent > 0.82 && percent < 0.98) {
let bikeLeft = bikeX - 25;
let bikeRight = bikeX + 25;
let obsLeft = targetX - obsWidth / 2;
let obsRight = targetX + obsWidth / 2;
if (bikeRight > obsLeft && bikeLeft < obsRight) {
gameState = 'GAMEOVER';
restartBtn.style.display = "block";
}
}
}
}
// মেইন গেম লুপ
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (gameState === 'WELCOME') {
draw3DScene();
ctx.textAlign = "center";
ctx.fillStyle = "#ffffff";
ctx.font = "bold 22px sans-serif";
ctx.fillText("সোমেন রেসিং গেম সংস্করণে স্বাগতম", canvas.width / 2, canvas.height / 2 + 30);
}
else if (gameState === 'PLAYING') {
// ৩ডি ঘাস এবং রাস্তা ড্র করা
draw3DScene();
// প্লেয়ার মুভমেন্ট হ্যান্ডেল (বাঁয়ে/ডানে)
if (isLeftPressed) bikeSpeed = -6;
else if (isRightPressed) bikeSpeed = 6;
else bikeSpeed = 0;
bikeX += bikeSpeed;
// ট্র্যাকের ভেতরে বাইক সীমাবদ্ধ রাখা
if (bikeX < canvas.width / 2 - 210) bikeX = canvas.width / 2 - 210;
if (bikeX > canvas.width / 2 + 210) bikeX = canvas.width / 2 + 210;
// বাধা তৈরির লজিক (Spawn Obstacles at Horizon)
if (gameTick % 50 === 0) {
// trackOffset: -0.35 থেকে 0.35 এর মধ্যে (রাস্তার বাম, ডান বা মাঝখান)
let offset = (Math.random() * 0.7) - 0.35;
obstacles.push({ z: 1.0, trackOffset: offset });
}
// বাধা আঁকা এবং আপডেট করা
drawObstacles();
// ৩ডি স্পোর্টস বাইক আঁকা
drawPlayerBike(bikeX, bikeY);
// গেম ড্যাশবোর্ড UI
ctx.fillStyle = "#ffffff";
ctx.font = "bold 18px sans-serif";
ctx.textAlign = "left";
ctx.fillText("রেসার: সোমেন", 20, 35);
ctx.fillText("স্কোর: " + score, 20, 65);
ctx.fillText("গতি: " + Math.floor(speedMultiplier * 140) + " KM/H", canvas.width - 160, 35);
}
else if (gameState === 'GAMEOVER') {
ctx.fillStyle = "rgba(0, 0, 0, 0.85)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.textAlign = "center";
ctx.fillStyle = "#ff3333";
ctx.font = "bold 45px sans-serif";
ctx.fillText("ক্র্যাশ! গেম ওভার", canvas.width / 2, canvas.height / 2 - 20);
ctx.fillStyle = "#ffffff";
ctx.font = "20px sans-serif";
ctx.fillText("সোমেন, আপনার মোট স্কোর: " + score, canvas.width / 2, canvas.height / 2 + 25);
}
requestAnimationFrame(gameLoop);
}
gameLoop();
</script>
</body>
</html>
1
1
15KB
15KB
181.0ms
208.0ms
182.0ms