بناء ألعاب باستخدام JavaScript

بناء ألعاب باستخدام JavaScript

تعلم JavaScript لا يقتصر على عرض النصوص في المتصفح أو التعامل مع الأزرار والنماذج فقط. هذه اللغة الصغيرة في بدايتها، الكبيرة في تأثيرها، تمنحك بوابة ممتعة جدًا إلى عالم صناعة الألعاب. وربما هذا هو أجمل طريق لتعلمها أصلًا، لأن الألعاب تجعل البرمجة حيّة أمامك: تضغط زرًا فتتحرك الصورة، تغيّر قيمة فتتبدّل النتيجة، تكتب سطرًا فتولد قصة تفاعلية كاملة. هنا لا يكون الكود مجرد نص جامد، بل يصبح شيئًا تراه وتسمعه وتلمسه بعينك كل ثانية.

إذا كنت مبتدئًا، فربما تشعر أن بناء لعبة شيء معقّد، وأنه يحتاج إلى خبرة طويلة أو محرك ألعاب ضخم أو معرفة متقدمة في الرياضيات. الحقيقة أبسط من ذلك بكثير. يمكنك أن تبدأ بألعاب صغيرة جدًا داخل المتصفح، وتتعلم من خلالها أساسيات مهمة مثل التعامل مع العناصر في الصفحة، والاستماع إلى الأحداث، وإدارة الحالة، والتفكير المنطقي، وربط المدخلات بالمخرجات. والأجمل من ذلك أنك ستتعلم كل هذا وأنت تصنع شيئًا ممتعًا بدل أن تحفظ المفاهيم بشكل جاف.

في هذا المقال سنبني معًا عقلية مطوّر الألعاب المبتدئ. لن نتعامل مع اللعبة كفكرة غامضة، بل سنفككها إلى أجزاء مفهومة: واجهة، منطق، حالة، قواعد، وتنفيذ. وسنمر على عدة أمثلة عملية بسيطة لكنها مفيدة جدًا، مثل لعبة تخمين الرقم، لعبة حجر ورقة مقص، لعبة XO، ولمحة أولى عن ألعاب الرسم على Canvas. الهدف ليس فقط أن تنسخ الأكواد، بل أن تفهم لماذا كُتبت بهذه الطريقة، وكيف تطوّرها بنفسك لاحقًا.


لماذا تعتبر JavaScript مناسبة جدًا للألعاب للمبتدئين؟

السبب الأول بسيط: JavaScript تعمل مباشرة في المتصفح. لا تحتاج إلى تثبيت بيئة معقدة أو إعدادات طويلة. افتح ملف HTML، أضف سكربت، وابدأ التجربة. هذا وحده يجعلها مثالية للمبتدئ الذي يريد نتائج سريعة وواضحة. والسبب الثاني أنها مرتبطة بالـ DOM والأحداث، وهذا يعني أنك تستطيع تحويل أي صفحة ويب تقريبًا إلى تجربة تفاعلية. والسبب الثالث أنها تمنحك طريقًا تدريجيًا جدًا للتعلّم: تبدأ بأزرار ونصوص، ثم رسوم بسيطة، ثم Canvas، ثم أنيميشن، ثم ألعاب أكثر احترافًا.

عندما تبني لعبة في JavaScript فأنت في الحقيقة تتعلم أشياء أوسع من الألعاب نفسها. تتعلم كيف تفكر في “الحالة” الحالية للعبة، وكيف تدير “الحدث” الذي يغيرها، وكيف تعرض هذا التغيير للمستخدم بشكل واضح. هذه المفاهيم ستفيدك لاحقًا في تطبيقات الويب، ولوحات التحكم، وحتى في تطبيقات الجوال أو الخلفية. لذلك، لعبة صغيرة قد تبدو بسيطة جدًا، لكنها في الحقيقة تدريب ممتاز على طريقة التفكير البرمجية الصحيحة.

ومع أن هناك محركات ألعاب قوية مثل Unity وGodot، فإن البدء بـ JavaScript له قيمة خاصة. أنت لا تتعلم المحرك فقط، بل تتعلم الجوهر: كيف تتحرك الأشياء؟ كيف يتفاعل المستخدم؟ كيف يتغير الوضع بعد كل نقرة أو ضغطة؟ هذه الأسئلة هي قلب أي لعبة، وأفضل مكان لبدء فهمها هو المتصفح.


ما الذي تحتاجه قبل أن تبدأ؟

الخبر السار هو أنك لا تحتاج إلى تجهيزات كثيرة. في البداية، يكفيك المتصفح وملف HTML وملف JavaScript. يمكنك العمل في محرر بسيط مثل VS Code، أو حتى داخل ملف واحد إذا أردت تجربة سريعة. من الجميل جدًا أن تبدأ بأبسط شكل ممكن، لأن التعقيد الزائد في البداية يقتل الحماس. وأنت هنا تحتاج إلى الحماس أكثر من أي شيء آخر.

