|
3 weeks ago | |
---|---|---|
.. | ||
README.md | 3 weeks ago | |
assignment.md | 4 weeks ago |
README.md
اسپیس گیم بنائیں حصہ 3: حرکت شامل کریں
لیکچر سے پہلے کا کوئز
گیمز تب تک زیادہ مزے کے نہیں ہوتے جب تک اسکرین پر ایلینز حرکت نہ کر رہے ہوں! اس گیم میں ہم دو قسم کی حرکتوں کا استعمال کریں گے:
- کی بورڈ/ماؤس حرکت: جب صارف کی بورڈ یا ماؤس کے ذریعے اسکرین پر کسی آبجیکٹ کو حرکت دیتا ہے۔
- گیم کی طرف سے حرکت: جب گیم کسی آبجیکٹ کو ایک خاص وقت کے وقفے سے حرکت دیتا ہے۔
تو اسکرین پر چیزوں کو کیسے حرکت دی جائے؟ یہ سب کارٹیزین کوآرڈینیٹس کے بارے میں ہے: ہم آبجیکٹ کی جگہ (x, y) کو تبدیل کرتے ہیں اور پھر اسکرین کو دوبارہ ڈرا کرتے ہیں۔
عام طور پر اسکرین پر حرکت کو مکمل کرنے کے لیے آپ کو درج ذیل مراحل کی ضرورت ہوتی ہے:
- آبجیکٹ کے لیے نئی جگہ مقرر کریں؛ یہ ضروری ہے تاکہ آبجیکٹ کی حرکت محسوس ہو۔
- اسکرین صاف کریں، ڈرا کے درمیان اسکرین کو صاف کرنا ضروری ہے۔ ہم اسے ایک مستطیل ڈرا کرکے صاف کر سکتے ہیں جسے ہم بیک گراؤنڈ کلر سے بھرتے ہیں۔
- آبجیکٹ کو نئی جگہ پر دوبارہ ڈرا کریں۔ ایسا کرنے سے ہم آخر کار آبجیکٹ کو ایک جگہ سے دوسری جگہ منتقل کرنے میں کامیاب ہو جاتے ہیں۔
یہ کوڈ میں کچھ اس طرح نظر آ سکتا ہے:
//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);
✅ کیا آپ سوچ سکتے ہیں کہ آپ کے ہیرو کو فی سیکنڈ کئی فریمز پر دوبارہ ڈرا کرنے سے پرفارمنس پر کیا اثر پڑ سکتا ہے؟ اس پیٹرن کے متبادل کے بارے میں پڑھیں۔
کی بورڈ ایونٹس کو ہینڈل کریں
آپ ایونٹس کو مخصوص کوڈ کے ساتھ منسلک کرکے ہینڈل کرتے ہیں۔ کی بورڈ ایونٹس پورے ونڈو پر ٹرگر ہوتے ہیں جبکہ ماؤس ایونٹس جیسے click
کسی خاص عنصر پر کلک کرنے سے منسلک ہو سکتے ہیں۔ ہم اس پروجیکٹ میں کی بورڈ ایونٹس کا استعمال کریں گے۔
ایونٹ کو ہینڈل کرنے کے لیے آپ کو ونڈو کے addEventListener()
میتھڈ کا استعمال کرنا ہوگا اور اسے دو ان پٹ پیرامیٹرز فراہم کرنے ہوں گے۔ پہلا پیرامیٹر ایونٹ کا نام ہے، مثلاً keyup
۔ دوسرا پیرامیٹر وہ فنکشن ہے جو ایونٹ ہونے کے نتیجے میں کال کیا جائے گا۔
یہاں ایک مثال ہے:
window.addEventListener('keyup', (evt) => {
// `evt.key` = string representation of the key
if (evt.key === 'ArrowUp') {
// do something
}
})
کی ایونٹس کے لیے ایونٹ پر دو پراپرٹیز ہیں جنہیں آپ دیکھ سکتے ہیں کہ کون سی کی دبائی گئی:
key
، یہ دبائی گئی کی کی ایک اسٹرنگ نمائندگی ہے، مثلاًArrowUp
keyCode
، یہ ایک عددی نمائندگی ہے، مثلاً37
، جوArrowLeft
کے مطابق ہے۔
✅ کی ایونٹ مینیپولیشن گیم ڈیولپمنٹ کے علاوہ بھی مفید ہے۔ اس تکنیک کے اور کیا استعمالات ہو سکتے ہیں؟
خاص کیز: ایک انتباہ
کچھ خاص کیز ہیں جو ونڈو کو متاثر کرتی ہیں۔ اس کا مطلب ہے کہ اگر آپ keyup
ایونٹ سن رہے ہیں اور ان خاص کیز کا استعمال اپنے ہیرو کو حرکت دینے کے لیے کرتے ہیں تو یہ افقی اسکرولنگ بھی کرے گا۔ اس وجہ سے آپ گیم بناتے وقت اس بلٹ ان براؤزر رویے کو بند کرنا چاہیں گے۔ آپ کو اس طرح کا کوڈ درکار ہوگا:
let 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()
کو کال کرتے ہیں۔
گیم کی طرف سے حرکت
ہم چیزوں کو خود بخود حرکت دے سکتے ہیں جیسے setTimeout()
یا setInterval()
فنکشن کا استعمال کرکے جو ہر ٹک یا وقت کے وقفے پر آبجیکٹ کی جگہ کو اپ ڈیٹ کرتا ہے۔ یہ کچھ اس طرح نظر آ سکتا ہے:
let id = setInterval(() => {
//move the enemy on the y axis
enemy.y += 10;
})
گیم لوپ
گیم لوپ ایک تصور ہے جو بنیادی طور پر ایک فنکشن ہے جو باقاعدہ وقفوں پر کال کیا جاتا ہے۔ اسے گیم لوپ کہا جاتا ہے کیونکہ جو کچھ بھی صارف کو نظر آنا چاہیے وہ لوپ میں ڈرا کیا جاتا ہے۔ گیم لوپ گیم کے تمام آبجیکٹس کا استعمال کرتا ہے جو گیم کا حصہ ہیں، ان سب کو ڈرا کرتا ہے جب تک کہ کسی وجہ سے وہ گیم کا حصہ نہ رہیں۔ مثال کے طور پر، اگر کوئی آبجیکٹ ایک دشمن ہے جسے لیزر نے مارا اور وہ پھٹ گیا، تو وہ موجودہ گیم لوپ کا حصہ نہیں رہتا (آپ اس کے بارے میں مزید اگلے اسباق میں سیکھیں گے)۔
یہاں گیم لوپ عام طور پر کوڈ میں کچھ اس طرح نظر آ سکتا ہے:
let 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();
}, 200);
اوپر دیا گیا لوپ ہر 200
ملی سیکنڈز میں کینوس کو دوبارہ ڈرا کرنے کے لیے کال کیا جاتا ہے۔ آپ کے پاس اپنے گیم کے لیے موزوں وقفہ منتخب کرنے کی صلاحیت ہے۔
اسپیس گیم جاری رکھیں
آپ موجودہ کوڈ کو لیں گے اور اسے بڑھائیں گے۔ یا تو اس کوڈ سے شروع کریں جو آپ نے حصہ I کے دوران مکمل کیا تھا یا حصہ II- اسٹارٹر میں موجود کوڈ کا استعمال کریں۔
- ہیرو کو حرکت دینا: آپ کوڈ شامل کریں گے تاکہ آپ ایرو کیز کا استعمال کرتے ہوئے ہیرو کو حرکت دے سکیں۔
- دشمنوں کو حرکت دینا: آپ کوڈ شامل کریں گے تاکہ دشمن اوپر سے نیچے ایک خاص رفتار سے حرکت کریں۔
تجویز کردہ مراحل
your-work
سب فولڈر میں بنائی گئی فائلوں کو تلاش کریں۔ اس میں درج ذیل شامل ہونا چاہیے:
-| assets
-| enemyShip.png
-| player.png
-| index.html
-| app.js
-| package.json
آپ اپنے پروجیکٹ کو your_work
فولڈر میں درج ذیل کمانڈ کے ذریعے شروع کریں:
cd your-work
npm start
اوپر دیا گیا کمانڈ ایچ ٹی ٹی پی سرور کو ایڈریس http://localhost:5000
پر شروع کرے گا۔ ایک براؤزر کھولیں اور اس ایڈریس کو درج کریں، اس وقت یہ ہیرو اور تمام دشمنوں کو رینڈر کرے گا؛ ابھی کچھ حرکت نہیں کر رہا - ابھی!
کوڈ شامل کریں
-
ہیرو، دشمن، اور گیم آبجیکٹ کے لیے مخصوص آبجیکٹس شامل کریں، ان میں
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); } }
اب، اس GameObject کو بڑھا کر ہیرو اور دشمن بنائیں۔
class Hero extends GameObject { constructor(x, y) { ...it needs an x, y, type, and speed } }
class Enemy extends GameObject { constructor(x, y) { super(x, y); (this.width = 98), (this.height = 50); this.type = "Enemy"; let id = setInterval(() => { if (this.y < canvas.height - this.height) { this.y += 5; } else { console.log('Stopped at', this.y) clearInterval(id); } }, 300) } }
-
کی ایونٹ ہینڈلرز شامل کریں تاکہ کی نیویگیشن کو ہینڈل کیا جا سکے (ہیرو کو اوپر/نیچے، بائیں/دائیں حرکت دیں)
یاد رکھیں: یہ ایک کارٹیزین سسٹم ہے، اوپر بائیں
0,0
ہے۔ ڈیفالٹ رویے کو بند کرنے کے لیے کوڈ شامل کرنا بھی یاد رکھیں۔ٹپ: اپنا onKeyDown فنکشن بنائیں اور اسے ونڈو سے منسلک کریں:
let onKeyDown = function (e) { console.log(e.keyCode); ...add the code from the lesson above to stop default behavior } }; window.addEventListener("keydown", onKeyDown);
اس مقام پر اپنے براؤزر کنسول کو چیک کریں، اور دیکھیں کہ کی اسٹروکس لاگ ہو رہے ہیں۔
-
پب سب پیٹرن کو نافذ کریں، یہ آپ کے کوڈ کو صاف رکھے گا جب آپ باقی حصے مکمل کریں گے۔
اس آخری حصے کو کرنے کے لیے، آپ:
-
ونڈو پر ایک ایونٹ لسٹنر شامل کریں:
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); } });
-
ایک EventEmitter کلاس بنائیں تاکہ پیغامات کو پبلش اور سبسکرائب کیا جا سکے:
class EventEmitter { constructor() { this.listeners = {}; } on(message, listener) { if (!this.listeners[message]) { this.listeners[message] = []; } this.listeners[message].push(listener); } emit(message, payload = null) { if (this.listeners[message]) { this.listeners[message].forEach((l) => l(message, payload)); } } }
-
کانسٹنٹس شامل کریں اور 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();
-
گیم کو انیشیالائز کریں
function initGame() { gameObjects = []; createEnemies(); createHero(); eventEmitter.on(Messages.KEY_EVENT_UP, () => { hero.y -=5 ; }) eventEmitter.on(Messages.KEY_EVENT_DOWN, () => { hero.y += 5; }); eventEmitter.on(Messages.KEY_EVENT_LEFT, () => { hero.x -= 5; }); eventEmitter.on(Messages.KEY_EVENT_RIGHT, () => { hero.x += 5; }); }
-
-
گیم لوپ سیٹ اپ کریں
ونڈو.onload فنکشن کو ریفیکٹر کریں تاکہ گیم کو انیشیالائز کیا جا سکے اور ایک اچھے وقفے پر گیم لوپ سیٹ اپ کیا جا سکے۔ آپ ایک لیزر بیم بھی شامل کریں گے:
window.onload = async () => { canvas = document.getElementById("canvas"); ctx = canvas.getContext("2d"); heroImg = await loadTexture("assets/player.png"); enemyImg = await loadTexture("assets/enemyShip.png"); laserImg = await loadTexture("assets/laserRed.png"); initGame(); let gameLoopId = setInterval(() => { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "black"; ctx.fillRect(0, 0, canvas.width, canvas.height); drawGameObjects(ctx); }, 100) };
-
دشمنوں کو ایک خاص وقفے پر حرکت دینے کے لیے کوڈ شامل کریں
createEnemies()
فنکشن کو ریفیکٹر کریں تاکہ دشمنوں کو بنایا جا سکے اور انہیں نئے gameObjects کلاس میں دھکیلا جا سکے:function createEnemies() { const MONSTER_TOTAL = 5; const MONSTER_WIDTH = MONSTER_TOTAL * 98; const START_X = (canvas.width - MONSTER_WIDTH) / 2; const STOP_X = START_X + MONSTER_WIDTH; for (let x = START_X; x < STOP_X; x += 98) { for (let y = 0; y < 50 * 5; y += 50) { const enemy = new Enemy(x, y); enemy.img = enemyImg; gameObjects.push(enemy); } } }
اور ایک
createHero()
فنکشن شامل کریں تاکہ ہیرو کے لیے بھی ایسا ہی عمل کیا جا سکے۔function createHero() { hero = new Hero( canvas.width / 2 - 45, canvas.height - canvas.height / 4 ); hero.img = heroImg; gameObjects.push(hero); }
اور آخر میں، ایک
drawGameObjects()
فنکشن شامل کریں تاکہ ڈرائنگ شروع کی جا سکے:function drawGameObjects(ctx) { gameObjects.forEach(go => go.draw(ctx)); }
آپ کے دشمن آپ کے ہیرو اسپیس شپ پر حملہ کرنا شروع کر دیں گے!
🚀 چیلنج
جیسا کہ آپ دیکھ سکتے ہیں، جب آپ فنکشنز، ویریبلز، اور کلاسز شامل کرتے ہیں تو آپ کا کوڈ 'اسپیگٹی کوڈ' میں تبدیل ہو سکتا ہے۔ آپ اپنے کوڈ کو بہتر طریقے سے منظم کرنے کے لیے کیا کر سکتے ہیں تاکہ یہ زیادہ پڑھنے کے قابل ہو؟ اپنے کوڈ کو منظم کرنے کے لیے ایک نظام کا خاکہ بنائیں، چاہے یہ ابھی بھی ایک فائل میں موجود ہو۔
لیکچر کے بعد کا کوئز
جائزہ اور خود مطالعہ
جبکہ ہم اپنا گیم فریم ورک کے بغیر لکھ رہے ہیں، گیم ڈیولپمنٹ کے لیے بہت سے جاوا اسکرپٹ پر مبنی کینوس فریم ورک موجود ہیں۔ ان کے بارے میں کچھ وقت نکال کر پڑھیں۔
اسائنمنٹ
ڈسکلیمر:
یہ دستاویز AI ترجمہ سروس Co-op Translator کا استعمال کرتے ہوئے ترجمہ کی گئی ہے۔ ہم درستگی کے لیے کوشش کرتے ہیں، لیکن براہ کرم آگاہ رہیں کہ خودکار ترجمے میں غلطیاں یا غیر درستیاں ہو سکتی ہیں۔ اصل دستاویز کو اس کی اصل زبان میں مستند ذریعہ سمجھا جانا چاہیے۔ اہم معلومات کے لیے، پیشہ ور انسانی ترجمہ کی سفارش کی جاتی ہے۔ ہم اس ترجمے کے استعمال سے پیدا ہونے والی کسی بھی غلط فہمی یا غلط تشریح کے ذمہ دار نہیں ہیں۔