You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/ur/6-space-game/3-moving-elements-around/README.md

31 KiB

خلائی کھیل بنائیں حصہ 3: حرکت شامل کرنا

اپنے پسندیدہ کھیلوں کے بارے میں سوچیں جو انہیں دلچسپ بناتا ہے وہ صرف خوبصورت گرافکس نہیں ہیں، بلکہ یہ ہے کہ سب کچھ کیسے حرکت کرتا ہے اور آپ کے اعمال پر کیسے ردعمل ظاہر کرتا ہے۔ اس وقت، آپ کا خلائی کھیل ایک خوبصورت تصویر کی طرح ہے، لیکن ہم اس میں حرکت شامل کرنے والے ہیں جو اسے زندگی بخشے گی۔

جب ناسا کے انجینئرز نے اپولو مشنز کے لیے گائیڈنس کمپیوٹر پروگرام کیا، تو انہیں ایک جیسا چیلنج درپیش تھا: خلائی جہاز کو پائلٹ کے ان پٹ پر کیسے ردعمل دینا ہے جبکہ خودکار طور پر کورس کی اصلاحات کو برقرار رکھنا ہے؟ آج ہم جو اصول سیکھیں گے وہ انہی تصورات کی عکاسی کرتے ہیں کھلاڑی کے کنٹرول شدہ حرکت کو خودکار نظام کے رویوں کے ساتھ منظم کرنا۔

اس سبق میں، آپ سیکھیں گے کہ خلائی جہاز کو اسکرین پر کیسے حرکت دی جائے، کھلاڑی کے احکامات پر کیسے ردعمل دیا جائے، اور ہموار حرکت کے نمونے کیسے بنائے جائیں۔ ہم ہر چیز کو قابل انتظام تصورات میں تقسیم کریں گے جو قدرتی طور پر ایک دوسرے پر تعمیر ہوتے ہیں۔

آخر میں، آپ کے کھلاڑی اپنے ہیرو جہاز کو اسکرین پر اڑائیں گے جبکہ دشمن کے جہاز اوپر گشت کریں گے۔ اس سے بھی اہم بات یہ ہے کہ آپ ان بنیادی اصولوں کو سمجھیں گے جو کھیل کی حرکت کے نظام کو طاقت دیتے ہیں۔

پری لیکچر کوئز

پری لیکچر کوئز

کھیل کی حرکت کو سمجھنا

کھیل اس وقت زندہ محسوس ہوتے ہیں جب چیزیں حرکت کرنا شروع کرتی ہیں، اور بنیادی طور پر دو طریقے ہیں جن سے یہ ہوتا ہے:

  • کھلاڑی کے کنٹرول شدہ حرکت: جب آپ کوئی کلید دبائیں یا ماؤس پر کلک کریں، تو کچھ حرکت کرتا ہے۔ یہ آپ اور آپ کی کھیل کی دنیا کے درمیان براہ راست تعلق ہے۔
  • خودکار حرکت: جب کھیل خود چیزوں کو حرکت دینے کا فیصلہ کرتا ہے جیسے وہ دشمن کے جہاز جو اسکرین پر گشت کرنے کی ضرورت ہے چاہے آپ کچھ بھی نہ کریں۔

کمپیوٹر اسکرین پر اشیاء کو حرکت دینا آپ کے خیال سے زیادہ آسان ہے۔ یاد ہے وہ x اور y کوآرڈینیٹس جو آپ نے ریاضی کی کلاس میں سیکھے تھے؟ یہی وہ چیز ہے جس کے ساتھ ہم یہاں کام کر رہے ہیں۔ جب گلیلیو نے 1610 میں مشتری کے چاندوں کا مشاہدہ کیا، تو وہ بنیادی طور پر یہی کر رہا تھا وقت کے ساتھ پوزیشنز کو پلاٹ کر کے حرکت کے نمونوں کو سمجھنا۔