في العادة، ستحتاج إلى ثلاثة أشياء فقط:

العنصر

وظيفته

HTML

يبني هيكل الصفحة والعناصر التي سيرىها اللاعب

CSS

يضيف الشكل الجميل والتنسيق والهوية البصرية

JavaScript

يكتب منطق اللعبة والتفاعل والحركة

فكّر في HTML كأنه خشبة المسرح، وCSS كأنه الإضاءة والديكور، وJavaScript كأنه المخرج الذي يحرّك كل شيء. بدون JavaScript لن تكون لديك لعبة حقيقية، لكن بدون HTML وCSS لن تكون لديك مساحة العرض أصلًا. ولهذا السبب نحتاج الثلاثة معًا، حتى لو كان التركيز الأساسي في هذا المقال على JavaScript.


الفكرة الأساسية: أي لعبة يمكن تفكيكها إلى أجزاء

قبل أن نكتب أول سطر كود، من المفيد أن نفكر كما يفكر مطوّر الألعاب. أي لعبة بسيطة غالبًا تتكون من هذه العناصر:

  • حالة اللعبة: ما الذي يحدث الآن؟

  • قواعد اللعبة: متى يربح اللاعب؟ متى يخسر؟

  • المدخلات: ماذا يفعل اللاعب؟

  • الإخراج: ماذا ترى على الشاشة؟

  • إعادة البدء: كيف تبدأ من جديد؟

هذه العناصر تتكرر في معظم الألعاب، سواء كانت لعبة تخمين رقم أو لعبة قتال ثلاثية الأبعاد. الفارق فقط في مستوى التعقيد. لذلك إذا فهمت هذه اللبنات الصغيرة، فإنك تضع قدميك على الطريق الصحيح. لا تتعجل الوصول إلى ألعاب كبيرة. ابدأ بفكرة بسيطة جدًا، ثم أضف إليها خطوة خطوة، وستفاجأ بنفسك بعد فترة قصيرة.


أول لعبة: لعبة تخمين الرقم

هذه واحدة من أفضل الألعاب للمبتدئين، لأنها تعلمك التفاعل مع المستخدم، والتحقق من المدخلات، ومقارنة القيم، وعرض الرسائل، وتحديث الحالة. الفكرة بسيطة: البرنامج يختار رقمًا عشوائيًا بين 1 و100، وعلى اللاعب أن يخمّنه. عند كل محاولة، تخبره اللعبة إن كان الرقم أكبر أو أصغر من التخمين.

ملف HTML

<!DOCTYPE html>
<html lang="ar">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>لعبة تخمين الرقم</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      direction: rtl;
      text-align: center;
      background: #f4f7fb;
      padding: 40px;
    }

    .game-box {
      max-width: 500px;
      margin: auto;
      background: white;
      padding: 30px;
      border-radius: 16px;
      box-shadow: 0 10px 30px rgba(0,0,0,0.08);
    }

    input, button {
      padding: 12px 16px;
      font-size: 16px;
      margin-top: 10px;
      border-radius: 10px;
      border: 1px solid #ccc;
    }

    button {
      cursor: pointer;
      background: #2563eb;
      color: white;
      border: none;
    }

    #message {
      margin-top: 20px;
      font-size: 18px;
      min-height: 28px;
    }
  </style>
</head>
<body>
  <div class="game-box">
    <h1>لعبة تخمين الرقم</h1>
    <p>اختر رقمًا بين 1 و 100 وحاول الوصول إلى الرقم الصحيح.</p>
    <input type="number" id="guessInput" placeholder="اكتب تخمينك هنا" />
    <br />
    <button id="guessBtn">تحقق</button>
    <button id="restartBtn">إعادة اللعب</button>
    <p id="message"></p>
    <p id="attempts"></p>
  </div>

  <script src="script.js"></script>
</body>
</html>

ملف JavaScript

let secretNumber = Math.floor(Math.random() * 100) + 1;
let attempts = 0;

const guessInput = document.getElementById("guessInput");
const guessBtn = document.getElementById("guessBtn");
const restartBtn = document.getElementById("restartBtn");
const message = document.getElementById("message");
const attemptsText = document.getElementById("attempts");

function checkGuess() {
  const userGuess = Number(guessInput.value);

  if (!userGuess) {
    message.textContent = "من فضلك اكتب رقمًا صحيحًا.";
    return;
  }

  attempts++;

  if (userGuess < secretNumber) {
    message.textContent = "الرقم أكبر من تخمينك.";
  } else if (userGuess > secretNumber) {
    message.textContent = "الرقم أصغر من تخمينك.";
  } else {
    message.textContent = `أحسنت! لقد وجدت الرقم الصحيح وهو ${secretNumber}.`;
  }

  attemptsText.textContent = `عدد المحاولات: ${attempts}`;
  guessInput.value = "";
  guessInput.focus();
}

