مقدمه
بازیهای HTML5 به دلیل دسترسی آسان و قابلیت اجرا در مرورگرهای مختلف، به یک پلتفرم محبوب برای توسعه بازی تبدیل شدهاند. ایجاد یک چارچوب اساسی و سازماندهی شده، اولین قدم برای ساخت یک بازی HTML5 موفق است. این مقاله به بررسی اجزای اصلی این چارچوب و نحوه پیادهسازی آنها با استفاده از نمونه کد میپردازد.
1. ساختار HTML:
هسته اصلی یک بازی HTML5، عنصر <canvas> است. این عنصر یک ناحیه مستطیلی را در صفحه وب ایجاد میکند که میتوان از طریق جاوااسکریپت برای ترسیم گرافیک، تصاویر و انیمیشنها استفاده کرد. ساختار اولیه HTML برای یک بازی HTML5 به شکل زیر است:
<!DOCTYPE html>
<html>
<head>
<title>بازی HTML5</title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<script src="game.js"></script>
</body>
</html>
در این ساختار:
<!DOCTYPE html>: نوع سندHTML5را تعریف میکند.<html>: عنصر ریشه سندHTMLاست.<head>: شامل فرادادهها مانند عنوان صفحه و استایلهایCSSاست.<title>: عنوان بازی را در نوار عنوان مرورگر تعیین میکند.<style>: شامل استایلهایCSSبرای صفحه و عنصرcanvasاست. در اینجا، حاشیه بدنه حذف شده و عنصرcanvasبه صورت یک بلوک نمایش داده میشود.<body>: شامل محتوای قابل مشاهده صفحه است.<canvas id="gameCanvas"></canvas>: عنصر اصلی برای ترسیم گرافیک بازی است. شناسهgameCanvasبرای دسترسی به این عنصر در جاوااسکریپت استفاده میشود.<script src="game.js"></script>: اسکریپت جاوااسکریپت حاوی منطق بازی را به صفحه پیوند میدهد.
2. منطق بازی با جاوااسکریپت (game.js):
اکثر منطق بازی در فایل جاوااسکریپت (game.js) پیادهسازی میشود. این شامل مدیریت ورودی، بهروزرسانی وضعیت بازی، و ترسیم عناصر روی canvas است.
2.1. دریافت زمینه نقاشی:
اولین قدم در فایل game.js، دریافت ارجاع به عنصر canvas و زمینه نقاشی دو بعدی (2D rendering context) آن است:
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
متغیر canvas به عنصر HTML canvas اشاره میکند و متغیر ctx یک شیء را در اختیار ما قرار میدهد که متدهای مختلفی برای ترسیم اشکال، متن، تصاویر و غیره روی canvas دارد.
2.2. حلقه بازی (Game Loop):
حلقه بازی یک مفهوم اساسی در توسعه بازی است. این یک حلقه بینهایت است که به طور مداوم مراحل زیر را انجام میدهد:
- پردازش ورودی: بررسی ورودی کاربر (مانند فشار دادن کلیدها یا کلیک ماوس).
- بهروزرسانی وضعیت بازی: تغییر موقعیت، سرعت، امتیاز و سایر جنبههای بازی بر اساس ورودی و قوانین بازی.
- ترسیم (
Rendering): پاک کردنcanvasو ترسیم مجدد تمام عناصر بازی در موقعیتهای جدید.
یک پیادهسازی ساده از حلقه بازی میتواند به شکل زیر باشد:
function gameLoop() {
// پردازش ورودی
update();
// بهروزرسانی وضعیت بازی
render();
// درخواست فریم بعدی انیمیشن
requestAnimationFrame(gameLoop);
}
function update() {
// منطق بهروزرسانی وضعیت بازی در اینجا قرار میگیرد
}
function render() {
// پاک کردن canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// منطق ترسیم عناصر بازی در اینجا قرار میگیرد
}
// شروع حلقه بازی
gameLoop();
تابع gameLoop به طور مکرر فراخوانی میشود. requestAnimationFrame یک روش کارآمد برای اجرای انیمیشنها در مرورگر است زیرا نرخ فریم را با نرخ تازهسازی صفحه نمایش هماهنگ میکند.
2.3. مدیریت ورودی:
برای تعامل با کاربر، باید رویدادهای ورودی مانند فشار دادن کلیدها یا کلیک ماوس را مدیریت کنیم.
2.3.1. مدیریت ورودی صفحه کلید:
const keys = {};
document.addEventListener('keydown', function(event) {
keys[event.key] = true;
});
document.addEventListener('keyup', function(event) {
keys[event.key] = false;
});
function update() {
if (keys['ArrowUp']) {
// حرکت به بالا
}
if (keys['ArrowDown']) {
// حرکت به پایین
}
if (keys['ArrowLeft']) {
// حرکت به چپ
}
if (keys['ArrowRight']) {
// حرکت به راست
}
// سایر منطقهای بهروزرسانی
}
در این مثال، یک شیء به نام keys برای نگهداری وضعیت هر کلید (فشرده شده یا خیر) استفاده میشود. رویدادهای keydown و keyup برای بهروزرسانی این شیء ثبت میشوند. در تابع update، وضعیت کلیدهای جهتدار بررسی شده و اقدامات مربوطه انجام میشود.
2.3.2. مدیریت ورودی ماوس:
canvas.addEventListener('mousedown', function(event) {
const mouseX = event.clientX - canvas.getBoundingClientRect().left;
const mouseY = event.clientY - canvas.getBoundingClientRect().top;
// انجام اقدامات بر اساس موقعیت ماوس (mouseX, mouseY)
});
رویداد mousedown برای تشخیص کلیک ماوس روی canvas ثبت میشود. event.clientX و event.clientY مختصات ماوس در پنجره مرورگر را ارائه میدهند. برای به دست آوردن مختصات ماوس نسبت به canvas، موقعیت canvas با استفاده از getBoundingClientRect() کم میشود.
2.4. ترسیم (Rendering):
تابع render مسئول پاک کردن canvas و ترسیم تمام عناصر بازی است.
2.4.1. ترسیم یک مستطیل:
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 100, 100); // x, y, width, height
}
این کد یک مستطیل آبی رنگ با عرض و ارتفاع 100 پیکسل در موقعیت (50, 50) روی canvas ترسیم میکند.
2.4.2. ترسیم یک دایره:
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'green';
ctx.beginPath();
ctx.arc(200, 200, 50, 0, Math.PI * 2); // x, y, radius, startAngle, endAngle
ctx.fill();
}
این کد یک دایره سبز رنگ با شعاع 50 پیکسل در موقعیت (200, 200) ترسیم میکند.
2.4.3. ترسیم متن:
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'black';
ctx.font = '20px Arial';
ctx.fillText('سلام دنیا!', 10, 30); // text, x, y
}
این کد متن “سلام دنیا!” را با فونت Arial به اندازه 20 پیکسل در موقعیت (10, 30) ترسیم میکند.
3. مدیریت وضعیت بازی:
در بازیهای پیچیدهتر، مدیریت وضعیتهای مختلف بازی (مانند صفحه شروع، صفحه بازی، صفحه پایان) ضروری است. میتوان از یک متغیر برای پیگیری وضعیت فعلی بازی استفاده کرد:
let gameState = 'loading'; // یا 'playing', 'gameOver'
function gameLoop() {
// ...
if (gameState === 'loading') {
// نمایش صفحه بارگیری
} else if (gameState === 'playing') {
update();
render();
} else if (gameState === 'gameOver') {
// نمایش صفحه پایان بازی
}
requestAnimationFrame(gameLoop);
}
4. مثال ساده: حرکت یک مستطیل با کلیدهای جهتدار:
در اینجا یک مثال کامل از یک بازی بسیار ساده وجود دارد که در آن یک مستطیل با استفاده از کلیدهای جهتدار حرکت میکند:
game.js:
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
canvas.width = 400;
canvas.height = 300;
const player = {
x: canvas.width / 2 - 25,
y: canvas.height / 2 - 25,
width: 50,
height: 50,
speed: 5
};
const keys = {};
document.addEventListener('keydown', function(event) {
keys[event.key] = true;
});
document.addEventListener('keyup', function(event) {
keys[event.key] = false;
});
function update() {
if (keys['ArrowUp']) {
player.y -= player.speed;
}
if (keys['ArrowDown']) {
player.y += player.speed;
}
if (keys['ArrowLeft']) {
player.x -= player.speed;
}
if (keys['ArrowRight']) {
player.x += player.speed;
}
// جلوگیری از خروج مستطیل از مرزهای canvas
if (player.x < 0) player.x = 0;
if (player.y < 0) player.y = 0;
if (player.x + player.width > canvas.width) player.x = canvas.width - player.width;
if (player.y + player.height > canvas.height) player.y = canvas.height - player.height;
}
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'red';
ctx.fillRect(player.x, player.y, player.width, player.height);
}
function gameLoop() {
update();
render();
requestAnimationFrame(gameLoop);
}
gameLoop();
در این مثال:
- اندازه
canvasتعیین شده است. - یک شیء
playerبرای نگهداری اطلاعات مربوط به مستطیل (موقعیت، اندازه، سرعت) ایجاد شده است. - در تابع
update، موقعیتplayerبر اساس کلیدهای جهتدار فشرده شده بهروزرسانی میشود. - در تابع
render،canvasپاک شده و مستطیل در موقعیت فعلی خود ترسیم میشود.
نتیجهگیری:
این مقاله یک چارچوب اساسی برای توسعه بازیهای HTML5 را با استفاده از عنصر <canvas> و جاوااسکریپت ارائه داد. درک این مفاهیم اساسی مانند ساختار HTML، حلقه بازی، مدیریت ورودی و ترسیم، گام مهمی در ساخت بازیهای HTML5 پیچیدهتر و جذابتر است. با گسترش این چارچوب و افزودن مفاهیم پیشرفتهتر مانند مدیریت داراییها، تشخیص برخورد، و صدا، میتوان بازیهای HTML5 کاملی ایجاد کرد.