اسکرین پر چیزوں کو حرکت دینا ایک فلیپ بک اینیمیشن بنانے جیسا ہے آپ کو یہ تین آسان مراحل پر عمل کرنا ہوگا:

  1. پوزیشن کو اپ ڈیٹ کریں اپنی چیز کو کہاں ہونا چاہیے اسے تبدیل کریں (شاید اسے 5 پکسلز دائیں طرف لے جائیں)
  2. پرانا فریم مٹائیں اسکرین کو صاف کریں تاکہ آپ کو ہر جگہ بھوت نما نشان نظر نہ آئیں
  3. نیا فریم بنائیں اپنی چیز کو اس کی نئی جگہ پر رکھیں

یہ کافی تیزی سے کریں، اور بوم! آپ کے پاس ہموار حرکت ہے جو کھلاڑیوں کو قدرتی محسوس ہوتی ہے۔

یہ کوڈ میں کچھ اس طرح نظر آ سکتا ہے:

// Set the hero's location
hero.x += 5;
// Clear the rectangle that hosts the hero
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Redraw the game background and hero
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);

یہ کوڈ کیا کرتا ہے:

  • ہیرو کے x-کوآرڈینیٹ کو اپ ڈیٹ کرتا ہے تاکہ اسے افقی طور پر حرکت دی جا سکے
  • پورے کینوس کے علاقے کو صاف کرتا ہے تاکہ پچھلا فریم ہٹایا جا سکے
  • کینوس کو سیاہ پس منظر کے رنگ سے بھر دیتا ہے
  • ہیرو کی تصویر کو اس کی نئی پوزیشن پر دوبارہ بناتا ہے

کیا آپ سوچ سکتے ہیں کہ کیوں ہیرو کو کئی فریمز فی سیکنڈ دوبارہ بنانا کارکردگی کے اخراجات کو بڑھا سکتا ہے؟ اس پیٹرن کے متبادل کے بارے میں پڑھیں۔

کی بورڈ ایونٹس کو ہینڈل کریں

یہ وہ جگہ ہے جہاں ہم کھلاڑی کے ان پٹ کو کھیل کی کارروائی سے جوڑتے ہیں۔ جب کوئی اسپیس بار دبائے تاکہ لیزر فائر کرے یا تیر کی کلید دبائے تاکہ ایسٹروئیڈ سے بچ سکے، آپ کے کھیل کو اس ان پٹ کا پتہ لگانا اور اس پر ردعمل دینا ہوگا۔

کی بورڈ ایونٹس ونڈو لیول پر ہوتے ہیں، یعنی آپ کی پوری براؤزر ونڈو ان کلیدوں کے دبانے کو سن رہی ہوتی ہے۔ دوسری طرف، ماؤس کلکس مخصوص عناصر سے منسلک ہو سکتے ہیں (جیسے کسی بٹن پر کلک کرنا)۔ ہمارے خلائی کھیل کے لیے، ہم کی بورڈ کنٹرولز پر توجہ مرکوز کریں گے کیونکہ یہی کھلاڑیوں کو کلاسک آرکیڈ کا احساس دیتا ہے۔

یہ مجھے یاد دلاتا ہے کہ 1800 کی دہائی میں ٹیلی گراف آپریٹرز کو مورز کوڈ ان پٹ کو معنی خیز پیغامات میں ترجمہ کرنا پڑتا تھا ہم کچھ ایسا ہی کر رہے ہیں، کلیدوں کے دبانے کو کھیل کے احکامات میں ترجمہ کر رہے ہیں۔

کسی ایونٹ کو ہینڈل کرنے کے لیے آپ کو ونڈو کے addEventListener() طریقہ استعمال کرنے کی ضرورت ہے اور اسے دو ان پٹ پیرامیٹرز فراہم کرنے کی ضرورت ہے۔ پہلا پیرامیٹر ایونٹ کا نام ہے، مثال کے طور پر keyup۔ دوسرا پیرامیٹر وہ فنکشن ہے جو ایونٹ ہونے کے نتیجے میں بلایا جانا چاہیے۔

یہاں ایک مثال ہے:

window.addEventListener('keyup', (evt) => {
  // evt.key = string representation of the key
  if (evt.key === 'ArrowUp') {
    // do something
  }
});