function restartGame() {
  secretNumber = Math.floor(Math.random() * 100) + 1;
  attempts = 0;
  message.textContent = "تمت إعادة اللعبة. حاول من جديد!";
  attemptsText.textContent = "";
  guessInput.value = "";
  guessInput.focus();
}

guessBtn.addEventListener("click", checkGuess);
restartBtn.addEventListener("click", restartGame);

guessInput.addEventListener("keydown", function(event) {
  if (event.key === "Enter") {
    checkGuess();
  }
});

ماذا تتعلم من هذه اللعبة؟

هذه اللعبة تبدو بسيطة، لكنها تعلّمك أشياء ثمينة جدًا. أولًا، تعلّمك كيف تولّد قيمة عشوائية باستخدام Math.random() وMath.floor(). ثانيًا، تعلّمك كيف تقرأ قيمة من حقل إدخال وتحولها إلى رقم باستخدام Number(). ثالثًا، تعلّمك كيف تبني منطقًا يعتمد على المقارنة: أصغر، أكبر، أو يساوي. وأخيرًا، تعلّمك كيف تعرض رسائل مباشرة للمستخدم بدلاً من طباعتها في الكونسول فقط.

وهناك درس مهم جدًا هنا: لا تجعل اللعبة تعتمد على التخمينات غير الصحيحة. لاحظ أننا تحققنا أولًا من أن المستخدم أدخل رقمًا فعلًا، ثم انتقلنا إلى المقارنة. هذا النوع من التفكير هو ما يصنع الكود الجيد. ليس المطلوب فقط أن تعمل اللعبة، بل أن تعمل بشكل محترم وواضح حتى لو أخطأ اللاعب.


اللعبة الثانية: حجر ورقة مقص

هذه اللعبة معروفة جدًا، وممتازة لتعليمك كيفية إدارة الحالة بين اللاعب والكمبيوتر. هنا لا تحتاج إلى تعقيد، لكنك تحتاج إلى قواعد واضحة. لكل اختيار نتيجة محددة، ولا بد أن يحدد البرنامج الفائز في كل جولة. هذه اللعبة مثالية لأنك ستبدأ بالتفكير في “المنطق الشرطي” بطريقة عملية جدًا.

هيكل بسيط للعبة

<!DOCTYPE html>
<html lang="ar">
<head>
  <meta charset="UTF-8" />
  <meta charset="UTF-8">
  <title>حجر ورقة مقص</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      direction: rtl;
      text-align: center;
      background: #eef2ff;
      padding: 40px;
    }

    .buttons button {
      padding: 12px 18px;
      margin: 10px;
      font-size: 16px;
      border: none;
      border-radius: 10px;
      background: #4f46e5;
      color: white;
      cursor: pointer;
    }

    .result {
      margin-top: 20px;
      font-size: 20px;
      min-height: 30px;
    }
  </style>
</head>
<body>
  <h1>لعبة حجر ورقة مقص</h1>
  <p>اختر أحد الخيارات وواجه الكمبيوتر.</p>

  <div class="buttons">
    <button onclick="play('rock')">حجر</button>
    <button onclick="play('paper')">ورقة</button>
    <button onclick="play('scissors')">مقص</button>
  </div>

  <div class="result" id="result"></div>

  <script src="script.js"></script>
</body>
</html>

منطق اللعبة

function getComputerChoice() {
  const choices = ["rock", "paper", "scissors"];
  const randomIndex = Math.floor(Math.random() * choices.length);
  return choices[randomIndex];
}

function play(userChoice) {
  const computerChoice = getComputerChoice();
  const result = document.getElementById("result");

  if (userChoice === computerChoice) {
    result.textContent = `تعادل! اخترتَ ${translate(userChoice)} والكمبيوتر اختار ${translate(computerChoice)}.`;
    return;
  }

  if (
    (userChoice === "rock" && computerChoice === "scissors") ||
    (userChoice === "paper" && computerChoice === "rock") ||
    (userChoice === "scissors" && computerChoice === "paper")
  ) {
    result.textContent = `فزت! اخترتَ ${translate(userChoice)} والكمبيوتر اختار ${translate(computerChoice)}.`;
  } else {
    result.textContent = `خسرت! اخترتَ ${translate(userChoice)} والكمبيوتر اختار ${translate(computerChoice)}.`;
  }
}

function translate(choice) {
  if (choice === "rock") return "حجر";
  if (choice === "paper") return "ورقة";
  if (choice === "scissors") return "مقص";
}

لماذا هذه اللعبة مهمة؟

