آموزش ساخت بازی آنلاین مین‌روب

ساخت بازی آنلاین، دانش آموز برنامه نویس، برنامه نویسی، بازی سازی 1404/3/20
نویسنده: مدرس بهمن آبادی

آموزش ساخت بازی آنلاین مین‌روب با HTML، CSS، JavaScript، GSAP و .NET

آموزش ساخت بازی آنلاین مین‌روب

در این مقاله، یک بازی آنلاین مین‌روب می‌سازیم که بازیکنان باید خانه‌هایی را باز کنند و از برخورد با بمب‌ها اجتناب کنند. رابط کاربری با HTML، CSS و JavaScript ساخته می‌شود، انیمیشن‌ها با GSAP اضافه می‌شوند، و بک‌اند با C# و .NET برای ذخیره امتیازات و مدیریت حالت چندنفره استفاده می‌شود.

قدم اول: طراحی رابط کاربری با HTML و CSS

HTML (ساختار صفحه)

صفحه شامل یک شبکه ۸×۸ برای بازی، دکمه شروع مجدد، و نمایشگر امتیازات است.

<!DOCTYPE html>
<html lang="fa">
<head>
  <meta charset="UTF-8">
  <title>بازی مین‌روب آنلاین</title>
  <link rel="stylesheet" href="styles.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
</head>
<body>
  <div class="container">
    <h1 class="title">بازی مین‌روب</h1>
    <p class="subtitle">از بمب‌ها دوری کنید و امتیاز بگیرید!</p>
    <button class="restart-btn" onclick="restartGame()">شروع مجدد</button>
    <div id="gameBoard" class="board"></div>
    <p id="result" class="result"></p>
    <p id="leaderboard">امتیازات: <span id="scores"></span></p>
  </div>
  <script src="script.js"></script>
</body>
</html>

CSS (زیباسازی و آماده‌سازی برای انیمیشن)

کدها رو با همین ترتیب کپی کنید و در برنامه قرار دهید.

body {
  font-family: Arial, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
  background-color: #e0f7fa;
}

.container {
  text-align: center;
  background-color: white;
  padding: 20px;
  border-radius: 15px;
  box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
}

.title {
  color: #007bff;
  opacity: 0;
}

.subtitle {
  color: #555;
  opacity: 0;
}

.restart-btn {
  padding: 10px 20px;
  background-color: #28a745;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  opacity: 0;
}

.restart-btn:hover {
  background-color: #218838;
}

.board {
  display: grid;
  grid-template-columns: repeat(8, 40px);
  gap: 2px;
  margin: 20px auto;
  opacity: 0;
}

.cell {
  width: 40px;
  height: 40px;
  background-color: #ddd;
  border: 1px solid #999;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  cursor: pointer;
  user-select: none;
}

.cell.open {
  background-color: #f0f0f0;
}

.cell.bomb {
  background-color: #d32f2f;
}

.cell.safe {
  background-color: #2ecc71;
}

.result {
  font-size: 18px;
  color: #d32f2f;
  opacity: 0;
}

#leaderboard {
  margin-top: 20px;
  opacity: 0;
}

 

قدم دوم: منطق بازی و انیمیشن‌ها با JavaScript و GSAP

JavaScript (منطق مین‌روب و انیمیشن‌ها)

const boardSize = 8;
const bombCount = 10;
let board = [];
let gameOver = false;

function initGame() {
  board = [];
  gameOver = false;
  document.getElementById('result').textContent = '';
  document.getElementById('gameBoard').innerHTML = '';

  // ایجاد شبکه
  for (let i = 0; i < boardSize; i++) {
    board[i] = [];
    for (let j = 0; j < boardSize; j++) {
      board[i][j] = { bomb: false, open: false, count: 0 };
      const cell = document.createElement('div');
      cell.classList.add('cell');
      cell.dataset.row = i;
      cell.dataset.col = j;
      cell.addEventListener('click', handleCellClick);
      document.getElementById('gameBoard').appendChild(cell);
    }
  }

  // قرار دادن بمب‌ها
  let bombsPlaced = 0;
  while (bombsPlaced < bombCount) {
    const row = Math.floor(Math.random() * boardSize);
    const col = Math.floor(Math.random() * boardSize);
    if (!board[row][col].bomb) {
      board[row][col].bomb = true;
      bombsPlaced++;
    }
  }

  // محاسبه تعداد بمب‌های اطراف
  for (let i = 0; i < boardSize; i++) {
    for (let j = 0; j < boardSize; j++) {
      if (!board[i][j].bomb) {
        board[i][j].count = countNearbyBombs(i, j);
      }
    }
  }

  // انیمیشن‌های اولیه
  gsap.from(".title", { y: -50, opacity: 0, duration: 1, delay: 0.2 });
  gsap.from(".subtitle", { y: -50, opacity: 0, duration: 1, delay: 0.4 });
  gsap.from(".restart-btn", { scale: 0.5, opacity: 0, duration: 0.8, delay: 0.6 });
  gsap.from(".board", { scale: 0.8, opacity: 0, duration: 1, delay: 0.8 });
}

function countNearbyBombs(row, col) {
  let count = 0;
  for (let i = -1; i <= 1; i++) {
    for (let j = -1; j <= 1; j++) {
      const r = row + i;
      const c = col + j;
      if (r >= 0 && r < boardSize && c >= 0 && c < boardSize && board[r][c].bomb) {
        count++;
      }
    }
  }
  return count;
}