یہاں کیا ہوتا ہے:

  • کی بورڈ ایونٹس کو پوری ونڈو پر سنتا ہے
  • ایونٹ آبجیکٹ کو کیپچر کرتا ہے جس میں معلومات ہوتی ہیں کہ کون سی کلید دبائی گئی تھی
  • چیک کرتا ہے کہ دبائی گئی کلید کسی مخصوص کلید سے میل کھاتی ہے (اس صورت میں، اوپر کی تیر کی کلید)
  • کوڈ کو چلاتا ہے جب شرط پوری ہو

کلید کے ایونٹس کے لیے ایونٹ پر دو پراپرٹیز ہیں جنہیں آپ دیکھ سکتے ہیں کہ کون سی کلید دبائی گئی تھی:

  • key - یہ دبائی گئی کلید کی سٹرنگ نمائندگی ہے، مثال کے طور پر 'ArrowUp'
  • keyCode - یہ ایک عددی نمائندگی ہے، مثال کے طور پر 37، جو ArrowLeft کے مطابق ہے

کلید کے ایونٹ کی ہیرا پھیری کھیل کی ترقی کے علاوہ بھی مفید ہے۔ اس تکنیک کے لیے آپ اور کیا استعمال سوچ سکتے ہیں؟

خاص کلیدیں: ایک انتباہ!

کچھ کلیدوں کے اندرونی براؤزر رویے ہوتے ہیں جو آپ کے کھیل میں مداخلت کر سکتے ہیں۔ تیر کی کلیدیں صفحہ کو اسکرول کرتی ہیں اور اسپیس بار نیچے چھلانگ لگاتا ہے وہ رویے جو آپ نہیں چاہتے جب کوئی اپنا خلائی جہاز چلا رہا ہو۔

ہم ان ڈیفالٹ رویوں کو روک سکتے ہیں اور اپنے کھیل کو ان پٹ کو سنبھالنے دے سکتے ہیں۔ یہ اسی طرح ہے جیسے ابتدائی کمپیوٹر پروگرامرز کو کسٹم رویے بنانے کے لیے سسٹم انٹرپٹس کو اووررائیڈ کرنا پڑتا تھا ہم صرف براؤزر لیول پر ایسا کر رہے ہیں۔ یہ کیسے کریں:

const onKeyDown = function (e) {
  console.log(e.keyCode);
  switch (e.keyCode) {
    case 37:
    case 39:
    case 38:
    case 40: // Arrow keys
    case 32:
      e.preventDefault();
      break; // Space
    default:
      break; // do not block other keys
  }
};

window.addEventListener('keydown', onKeyDown);

اس روک تھام کے کوڈ کو سمجھنا:

  • مخصوص کلید کوڈز کے لیے چیک کرتا ہے جو ناپسندیدہ براؤزر رویے کا سبب بن سکتے ہیں
  • تیر کی کلیدوں اور اسپیس بار کے لیے ڈیفالٹ براؤزر ایکشن کو روکتا ہے
  • دوسری کلیدوں کو عام طور پر کام کرنے دیتا ہے
  • e.preventDefault() استعمال کرتا ہے تاکہ براؤزر کے اندرونی رویے کو روکا جا سکے

کھیل کی طرف سے پیدا کردہ حرکت

اب بات کرتے ہیں ان اشیاء کی جو کھلاڑی کے ان پٹ کے بغیر حرکت کرتی ہیں۔ دشمن کے جہازوں کے اسکرین پر چلنے، سیدھی لائنوں میں گولیاں چلنے، یا پس منظر میں بادلوں کے بہنے کے بارے میں سوچیں۔ یہ خود مختار حرکت آپ کے کھیل کی دنیا کو زندہ محسوس کراتی ہے چاہے کوئی کنٹرولز کو نہ چھو رہا ہو۔

ہم جاوا اسکرپٹ کے اندرونی ٹائمرز کا استعمال کرتے ہیں تاکہ پوزیشنز کو باقاعدہ وقفوں پر اپ ڈیٹ کیا جا سکے۔ یہ تصور اسی طرح ہے جیسے پینڈولم گھڑیاں کام کرتی ہیں ایک باقاعدہ میکانزم جو مستقل، وقت شدہ اعمال کو متحرک کرتا ہے۔ یہ کتنا آسان ہو سکتا ہے:

const id = setInterval(() => {
  // Move the enemy on the y axis
  enemy.y += 10;
}, 100);