لأنها تعلّمك كيف تفكر في قواعد واضحة. كل اختيار له نتيجة. هذا يشبه كثيرًا ما يحدث في الألعاب الحقيقية: اللاعب يختار، والبرنامج يحلل القرار ثم يقرر النتيجة. هنا تبدأ برؤية قوة if وelse بشكل عملي، وتبدأ أيضًا بفهم أهمية التنظيم. لو كتبت المنطق بعشوائية، ستتعقد اللعبة بسرعة. أما لو فهمت القاعدة الأساسية جيدًا، فستستطيع توسيع اللعبة لاحقًا بسهولة: عداد نقاط، جولات متعددة، أصوات، أو حتى أنيميشن.

وربما أجمل شيء في هذه اللعبة أنها تذكرنا بأن اللعبة الجيدة ليست كبيرة دائمًا. أحيانًا يكفي منطق بسيط جدًا وتجربة ممتعة ومباشرة. وهذا درس مهم للمبتدئ: لا تربط القيمة بالحجم. اللعبة الصغيرة قد تكون ممتازة إذا كانت واضحة وممتعة.


اللعبة الثالثة: XO أو Tic Tac Toe

هذه من أفضل الألعاب للمبتدئين بعد الألعاب السريعة البسيطة، لأنها تدخل بك إلى عالم “الشبكة” أو “grid” وإدارة الحالات المتعددة. هنا لديك 9 خانات، وكل خانة قد تكون فارغة أو تحتوي X أو O. وبعد كل حركة، يجب أن تتحقق إن كان هناك فائز. هذا النوع من التفكير سيفتح لك بابًا مهمًا جدًا في تطوير الألعاب: تمثيل الحالة بشكل منظّم.

HTML