async function handleCellClick(e) {
  if (gameOver) return;

  const row = parseInt(e.target.dataset.row);
  const col = parseInt(e.target.dataset.col);
  const cell = board[row][col];

  if (cell.open) return;
  cell.open = true;
  e.target.classList.add('open');

  if (cell.bomb) {
    e.target.classList.add('bomb');
    gameOver = true;
    document.getElementById('result').textContent = 'باختید! بمب منفجر شد!';
    gsap.to(e.target, { scale: 1.5, duration: 0.3, yoyo: true, repeat: 1 });
    gsap.to(".result", { opacity: 1, y: 0, duration: 0.5 });
    await submitScore(0);
  } else {
    e.target.classList.add('safe');
    e.target.textContent = cell.count || '';
    gsap.to(e.target, { scale: 1.1, duration: 0.2, yoyo: true, repeat: 1 });
    const score = calculateScore();
    if (score >= (boardSize * boardSize - bombCount)) {
      document.getElementById('result').textContent = 'تبریک! برنده شدید!';
      gsap.to(".result", { opacity: 1, color: '#2ecc71', duration: 0.5 });
      await submitScore(score);
    }
  }
}

function calculateScore() {
  let score = 0;
  for (let i = 0; i < boardSize; i++) {
    for (let j = 0; j < boardSize; j++) {
      if (board[i][j].open && !board[i][j].bomb) score++;
    }
  }
  return score;
}

async function submitScore(score) {
  const response = await fetch('https://your-api-endpoint/score', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ player: 'کاربر', score })
  });

  const data = await response.json();
  document.getElementById('scores').textContent = data.leaderboard.map(s => `${s.player}: ${s.score}`).join(', ');
  gsap.to("#leaderboard", { opacity: 1, y: 0, duration: 0.5 });
}

function restartGame() {
  gsap.to(".board", { opacity: 0, duration: 0.5, onComplete: initGame });
}

initGame();

 

توضیح انیمیشن‌ها

  • ورود المان‌ها: عنوان، زیرعنوان، دکمه شروع مجدد و شبکه بازی با افکت محو شدن و تغییر مقیاس وارد می‌شوند.

  • کلیک روی خانه‌ها: اگر خانه بمب باشد، با انیمیشن بزرگ شدن و لرزش نمایش داده می‌شود. اگر امن باشد، با یک افکت مقیاس کوچک ظاهر می‌شود.

  • نمایش نتیجه: پیام برد یا باخت با افکت محو شدن و تغییر رنگ (سبز برای برد، قرمز برای باخت) نشان داده می‌شود.

  • جدول امتیازات: با افکت محو شدن و جابجایی از پایین به‌روزرسانی می‌شود.

قدم سوم: بک‌اند با C# و .NET

بک‌اند برای ذخیره و مدیریت امتیازات بازیکنان استفاده می‌شود. کد زیر یک API ساده برای ثبت و دریافت امتیازات ارائه می‌دهد.

کد C# (Controllers/ScoreController.cs)

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;

namespace Minesweeper.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ScoreController : ControllerBase
    {
        private static readonly List<PlayerScore> leaderboard = new List<PlayerScore>();

        public class PlayerScore
        {
            public string Player { get; set; }
            public int Score { get; set; }
        }

        [HttpPost]
        public IActionResult PostScore([FromBody] ScoreInput input)
        {
            var existingPlayer = leaderboard.FirstOrDefault(p => p.Player == input.Player);
            if (existingPlayer == null)
            {
                leaderboard.Add(new PlayerScore { Player = input.Player, Score = input.Score });
            }
            else if (input.Score > existingPlayer.Score)
            {
                existingPlayer.Score = input.Score;
            }

            return Ok(new { leaderboard });
        }
    }

    public class ScoreInput
    {
        public string Player { get; set; }
        public int Score { get; set; }
    }
}

تنظیم پروژه .NET

  1. یک پروژه ASP.NET Core Web API ایجاد کنید.

  2. پکیج مورد نیاز:

 

dotnet add package Microsoft.AspNetCore.Mvc

  1. کد بالا را در پوشه Controllers قرار دهید.

قدم چهارم: تست و اجرا

  1. فرانت‌اند: فایل‌های HTML، CSS و JavaScript را در یک سرور محلی (مثل Live Server در VS Code) اجرا کنید.

  2. بک‌اند: پروژه .NET را با دستور زیر اجرا کنید:

 

dotnet run

      3. آدرس API (مثل https://localhost:5001/api/score) را در کد JavaScript تنظیم کنید.

      4.مطمئن شوید GSAP از CDN به‌درستی لود شده است.

نکات اضافی

  • افزودن صدا: با HTML5 Audio یا Howler.js می‌توانید صدای کلیک یا انفجار بمب اضافه کنید.

  • انیمیشن‌های پیشرفته: با GSAP می‌توانید افکت‌های پیچیده‌تری مثل انفجار بمب یا چرخش خانه‌ها اضافه کنید.

  • چندنفره بلادرنگ: از SignalR در .NET برای به‌روزرسانی بلادرنگ شبکه و امتیازات استفاده کنید.

  • بهینه‌سازی: تعداد انیمیشن‌های همزمان را محدود کنید تا عملکرد بازی روان بماند.

نتیجه‌گیری

با این آموزش، یک بازی آنلاین مین‌روب با رابط کاربری جذاب و انیمیشن‌های GSAP ساختید. این پروژه به شما کمک می‌کند تا مهارت‌های HTML، CSS، JavaScript و .NET را در کنار انیمیشن‌سازی با GSAP تمرین کنید. حالا بازی را تست کنید و ویژگی‌های جدید مثل تایمر یا سطوح مختلف سختی به آن اضافه کنید!