یہ حرکت کا کوڈ کیا کرتا ہے:

  • ایک ٹimer بناتا ہے جو ہر 100 ملی سیکنڈز پر چلتا ہے
  • دشمن کے y-کوآرڈینیٹ کو ہر بار 10 پکسلز سے اپ ڈیٹ کرتا ہے
  • وقفہ ID کو محفوظ کرتا ہے تاکہ ہم اسے بعد میں روک سکیں اگر ضرورت ہو
  • دشمن کو خود بخود اسکرین پر نیچے کی طرف حرکت دیتا ہے

کھیل کا لوپ

یہ وہ تصور ہے جو سب کچھ ایک ساتھ جوڑتا ہے کھیل کا لوپ۔ اگر آپ کا کھیل ایک فلم ہوتا، تو کھیل کا لوپ فلم پروجیکٹر ہوتا، جو فریم کے بعد فریم دکھاتا تاکہ سب کچھ ہموار حرکت کرتا ہوا نظر آئے۔

ہر کھیل کے پیچھے ایک ایسا لوپ چل رہا ہوتا ہے۔ یہ ایک فنکشن ہے جو تمام کھیل کی اشیاء کو اپ ڈیٹ کرتا ہے، اسکرین کو دوبارہ بناتا ہے، اور اس عمل کو مسلسل دہراتا ہے۔ یہ آپ کے ہیرو، تمام دشمنوں، کسی بھی لیزر کے ارد گرد اڑنے پورے کھیل کی حالت کو ٹریک کرتا ہے۔

یہ تصور مجھے یاد دلاتا ہے کہ ابتدائی فلم کے اینیمیٹرز جیسے والٹ ڈزنی کو کرداروں کو فریم بہ فریم دوبارہ بنانا پڑتا تھا تاکہ حرکت کا وہم پیدا ہو۔ ہم بھی یہی کر رہے ہیں، بس کوڈ کے ساتھ پنسل کے بجائے۔

یہاں ایک کھیل کا لوپ عام طور پر کوڈ میں کیسے نظر آ سکتا ہے:

const gameLoopId = setInterval(() => {
  function gameLoop() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "black";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    drawHero();
    drawEnemies();
    drawStaticObjects();
  }
  gameLoop();
}, 200);

کھیل کے لوپ کی ساخت کو سمجھنا:

  • پورے کینوس کو صاف کرتا ہے تاکہ پچھلا فریم ہٹایا جا سکے
  • پس منظر کو ایک ٹھوس رنگ سے بھر دیتا ہے
  • تمام کھیل کی اشیاء کو ان کی موجودہ پوزیشنز میں دوبارہ بناتا ہے
  • اس عمل کو ہر 200 ملی سیکنڈز میں دہراتا ہے تاکہ ہموار اینیمیشن بن سکے
  • فریم ریٹ کو منظم کرتا ہے وقفہ کے وقت کو کنٹرول کر کے

خلائی کھیل کو جاری رکھنا

اب ہم اس جامد منظر میں حرکت شامل کریں گے جو آپ نے پہلے بنایا تھا۔ ہم اسے اسکرین شاٹ سے ایک انٹرایکٹو تجربے میں تبدیل کرنے جا رہے ہیں۔ ہم اس پر قدم بہ قدم کام کریں گے تاکہ ہر حصہ آخری پر تعمیر ہو۔

پچھلے سبق میں جہاں ہم نے چھوڑا تھا وہاں سے کوڈ حاصل کریں (یا اگر آپ کو نئی شروعات کی ضرورت ہو تو حصہ II- اسٹارٹر فولڈر میں کوڈ سے شروع کریں)۔

آج ہم کیا بنا رہے ہیں:

  • ہیرو کنٹرولز: تیر کی کلیدیں آپ کے خلائی جہاز کو اسکرین پر چلائیں گی
  • دشمن کی حرکت: وہ اجنبی جہاز اپنی پیش قدمی شروع کریں گے

آئیے ان خصوصیات کو نافذ کرنا شروع کریں۔

تجویز کردہ مراحل

ان فائلوں کو تلاش کریں جو آپ کے لیے your-work سب فولڈر میں بنائی گئی ہیں۔ اس میں درج ذیل شامل ہونا چاہیے:

-| assets
  -| enemyShip.png
  -| player.png
-| index.html
-| app.js
-| package.json

آپ اپنے پروجیکٹ کو your-work فولڈر میں شروع کریں گے:

cd your-work
npm start

یہ کمانڈ کیا کرتی ہے:

  • آپ کے پروجیکٹ ڈائریکٹری میں جاتی ہے
  • ایچ ٹی ٹی پی سرور شروع کرتی ہے ایڈریس http://localhost:5000 پر
  • آپ کے کھیل کی فائلوں کو پیش کرتی ہے تاکہ آپ انہیں براؤزر میں ٹیسٹ کر سکیں

اوپر دی گئی کمانڈ ایڈریس http://localhost:5000 پر ایچ ٹی ٹی پی سرور شروع کرے گی۔ براؤزر کھولیں اور اس ایڈریس کو درج کریں، اس وقت یہ ہیرو اور تمام دشمنوں کو ظاہر کرے گا؛ ابھی کچھ حرکت نہیں ہو رہی ہے!

کوڈ شامل کریں

  1. ہیرو، دشمن، اور کھیل کی اشیاء کے لیے مخصوص آبجیکٹس شامل کریں، ان میں x اور y پراپرٹیز ہونی چاہئیں۔ (یاد رکھیں وراثت یا کمپوزیشن کے حصے پر)

    اشارہ کھیل کی اشیاء وہ ہونی چاہیے جس میں x اور y ہوں اور خود کو کینوس پر ڈرا کرنے کی صلاحیت ہو۔

    ٹپ: ایک نیا GameObject کلاس شامل کریں جس کا کنسٹرکٹر نیچے دیے گئے طریقے سے بیان کیا گیا ہو، اور پھر اسے کینوس پر ڈرا کریں:

    class GameObject {
      constructor(x, y) {
        this.x = x;
        this.y = y;
        this.dead = false;
        this.type = "";
        this.width = 0;
        this.height = 0;
        this.img = undefined;
      }
    
      draw(ctx) {
        ctx.drawImage(this.img, this.x, this.y, this.width, this.height);
      }
    }
    

    اس بنیادی کلاس کو سمجھنا:

    • عام پراپرٹیز کی وضاحت کرتا ہے جو تمام کھیل کی اشیاء میں مشترک ہیں (پوزیشن، سائز، تصویر)
    • ایک dead فلیگ شامل کرتا ہے تاکہ ٹریک کیا جا سکے کہ آیا آبجیکٹ کو ہٹایا جانا چاہیے
    • ایک draw() طریقہ فراہم کرتا ہے جو آبجیکٹ کو کینوس پر رینڈر کرتا ہے
    • تمام پراپرٹیز کے لیے ڈیفالٹ ویلیوز سیٹ کرتا ہے جنہیں چائلڈ کلاسز اووررائیڈ کر سکتی ہیں

    اب، اس GameObject کو بڑھا کر Hero اور Enemy بنائیں:

    class Hero extends GameObject {
      constructor(x, y) {
        super(x, y);
        this.width = 98;
        this.height = 75;
        this.type = "Hero";
        this.speed = 5;
      }
    }
    
    class Enemy extends GameObject {
      constructor(x, y) {
        super(x, y);
        this.width = 98;
        this.height = 50;
        this.type = "Enemy";
        const id = setInterval(() => {
          if (this.y < canvas.height - this.height) {
            this.y += 5;
          } else {
            console.log('Stopped at', this.y);
            clearInterval(id);
          }
        }, 300);
      }
    }
    

    ان کلاسز میں کلیدی تصورات:

    • GameObject سے وراثت حاصل کرتا ہے extends کلیدی لفظ استعمال کر کے
    • پیرنٹ کنسٹرکٹر کو super(x, y) کے ساتھ کال کرتا ہے
    • ہر آبجیکٹ کی قسم کے لیے مخصوص ڈائمینشنز اور پراپرٹیز سیٹ کرتا ہے
    • دشمنوں کے لیے خودکار حرکت نافذ کرتا ہے setInterval() استعمال کر کے
  2. کلید کے ایونٹ ہینڈلرز شامل کریں تاکہ کلید کی نیویگیشن کو ہینڈل کیا جا سکے (ہیرو کو اوپر/نیچے، بائیں/دائیں حرکت دیں)

    یاد رکھیں یہ ایک کارٹیسیئن سسٹم ہے، اوپر-بائیں 0,0 ہے۔ نیز، ڈیفالٹ رویے کو روکنے کے لیے کوڈ شامل کرنا یاد رکھیں۔

    ٹپ: اپنا onKeyDown فنکشن بنائیں اور اسے ونڈو سے منسلک کریں:

    const onKeyDown = function (e) {
      console.log(e.keyCode);
      // Add the code from the lesson above to stop default behavior
      switch (e.keyCode) {
        case 37:
        case 39:
        case 38:
        case 40: // Arrow keys
        case 32:
          e.preventDefault();
          break; // Space
        default:
          break; // do not block other keys
      }
    };
    
    window.addEventListener("keydown", onKeyDown);
    

    یہ ایونٹ ہینڈلر کیا کرتا ہے:

    • پوری ونڈو پر کلید کے دبانے کے ایونٹس سنتا ہے
    • کلید کوڈ کو لاگ کرتا ہے تاکہ آپ دیکھ سکیں کون سی کلیدیں دبائی جا رہی ہیں
    • تیر کی کلیدوں اور اسپیس بار کے لیے ڈیفالٹ براؤزر رویے کو روکتا ہے
    • دوسری کلیدوں کو عام طور پر کام کرنے دیتا ہے

    اس وقت اپنے براؤزر کنسول کو چیک کریں، اور دیکھیں کہ کلید کے دبانے لاگ ہو رہے ہیں۔

  3. پب سب پیٹرن نافذ کریں، یہ آپ کے کوڈ کو صاف رکھے گا جیسے آپ باقی حصے پر عمل کریں گے۔

    پبلش-سبسکرائب پیٹرن آپ کے کوڈ کو منظم کرنے میں مدد کرتا ہے ایونٹ کا پتہ لگانے کو ایونٹ ہینڈلنگ سے الگ کر کے۔ یہ آپ کے کوڈ کو زیادہ ماڈیولر اور برقرار رکھنے میں آسان بناتا ہے۔

    اس آخری حصے کو کرنے کے لیے، آپ کر سکتے ہیں:

    1. ونڈو پر ایک ایونٹ لسٹنر شامل کریں:

      window.addEventListener("keyup", (evt) => {
        if (evt.key === "ArrowUp") {
          eventEmitter.emit(Messages.KEY_EVENT_UP);
        } else if (evt.key === "ArrowDown") {
          eventEmitter.emit(Messages.KEY_EVENT_DOWN);
        } else if (evt.key === "ArrowLeft") {
          eventEmitter.emit(Messages.KEY_EVENT_LEFT);
        } else if (evt.key === "ArrowRight") {
          eventEmitter.emit(Messages.KEY_EVENT_RIGHT);
        }
      });
      

    یہ ایونٹ سسٹم کیا کرتا ہے:

    • کی بورڈ ان پٹ کا پتہ لگاتا ہے اور اسے کسٹم کھیل کے ایونٹس میں تبدیل کرتا ہے
    • ان پٹ کا پتہ لگانے کو کھیل کی منطق سے الگ کرتا ہے
    • کنٹرولز کو بعد میں تبدیل کرنا آسان بناتا ہے بغیر کھیل کے کوڈ کو متاثر کیے
    • متعدد سسٹمز کو ایک ہی ان پٹ پر ردعمل دینے کی اجازت دیتا ہے
    1. ایک EventEmitter کلاس بنائیں تاکہ پیغامات کو پبلش اور سبسکرائب کیا جا سکے:

      class EventEmitter {
        constructor() {
          this.listeners = {};
        }
      
        on(message, listener) {
          if (!this.listeners[message]) {
            this.listeners[message] = [];
          }
          this.listeners[message].push(listener);
        }
      
      
    2. کانسٹینٹس شامل کریں اور EventEmitter سیٹ کریں:

      const Messages = {
        KEY_EVENT_UP: "KEY_EVENT_UP",
        KEY_EVENT_DOWN: "KEY_EVENT_DOWN",
        KEY_EVENT_LEFT: "KEY_EVENT_LEFT",
        KEY_EVENT_RIGHT: "KEY_EVENT_RIGHT",
      };
      
      let heroImg, 
          enemyImg, 
          laserImg,
          canvas, ctx, 
          gameObjects = [], 
          hero, 
          eventEmitter = new EventEmitter();
      

    سیٹ اپ کو سمجھنا:

    • پیغام کے کانسٹینٹس کی وضاحت کرتا ہے تاکہ ٹائپوز سے بچا جا سکے اور ریفیکٹرنگ کو آسان بنایا جا سکے
    • **تصاویر، کینوس کنٹیکسٹ، اور کھیل کی حالت کے
  • بناتا ہے دشمنوں کی ایک گرڈ nested loops کے ذریعے
  • تفویض کرتا ہے دشمن کی تصویر ہر دشمن object کو
  • شامل کرتا ہے ہر دشمن کو global game objects array میں

اور ایک createHero() فنکشن شامل کریں جو ہیرو کے لیے اسی طرح کا عمل کرے۔

```javascript
function createHero() {
  hero = new Hero(
    canvas.width / 2 - 45,
    canvas.height - canvas.height / 4
  );
  hero.img = heroImg;
  gameObjects.push(hero);
}
```

ہیرو کی تخلیق کیا کرتی ہے:

  • پوزیشن کرتا ہے ہیرو کو اسکرین کے نیچے مرکز میں
  • تفویض کرتا ہے ہیرو کی تصویر ہیرو object کو
  • شامل کرتا ہے ہیرو کو game objects array میں rendering کے لیے

اور آخر میں، ایک drawGameObjects() فنکشن شامل کریں تاکہ drawing شروع کی جا سکے:

```javascript
function drawGameObjects(ctx) {
  gameObjects.forEach(go => go.draw(ctx));
}
```

drawing فنکشن کو سمجھنا:

  • Iterates کرتا ہے تمام game objects array میں
  • Calls کرتا ہے draw() method ہر object پر
  • پاس کرتا ہے canvas context تاکہ objects خود کو render کر سکیں

آپ کے دشمن آپ کے ہیرو spaceship پر حملہ شروع کر دیں گے!
}
}
```

and add a `createHero()` function to do a similar process for the hero.

```javascript
function createHero() {
  hero = new Hero(
    canvas.width / 2 - 45,
    canvas.height - canvas.height / 4
  );
  hero.img = heroImg;
  gameObjects.push(hero);
}
```

اور آخر میں، ایک drawGameObjects() فنکشن شامل کریں تاکہ drawing شروع کی جا سکے:

```javascript
function drawGameObjects(ctx) {
  gameObjects.forEach(go => go.draw(ctx));
}
```

آپ کے دشمن آپ کے ہیرو spaceship پر حملہ شروع کر دیں گے!


GitHub Copilot Agent Challenge 🚀

یہاں ایک چیلنج ہے جو آپ کے گیم کی polish کو بہتر بنائے گا: boundaries اور smooth controls شامل کرنا۔ فی الحال، آپ کا ہیرو اسکرین سے باہر جا سکتا ہے، اور حرکت تھوڑی بے ترتیب محسوس ہو سکتی ہے۔

آپ کا مشن: اپنے spaceship کو زیادہ حقیقت پسندانہ بنائیں boundaries اور fluid movement کو نافذ کر کے۔ یہ بالکل ویسا ہی ہے جیسے NASA کے flight control systems spacecraft کو محفوظ operational parameters سے تجاوز کرنے سے روکتے ہیں۔

یہ بنائیں: ایک ایسا نظام جو آپ کے ہیرو spaceship کو اسکرین پر رکھے، اور controls کو smooth بنائے۔ جب کھلاڑی arrow key کو دبائے رکھیں، تو ship کو مسلسل glide کرنا چاہیے بجائے discrete steps میں حرکت کرنے کے۔ اسکرین boundaries پر پہنچنے پر visual feedback شامل کرنے پر غور کریں شاید play area کے edge کو ظاہر کرنے کے لیے ایک subtle effect۔

agent mode کے بارے میں مزید جانیں۔

🚀 Challenge

جیسے جیسے پروجیکٹس بڑھتے ہیں، code organization زیادہ اہم ہو جاتی ہے۔ آپ نے محسوس کیا ہوگا کہ آپ کی فائل functions، variables، اور classes کے ساتھ بھری ہوئی ہے۔ یہ بالکل ویسا ہی ہے جیسے Apollo mission کے engineers کو code کو واضح اور قابل انتظام بنانے کے لیے systems بنانا پڑے جن پر مختلف teams ایک ساتھ کام کر سکیں۔

آپ کا مشن:
ایک software architect کی طرح سوچیں۔ آپ اپنے code کو کیسے organize کریں گے تاکہ چھ مہینے بعد، آپ (یا کوئی teammate) سمجھ سکے کہ کیا ہو رہا ہے؟ چاہے سب کچھ ابھی ایک فائل میں رہے، آپ بہتر organization بنا سکتے ہیں:

  • متعلقہ functions کو گروپ کرنا واضح comment headers کے ساتھ
  • Concerns کو الگ کرنا - game logic کو rendering سے الگ رکھیں
  • Consistent naming conventions کا استعمال variables اور functions کے لیے
  • Modules یا namespaces بنانا تاکہ گیم کے مختلف پہلوؤں کو organize کیا جا سکے
  • Documentation شامل کرنا جو ہر بڑے section کے مقصد کو بیان کرے

Reflection سوالات:

  • آپ کے code کے کون سے حصے سب سے زیادہ مشکل ہیں جب آپ ان پر واپس آتے ہیں؟
  • آپ اپنے code کو کیسے organize کر سکتے ہیں تاکہ کسی اور کے لیے contribute کرنا آسان ہو؟
  • اگر آپ نئے features جیسے power-ups یا مختلف دشمن types شامل کرنا چاہیں تو کیا ہوگا؟

Post-Lecture Quiz

Post-lecture quiz

Review & Self Study

ہم سب کچھ شروع سے بنا رہے ہیں، جو سیکھنے کے لیے شاندار ہے، لیکن یہاں ایک چھوٹا راز ہے کچھ حیرت انگیز JavaScript frameworks موجود ہیں جو آپ کے لیے بہت سا کام آسان بنا سکتے ہیں۔ جب آپ ان بنیادی اصولوں میں آرام دہ محسوس کریں جو ہم نے cover کیے ہیں، تو یہ دستیاب چیزوں کو explore کرنے کے قابل ہے۔

Frameworks کو ایسے سمجھیں جیسے آپ کے پاس ایک اچھی طرح سے stocked toolbox ہو بجائے ہر tool کو خود بنانے کے۔ وہ ان code organization challenges کو حل کر سکتے ہیں جن کے بارے میں ہم نے بات کی، اور ایسے features پیش کر سکتے ہیں جنہیں خود بنانے میں ہفتے لگ جائیں گے۔

Explore کرنے کے قابل چیزیں:

  • گیم engines code کو کیسے organize کرتے ہیں آپ ان کے clever patterns سے حیران ہوں گے
  • Performance tricks تاکہ canvas games butter-smooth چلیں
  • Modern JavaScript features جو آپ کے code کو صاف اور زیادہ maintainable بنا سکتے ہیں
  • گیم objects اور ان کے تعلقات کو manage کرنے کے مختلف طریقے

Assignment

Comment your code


اعلانِ لاتعلقی:
یہ دستاویز AI ترجمہ سروس Co-op Translator کا استعمال کرتے ہوئے ترجمہ کی گئی ہے۔ ہم درستگی کے لیے کوشش کرتے ہیں، لیکن براہ کرم آگاہ رہیں کہ خودکار ترجمے میں غلطیاں یا غیر درستیاں ہو سکتی ہیں۔ اصل دستاویز کو اس کی اصل زبان میں مستند ذریعہ سمجھا جانا چاہیے۔ اہم معلومات کے لیے، پیشہ ور انسانی ترجمہ کی سفارش کی جاتی ہے۔ اس ترجمے کے استعمال سے پیدا ہونے والی کسی بھی غلط فہمی یا غلط تشریح کے لیے ہم ذمہ دار نہیں ہیں۔