<!DOCTYPE html>
<html lang="ar">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>XO</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      direction: rtl;
      text-align: center;
      background: #f8fafc;
      padding: 30px;
    }

    .board {
      display: grid;
      grid-template-columns: repeat(3, 100px);
      gap: 10px;
      justify-content: center;
      margin: 30px auto;
    }

    .cell {
      width: 100px;
      height: 100px;
      background: white;
      border: 2px solid #334155;
      font-size: 40px;
      font-weight: bold;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      border-radius: 12px;
    }

    .status {
      font-size: 20px;
      margin-top: 20px;
      min-height: 28px;
    }

    button {
      padding: 12px 18px;
      font-size: 16px;
      border: none;
      border-radius: 10px;
      background: #0f766e;
      color: white;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <h1>لعبة XO</h1>
  <p>اللاعب X يبدأ أولًا، ثم يأتي O.</p>

  <div class="board" id="board"></div>
  <div class="status" id="status"></div>
  <button onclick="restartGame()">إعادة اللعب</button>

  <script src="script.js"></script>
</body>
</html>

JavaScript

const board = document.getElementById("board");
const status = document.getElementById("status");

let cells = ["", "", "", "", "", "", "", "", ""];
let currentPlayer = "X";
let gameActive = true;

const winningCombinations = [
  [0, 1, 2],
  [3, 4, 5],
  [6, 7, 8],
  [0, 3, 6],
  [1, 4, 7],
  [2, 5, 8],
  [0, 4, 8],
  [2, 4, 6]
];

function createBoard() {
  board.innerHTML = "";
  cells.forEach((cell, index) => {
    const cellElement = document.createElement("div");
    cellElement.classList.add("cell");
    cellElement.textContent = cell;
    cellElement.addEventListener("click", () => handleCellClick(index));
    board.appendChild(cellElement);
  });
}

function handleCellClick(index) {
  if (!gameActive || cells[index] !== "") return;

  cells[index] = currentPlayer;
  currentPlayer = currentPlayer === "X" ? "O" : "X";

  checkWinner();
  createBoard();
}

function checkWinner() {
  for (let combination of winningCombinations) {
    const [a, b, c] = combination;

    if (
      cells[a] !== "" &&
      cells[a] === cells[b] &&
      cells[a] === cells[c]
    ) {
      status.textContent = `اللاعب ${cells[a]} فاز باللعبة!`;
      gameActive = false;
      return;
    }
  }

  if (!cells.includes("")) {
    status.textContent = "انتهت اللعبة بالتعادل.";
    gameActive = false;
    return;
  }

  status.textContent = `الدور على اللاعب ${currentPlayer}`;
}

function restartGame() {
  cells = ["", "", "", "", "", "", "", "", ""];
  currentPlayer = "X";
  gameActive = true;
  status.textContent = "ابدأ اللعب.";
  createBoard();
}

createBoard();
status.textContent = `الدور على اللاعب ${currentPlayer}`;

ماذا تتعلم هنا؟

هنا يبدأ مستوى جديد من التفكير. لم تعد تتعامل مع زر واحد ورسالة واحدة فقط. أنت الآن تتعامل مع مصفوفة تمثل حالة كاملة للعبة. وهذا مهم جدًا لأن الألعاب في جوهرها هي إدارة حالة. الخانة رقم 0 يمكن أن تكون X، والخانة رقم 1 يمكن أن تكون O، وهكذا. كل حركة تغيّر جزءًا من الحالة، ثم يتم فحص النتيجة. هذا يشبه منطق العديد من الألعاب الأخرى أكثر مما تتخيل.

أكثر ما يميز هذا المثال هو أنك بدأت تستخدم مصفوفات وأنماط تكرار وفحص شامل للفوز. هذه مهارات صغيرة لكنها تتكرر كثيرًا في JavaScript. والأهم من ذلك أن اللعبة قابلة للتطوير: يمكنك إضافة تأثيرات بصرية، أو جعل اللاعب يلعب ضد الكمبيوتر، أو تخزين النتائج، أو إظهار إحصاءات، أو حتى تحسين التصميم بالكامل.


اللعب بالرسوم: مقدمة إلى Canvas

إذا كنت تريد أن تدخل إلى عالم الألعاب بشكل أوسع قليلًا، فلا بد أن تتعرف على <canvas>. هذا العنصر يتيح لك الرسم والتحريك داخل المتصفح. قد يبدو في البداية أكثر تعقيدًا من التعامل مع عناصر HTML العادية، لكنه في الحقيقة أداة جميلة جدًا. باستخدامه يمكنك رسم مربعات ودوائر وصور وحركات ومؤثرات بسيطة. كثير من الألعاب الخفيفة تبدأ من هنا.

مثال بسيط جدًا على الرسم

<!DOCTYPE html>
<html lang="ar">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Canvas بسيط</title>
  <style>
    body {
      text-align: center;
      direction: rtl;
      font-family: Arial, sans-serif;
      background: #f1f5f9;
      padding: 40px;
    }

    canvas {
      border: 2px solid #334155;
      background: white;
      border-radius: 12px;
    }
  </style>
</head>
<body>
  <h1>رسم بسيط على Canvas</h1>
  <canvas id="gameCanvas" width="500" height="300"></canvas>

  <script>
    const canvas = document.getElementById("gameCanvas");
    const ctx = canvas.getContext("2d");

    ctx.fillStyle = "blue";
    ctx.fillRect(50, 50, 100, 100);

    ctx.beginPath();
    ctx.arc(300, 150, 50, 0, Math.PI * 2);
    ctx.fillStyle = "red";
    ctx.fill();
  </script>
</body>
</html>

لماذا Canvas مهم؟

لأن الألعاب لا تقتصر على أزرار وخانات نص. أحيانًا تحتاج إلى تحكم كامل في ما يُرسم داخل المنطقة. في Canvas أنت ترسم كل شيء بنفسك، وهذا يمنحك حرية كبيرة. نعم، هذا يعني أيضًا أنك تتحمل مسؤولية أكبر، لكن المكسب كبير. ستفهم كيف تتحرك الأشياء، وكيف يتم تحديث الشاشة باستمرار، وكيف يمكن بناء جسم يتحرك أو كرة ترتد أو شخصية تتبع المؤشر.

وفي البداية، لا تحتاج إلى البدء بلعبة ضخمة على Canvas. يكفي أن ترسم شيئًا صغيرًا، ثم تحركه، ثم تضيف عنصرًا ثانيًا، ثم تتعرف على حلقة التحديث. بهذه الطريقة تبني خبرتك تدريجيًا وبثبات.


كيف تنشئ حركة بسيطة داخل Canvas؟

الجزء الأهم في ألعاب Canvas هو “حلقة اللعب” أو Game Loop. الفكرة بسيطة: تحديث الحالة، ثم الرسم، ثم التكرار. هذا يحدث عشرات المرات في الثانية حتى تشعر أن الحركة طبيعية وسلسة. دعنا نرى مثالًا صغيرًا على كرة تتحرك داخل الشاشة وترتد من الجدران.

<!DOCTYPE html>
<html lang="ar">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>كرة تتحرك</title>
  <style>
    body {
      text-align: center;
      direction: rtl;
      font-family: Arial, sans-serif;
      background: #e2e8f0;
      padding: 30px;
    }

    canvas {
      border: 2px solid #0f172a;
      background: white;
      border-radius: 10px;
    }
  </style>
</head>
<body>
  <h1>كرة تتحرك داخل Canvas</h1>
  <canvas id="canvas" width="600" height="400"></canvas>

  <script>
    const canvas = document.getElementById("canvas");
    const ctx = canvas.getContext("2d");

    let x = 100;
    let y = 100;
    let dx = 3;
    let dy = 2;
    const radius = 20;

    function drawBall() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      ctx.beginPath();
      ctx.arc(x, y, radius, 0, Math.PI * 2);
      ctx.fillStyle = "green";
      ctx.fill();
      ctx.closePath();

      x += dx;
      y += dy;

      if (x + radius > canvas.width || x - radius < 0) {
        dx = -dx;
      }

      if (y + radius > canvas.height || y - radius < 0) {
        dy = -dy;
      }

      requestAnimationFrame(drawBall);
    }

    drawBall();
  </script>
</body>
</html>

هذا المثال يفتح لك الباب لفهم أهم جزء في معظم الألعاب: “التحديث المستمر”. لاحظ أننا لا نرسم مرة واحدة فقط، بل نكرر العملية عبر requestAnimationFrame. هذه النقطة وحدها مهمة جدًا، لأنها هي التي تمنح الحركة سلاستها. وفي كل مرة نعيد فيها الرسم، نمسح الشاشة أولًا ثم نرسم من جديد في الموقع الجديد.


ما الذي يجب أن تتعلمه بالترتيب؟

كثير من المبتدئين يقفزون مباشرة إلى مشاريع كبيرة ثم يشعرون بالإحباط. الأفضل هو أن تمشي بالترتيب. هذا ليس تقليلًا من طموحك، بل احترامًا لطريقة التعلم الطبيعية. عندما تتعلم خطوة بخطوة، تبقى متحمسًا وتفهم ما يحدث فعلًا بدل أن تحفظ أكوادًا لا تعرف كيف تعمل.

المرحلة

ماذا تتعلم؟

مشروع صغير مناسب

1

المتغيرات والشروط

لعبة تخمين الرقم

2

الأحداث وأزرار الواجهة

حجر ورقة مقص

3

المصفوفات والحالات

لعبة XO

4

Canvas والرسم

كرة تتحرك

5

الحركة والتصادم

لعبة Pong بسيطة

6

التنظيم وتفكيك الكود

لعبة كاملة صغيرة

هذا التدرج مهم جدًا. ليس لأنك لا تستطيع القفز، بل لأنك ستستفيد أكثر إذا فهمت كل طبقة قبل الانتقال إلى التي بعدها. البرمجة مثل البناء؛ إذا لم تكن القاعدة قوية، ستتعب لاحقًا في إصلاح الشروخ.


كيف تنظّم كود اللعبة بشكل جيد؟

من أكثر الأخطاء التي يقع فيها المبتدئون أن يكتبوا كل شيء في مكان واحد. في البداية قد يبدو ذلك أسرع، لكنه يتحول بسرعة إلى فوضى. لذلك من الأفضل أن تتعلم تنظيم الكود منذ البداية. حتى في لعبة صغيرة، حاول أن تفصل بين الأشياء: دوال للرسم، دوال للتحديث، دوال للتحقق من الفوز، دوال لإعادة التشغيل.

مثال صغير على التنظيم:

function initGame() {
  // إعداد القيم الأولية
}

function updateGame() {
  // تحديث الحالة
}

function renderGame() {
  // رسم كل شيء على الشاشة
}

function handleInput() {
  // التعامل مع ضغطات المستخدم
}

function gameLoop() {
  updateGame();
  renderGame();
  requestAnimationFrame(gameLoop);
}

initGame();
gameLoop();

هذا الفصل يبدو بسيطًا، لكنه يمنحك وضوحًا كبيرًا. عندما تكبر اللعبة، ستشكر نفسك على هذا التنظيم. وستلاحظ أنك أصبحت أسرع في فهم الكود وتصحيحه وتوسيعه. وهنا تحديدًا يظهر الفرق بين كتابة كود “يعمل” وكتابة كود “مريح للعيش معه”.


أخطاء شائعة يقع فيها المبتدئون

من الطبيعي جدًا أن تخطئ في البداية. بل إن الأخطاء جزء أساسي من التعلم. لكن هناك أخطاء تتكرر كثيرًا، ومن الأفضل أن تنتبه لها مبكرًا حتى لا تضيع وقتك في دوائر مكررة.

أول خطأ هو الخلط بين النصوص والأرقام. أحيانًا تكون قيمة الإدخال نصًا، وأنت تتعامل معها كأنها رقم. لهذا من المهم التحويل باستخدام Number() أو parseInt() حسب الحاجة. الخطأ الثاني هو نسيان تحديث الواجهة بعد تغيير الحالة. أنت قد تغيّر القيمة داخل المتغير، لكن اللاعب لن يرى شيئًا إن لم تعكس ذلك على الشاشة. الخطأ الثالث هو تكرار الكود بلا داعٍ. كلما وجدت أنك تكرر نفس المنطق أكثر من مرة، اسأل نفسك: هل يمكنني وضعه داخل دالة؟ الخطأ الرابع هو كتابة لعبة كاملة قبل اختبار كل جزء صغير. الأفضل أن تختبر كل خطوة وحدها، ثم تجمعها لاحقًا.

وهناك خطأ نفسي أيضًا، وهو الاستعجال. كثير من الناس يريدون الوصول إلى لعبة معقدة بسرعة، ثم يصابون بالإرهاق. لكن الحقيقة أن كل لعبة كبيرة تبدأ من مربع واحد يتحرك أو زر واحد يعمل. لا تستهن بالخطوات الصغيرة، لأنها هي التي تصنع الفارق الحقيقي.


كيف تضيف “روحًا” إلى لعبتك؟

اللعبة الجيدة ليست منطقًا فقط. هي إحساس أيضًا. وما يجعل اللاعب يستمتع هو التفاصيل الصغيرة: صوت عند الفوز، لون يتغير عند الخطأ، حركة خفيفة عند الضغط، رسالة لطيفة، تصميم مريح للعين. هذه الأشياء لا تبدو ضخمة، لكنها تصنع التجربة. وهنا يظهر الجانب الإنساني في بناء الألعاب: أنت لا تكتب كودًا فحسب، بل تفكر في شخص سيجلس أمام الشاشة ويعيش هذه التجربة لبضع دقائق أو ربما ساعات.

جرب أن تضيف لمسة صغيرة مثل:

message.style.color = "green";
button.style.transform = "scale(1.05)";

أو استخدم انتقالًا بصريًا بسيطًا في CSS:

button {
  transition: transform 0.2s ease, background 0.2s ease;
}

button:hover {
  transform: scale(1.05);
}

هذه التفاصيل الصغيرة تجعل اللعبة أكثر حياة. وربما هذا هو سر الألعاب الجيدة عمومًا: ليست كلها أرقامًا وحسابات، بل إحساس وتوقيت وصوت وشكل وتوازن.


فكرة لعبة إضافية: النقر السريع

إذا أردت مشروعًا بسيطًا جدًا بعد هذه الأمثلة، فجرّب لعبة النقر السريع. الفكرة: لديك عداد، وكلما ضغط اللاعب على زر خلال وقت محدد ترتفع النقاط. هذه اللعبة ممتازة لتدريبك على الوقت والعدادات.

<!DOCTYPE html>
<html lang="ar">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>النقر السريع</title>
  <style>
    body {
      text-align: center;
      direction: rtl;
      font-family: Arial, sans-serif;
      padding: 40px;
      background: #f8fafc;
    }

    button {
      padding: 14px 24px;
      font-size: 18px;
      border: none;
      border-radius: 10px;
      background: #7c3aed;
      color: white;
      cursor: pointer;
    }

    .score {
      font-size: 24px;
      margin-top: 20px;
    }
  </style>
</head>
<body>
  <h1>لعبة النقر السريع</h1>
  <p>اضغط أكبر عدد ممكن من المرات خلال 10 ثوانٍ.</p>
  <button id="clickBtn">اضغط هنا</button>
  <p class="score">النقاط: <span id="score">0</span></p>
  <p id="timer">الوقت المتبقي: 10</p>

  <script>
    let score = 0;
    let timeLeft = 10;
    let gameOver = false;

    const scoreText = document.getElementById("score");
    const timerText = document.getElementById("timer");
    const clickBtn = document.getElementById("clickBtn");

    clickBtn.addEventListener("click", function() {
      if (gameOver) return;
      score++;
      scoreText.textContent = score;
    });

    const countdown = setInterval(function() {
      timeLeft--;
      timerText.textContent = `الوقت المتبقي: ${timeLeft}`;

      if (timeLeft === 0) {
        clearInterval(countdown);
        gameOver = true;
        timerText.textContent = `انتهت اللعبة! نتيجتك النهائية: ${score}`;
      }
    }, 1000);
  </script>
</body>
</html>

هذا المثال يعلمك شيئًا مهمًا جدًا: الألعاب لا تحتاج دائمًا إلى رسم معقد. أحيانًا يكون التفاعل وحده كافيًا ليصنع لعبة مسلية. والأهم أنه يدرّبك على التعامل مع setInterval، ومع إدارة الوقت، ومع إنهاء اللعبة في اللحظة المناسبة.


كيف تتطور من مبتدئ إلى مطوّر ألعاب أفضل؟

التطور الحقيقي لا يأتي من مشاهدة الكثير من الفيديوهات فقط، بل من البناء العملي. بعد كل لعبة صغيرة، اسأل نفسك: ماذا تعلمت؟ ماذا يمكن تحسينه؟ هل يمكنني إعادة كتابة الكود بشكل أوضح؟ هل يمكنني جعل التصميم أجمل؟ هل يمكنني إضافة صوت أو مستوى أو عداد نقاط؟ هذه الأسئلة تحوّل كل مشروع صغير إلى درس متكامل.

حاول أيضًا أن تبني ألعابًا من واقع بسيط جدًا. لعبة ذاكرة البطاقات، لعبة المطابقة، لعبة المتاهة، لعبة الرد السريع، أو حتى تطبيق تفاعلي يشبه اللعبة. المهم أن تستمر في الكتابة والتجربة. لا تنتظر اللحظة “المثالية” التي تشعر فيها أنك أصبحت جاهزًا؛ الجاهزية تأتي من العمل نفسه.

ومن المفيد كذلك أن تنظر أحيانًا إلى كودك بعد أيام قليلة بعين جديدة. ستلاحظ أشياء لم تكن تراها من قبل. ستقول: هنا كان يمكنني استخدام دالة، وهنا كان يمكنني تسمية المتغيرات بشكل أوضح، وهنا كان يجب أن أفصل المنطق عن العرض. هذا طبيعي جدًا، وهو علامة جيدة، لأنه يعني أنك تتطور فعلاً.


هل يجب أن أتعلم الرياضيات أولًا؟

ليس بالضرورة. هذا سؤال يقلق الكثير من المبتدئين. الحقيقة أن معظم الألعاب البسيطة التي ستبنيها في البداية لا تحتاج إلى رياضيات معقدة. نعم، ستحتاج إلى فهم بسيط للمسافات أو الاتجاهات أو السرعة، لكنك لست بحاجة إلى الجبر المتقدم أو الهندسة الصعبة لتبدأ. ابدأ أولًا بالألعاب التي تعتمد على المنطق والتفاعل، ثم ستكتشف أن الرياضيات المطلوبة تظهر بشكل طبيعي مع احتياجك لها.

في ألعاب Canvas مثلًا، قد تحتاج إلى فهم بسيط للموقع والحجم والسرعة. لكن هذا يأتي تدريجيًا جدًا. لا تجعل الرياضيات حاجزًا يمنعك من البدء. ابدأ بما تعرفه، وتعلم ما تحتاجه في الطريق.


ماذا بعد هذه المقالة؟

بعد أن تفهم الأساسيات، يمكنك الانتقال إلى ألعاب أكثر مرحًا مثل:

  • لعبة Pong

  • لعبة Snake

  • لعبة Memory Cards

  • لعبة المنصات البسيطة

  • لعبة إطلاق صغيرة جدًا

  • لعبة أسئلة وأجوبة تفاعلية

وكل لعبة من هذه الألعاب ستفتح لك مهارة جديدة. لعبة Snake ستعلمك عن الحركة والتصادم. لعبة Memory ستعلمك عن ترتيب البطاقات والحالة. لعبة Pong ستعلمك التحكم في الأجسام المرتدة. وكل ذلك سيجعل فهمك لـ JavaScript أعمق بكثير.

لا تتعامل مع هذه الرحلة على أنها سباق. هي أقرب إلى المشي الجميل من محطة إلى محطة. كل لعبة صغيرة تنجزها ستعطيك ثقة جديدة. وكل خطأ تصلحه بنفسك سيبني داخلك عقلًا برمجيًا أفضل من مئة درس نظري.


خاتمة

بناء الألعاب باستخدام JavaScript للمبتدئين ليس مجرد تمرين برمجي، بل هو طريقة ممتعة جدًا لتعلم التفكير المنطقي، وتنظيم الأفكار، وتحويل القواعد إلى سلوك حي على الشاشة. بدأت معنا الفكرة من أبسط شكل: لعبة تخمين الرقم، ثم انتقلنا إلى حجر ورقة مقص، ثم XO، ثم لمسنا عالم Canvas، ثم رأينا كيف يمكن للحركة والوقت أن يغيرا التجربة بالكامل. وكل هذا مجرد بداية.

الأجمل في هذا المجال أنك ترى نتائجك بسرعة. تكتب سطرًا فتظهر أمامك استجابة. تغيّر قيمة فتتبدل الرسالة. تضغط زرًا فتتحرك اللعبة. هذا الإحساس السريع بالنتيجة هو ما يجعل تعلم JavaScript في الألعاب ممتعًا جدًا. وربما لهذا السبب يعود كثير من المطورين إلى الألعاب الصغيرة كلما أرادوا تدريبًا جديدًا أو استعادة الحماس.

ابدأ صغيرًا، وكن صبورًا، واسمح لنفسك بالتجربة والخطأ. لا تبحث عن الكمال من أول مرة. ابحث عن الفهم، ثم التحسين، ثم المتعة. ومع كل لعبة ستكتبها، ستقترب خطوة من أن تصبح شخصًا لا يعرف فقط كيف يستخدم JavaScript، بل يعرف كيف يصنع بها تجربة حيّة ومؤثرة ومرحة.

#بناء ألعاب باستخدام JavaScript #ألعاب جافاسكريبت للمبتدئين #تعلم JavaScript بالعربي #برمجة ألعاب المتصفح #إنشاء ألعاب بسيطة بالجافاسكريبت