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.
463 lines
22 KiB
463 lines
22 KiB
<!--
|
|
CO_OP_TRANSLATOR_METADATA:
|
|
{
|
|
"original_hash": "4b1d441cfd31924084956000c0fee5a5",
|
|
"translation_date": "2025-10-22T14:27:18+00:00",
|
|
"source_file": "6-space-game/4-collision-detection/README.md",
|
|
"language_code": "ar"
|
|
}
|
|
-->
|
|
# بناء لعبة فضاء الجزء 4: إضافة الليزر واكتشاف التصادمات
|
|
|
|
## اختبار ما قبل المحاضرة
|
|
|
|
[اختبار ما قبل المحاضرة](https://ff-quizzes.netlify.app/web/quiz/35)
|
|
|
|
تذكر لحظة في فيلم "حرب النجوم" عندما أصابت قذائف البروتون الخاصة بلوك منفذ العادم في نجمة الموت. هذا الكشف الدقيق للتصادم غيّر مصير المجرة! في الألعاب، يعمل اكتشاف التصادم بنفس الطريقة - فهو يحدد متى تتفاعل الأشياء وما الذي يحدث بعد ذلك.
|
|
|
|
في هذه الدرس، ستضيف أسلحة الليزر إلى لعبة الفضاء الخاصة بك وتنفذ اكتشاف التصادمات. تمامًا مثل مخططي مهام ناسا الذين يحسبون مسارات المركبات الفضائية لتجنب الحطام، ستتعلم كيفية اكتشاف تقاطع الأشياء في اللعبة. سنقسم هذا إلى خطوات يمكن إدارتها تبني على بعضها البعض.
|
|
|
|
في النهاية، سيكون لديك نظام قتال يعمل حيث تدمر الليزرات الأعداء وتؤدي التصادمات إلى أحداث اللعبة. يتم استخدام نفس مبادئ التصادم هذه في كل شيء بدءًا من محاكاة الفيزياء إلى واجهات الويب التفاعلية.
|
|
|
|
✅ قم بإجراء بحث صغير عن أول لعبة كمبيوتر تم كتابتها على الإطلاق. ما هي وظيفتها؟
|
|
|
|
## اكتشاف التصادمات
|
|
|
|
يعمل اكتشاف التصادمات مثل أجهزة استشعار القرب في وحدة الهبوط القمرية أبولو - فهو يتحقق باستمرار من المسافات ويطلق تنبيهات عندما تقترب الأشياء جدًا. في الألعاب، يحدد هذا النظام متى تتفاعل الأشياء وما الذي يجب أن يحدث بعد ذلك.
|
|
|
|
النهج الذي سنستخدمه يعامل كل كائن في اللعبة كأنه مستطيل، مشابهًا للطريقة التي تستخدم بها أنظمة مراقبة الحركة الجوية أشكالًا هندسية مبسطة لتتبع الطائرات. قد يبدو هذا النهج المستطيلي بسيطًا، لكنه فعال من حيث الحساب ويعمل جيدًا لمعظم سيناريوهات الألعاب.
|
|
|
|
### تمثيل المستطيل
|
|
|
|
كل كائن في اللعبة يحتاج إلى حدود إحداثيات، مشابهًا للطريقة التي رسمت بها مركبة المريخ "باثفايندر" موقعها على سطح المريخ. إليك كيفية تعريف هذه الحدود:
|
|
|
|
```javascript
|
|
rectFromGameObject() {
|
|
return {
|
|
top: this.y,
|
|
left: this.x,
|
|
bottom: this.y + this.height,
|
|
right: this.x + this.width
|
|
}
|
|
}
|
|
```
|
|
|
|
**لنقم بتفصيل هذا:**
|
|
- **الحافة العلوية**: هي فقط المكان الذي يبدأ فيه الكائن عموديًا (موضعه y)
|
|
- **الحافة اليسرى**: حيث يبدأ أفقيًا (موضعه x)
|
|
- **الحافة السفلية**: أضف الارتفاع إلى موضع y - الآن تعرف أين ينتهي!
|
|
- **الحافة اليمنى**: أضف العرض إلى موضع x - وستحصل على الحدود الكاملة
|
|
|
|
### خوارزمية التقاطع
|
|
|
|
اكتشاف تقاطع المستطيلات يستخدم منطقًا مشابهًا للطريقة التي يحدد بها تلسكوب هابل الفضائي إذا كانت الأجسام السماوية تتداخل في مجال رؤيته. تتحقق الخوارزمية من الفصل:
|
|
|
|
```javascript
|
|
function intersectRect(r1, r2) {
|
|
return !(r2.left > r1.right ||
|
|
r2.right < r1.left ||
|
|
r2.top > r1.bottom ||
|
|
r2.bottom < r1.top);
|
|
}
|
|
```
|
|
|
|
**اختبار الفصل يعمل مثل أنظمة الرادار:**
|
|
- هل المستطيل 2 بالكامل على يمين المستطيل 1؟
|
|
- هل المستطيل 2 بالكامل على يسار المستطيل 1؟
|
|
- هل المستطيل 2 بالكامل أسفل المستطيل 1؟
|
|
- هل المستطيل 2 بالكامل فوق المستطيل 1؟
|
|
|
|
إذا لم تكن أي من هذه الشروط صحيحة، فلا بد أن المستطيلات تتداخل. هذا النهج يشبه الطريقة التي يحدد بها مشغلو الرادار إذا كانت الطائرتان على مسافات آمنة.
|
|
|
|
## إدارة دورة حياة الكائنات
|
|
|
|
عندما يصيب الليزر العدو، يجب إزالة كلا الكائنين من اللعبة. ومع ذلك، فإن حذف الكائنات أثناء الحلقة يمكن أن يسبب أعطالًا - درس تعلمناه بالطريقة الصعبة في أنظمة الكمبيوتر المبكرة مثل كمبيوتر التوجيه أبولو. بدلاً من ذلك، نستخدم نهج "التحديد للحذف" الذي يزيل الكائنات بأمان بين الإطارات.
|
|
|
|
إليك كيفية تحديد شيء ما للإزالة:
|
|
|
|
```javascript
|
|
// Mark object for removal
|
|
enemy.dead = true;
|
|
```
|
|
|
|
**لماذا يعمل هذا النهج:**
|
|
- نحدد الكائن كـ "ميت" ولكن لا نحذفه على الفور
|
|
- هذا يسمح للإطار الحالي للعبة بالانتهاء بأمان
|
|
- لا توجد أعطال من محاولة استخدام شيء قد تم حذفه بالفعل!
|
|
|
|
ثم نقوم بتصفية الكائنات المحددة قبل دورة العرض التالية:
|
|
|
|
```javascript
|
|
gameObjects = gameObjects.filter(go => !go.dead);
|
|
```
|
|
|
|
**ما الذي تفعله هذه التصفية:**
|
|
- تنشئ قائمة جديدة تحتوي فقط على الكائنات "الحية"
|
|
- تتخلص من أي شيء تم تحديده كميت
|
|
- تحافظ على تشغيل اللعبة بسلاسة
|
|
- تمنع تراكم الذاكرة من الكائنات المدمرة
|
|
|
|
## تنفيذ ميكانيكية الليزر
|
|
|
|
تعمل مقذوفات الليزر في الألعاب على نفس مبدأ قذائف الفوتون في "ستار تريك" - فهي كائنات منفصلة تتحرك في خطوط مستقيمة حتى تصيب شيئًا ما. كل ضغطة على مفتاح المسافة تنشئ كائن ليزر جديد يتحرك عبر الشاشة.
|
|
|
|
لجعل هذا يعمل، نحتاج إلى تنسيق بعض الأجزاء المختلفة:
|
|
|
|
**المكونات الرئيسية للتنفيذ:**
|
|
- **إنشاء** كائنات الليزر التي تنطلق من موضع البطل
|
|
- **التعامل مع** إدخال لوحة المفاتيح لتفعيل إنشاء الليزر
|
|
- **إدارة** حركة الليزر ودورة حياته
|
|
- **تنفيذ** التمثيل البصري لمقذوفات الليزر
|
|
|
|
## تنفيذ التحكم في معدل الإطلاق
|
|
|
|
معدلات الإطلاق غير المحدودة ستثقل محرك اللعبة وتجعل اللعب سهلاً للغاية. تواجه أنظمة الأسلحة الحقيقية قيودًا مشابهة - حتى الفيزرات الخاصة بـ USS Enterprise تحتاج إلى وقت لإعادة الشحن بين الطلقات.
|
|
|
|
سننفذ نظام تبريد يمنع الإطلاق السريع المتكرر مع الحفاظ على التحكم السريع:
|
|
|
|
```javascript
|
|
class Cooldown {
|
|
constructor(time) {
|
|
this.cool = false;
|
|
setTimeout(() => {
|
|
this.cool = true;
|
|
}, time);
|
|
}
|
|
}
|
|
|
|
class Weapon {
|
|
constructor() {
|
|
this.cooldown = null;
|
|
}
|
|
|
|
fire() {
|
|
if (!this.cooldown || this.cooldown.cool) {
|
|
// Create laser projectile
|
|
this.cooldown = new Cooldown(500);
|
|
} else {
|
|
// Weapon is still cooling down
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**كيف يعمل التبريد:**
|
|
- عند الإنشاء، يبدأ السلاح "ساخنًا" (لا يمكن الإطلاق بعد)
|
|
- بعد فترة المهلة، يصبح "باردًا" (جاهز للإطلاق)
|
|
- قبل الإطلاق، نتحقق: "هل السلاح بارد؟"
|
|
- هذا يمنع النقر المتكرر مع الحفاظ على التحكم السريع
|
|
|
|
✅ ارجع إلى الدرس الأول في سلسلة لعبة الفضاء لتذكير نفسك بنظام التبريد.
|
|
|
|
## بناء نظام اكتشاف التصادمات
|
|
|
|
ستقوم بتوسيع كود لعبة الفضاء الحالية لإنشاء نظام اكتشاف التصادمات. مثل نظام تجنب التصادم الآلي لمحطة الفضاء الدولية، ستراقب اللعبة باستمرار مواقع الكائنات وتستجيب للتقاطعات.
|
|
|
|
بدءًا من كود الدرس السابق، ستضيف اكتشاف التصادمات مع قواعد محددة تحكم تفاعلات الكائنات.
|
|
|
|
> 💡 **نصيحة احترافية**: تم تضمين صورة الليزر بالفعل في مجلد الأصول الخاص بك ومشار إليها في الكود الخاص بك، وهي جاهزة للتنفيذ.
|
|
|
|
### قواعد التصادم التي يجب تنفيذها
|
|
|
|
**ميكانيكية اللعبة التي يجب إضافتها:**
|
|
1. **إصابة الليزر للعدو**: يتم تدمير كائن العدو عند ضربه بمقذوف الليزر
|
|
2. **إصابة الليزر لحدود الشاشة**: يتم إزالة الليزر عند وصوله إلى الحافة العلوية للشاشة
|
|
3. **تصادم العدو والبطل**: يتم تدمير كلا الكائنين عند تقاطعهما
|
|
4. **وصول العدو إلى الأسفل**: حالة انتهاء اللعبة عندما يصل الأعداء إلى أسفل الشاشة
|
|
|
|
## إعداد بيئة التطوير الخاصة بك
|
|
|
|
خبر سار - لقد قمنا بالفعل بإعداد معظم الأساسيات لك! جميع أصول اللعبة والبنية الأساسية جاهزة في مجلد `your-work`، جاهزة لإضافة ميزات التصادم الرائعة.
|
|
|
|
### هيكل المشروع
|
|
|
|
```bash
|
|
-| assets
|
|
-| enemyShip.png
|
|
-| player.png
|
|
-| laserRed.png
|
|
-| index.html
|
|
-| app.js
|
|
-| package.json
|
|
```
|
|
|
|
**فهم هيكل الملفات:**
|
|
- **يحتوي** على جميع صور الكائنات اللازمة للعبة
|
|
- **يتضمن** الوثيقة الرئيسية HTML وملف تطبيق JavaScript
|
|
- **يوفر** تكوين الحزمة لخادم التطوير المحلي
|
|
|
|
### بدء تشغيل خادم التطوير
|
|
|
|
انتقل إلى مجلد المشروع الخاص بك وابدأ الخادم المحلي:
|
|
|
|
```bash
|
|
cd your-work
|
|
npm start
|
|
```
|
|
|
|
**تسلسل الأوامر هذا:**
|
|
- **يغير** الدليل إلى مجلد المشروع الخاص بك
|
|
- **يبدأ** خادم HTTP المحلي على `http://localhost:5000`
|
|
- **يخدم** ملفات اللعبة الخاصة بك للاختبار والتطوير
|
|
- **يمكن** التطوير المباشر مع إعادة التحميل التلقائي
|
|
|
|
افتح متصفحك وانتقل إلى `http://localhost:5000` لرؤية حالة اللعبة الحالية مع البطل والأعداء معروضين على الشاشة.
|
|
|
|
### التنفيذ خطوة بخطوة
|
|
|
|
مثل النهج المنهجي الذي استخدمته ناسا لبرمجة مركبة الفضاء "فوياجر"، سننفذ اكتشاف التصادمات بشكل منهجي، نبني كل مكون خطوة بخطوة.
|
|
|
|
#### 1. إضافة حدود تصادم المستطيل
|
|
|
|
أولاً، دعنا نعلم كائنات اللعبة كيفية وصف حدودها. أضف هذه الطريقة إلى فئة `GameObject`:
|
|
|
|
```javascript
|
|
rectFromGameObject() {
|
|
return {
|
|
top: this.y,
|
|
left: this.x,
|
|
bottom: this.y + this.height,
|
|
right: this.x + this.width,
|
|
};
|
|
}
|
|
```
|
|
|
|
**ما الذي تحققه هذه الطريقة:**
|
|
- **تنشئ** كائن مستطيل بحدود إحداثيات دقيقة
|
|
- **تحسب** الحواف السفلية واليمنى باستخدام الموضع بالإضافة إلى الأبعاد
|
|
- **تعيد** كائنًا جاهزًا لخوارزميات اكتشاف التصادمات
|
|
- **توفر** واجهة موحدة لجميع كائنات اللعبة
|
|
|
|
#### 2. تنفيذ اكتشاف التقاطع
|
|
|
|
الآن دعنا ننشئ محقق التصادمات - وظيفة يمكنها تحديد متى تتداخل مستطيلات:
|
|
|
|
```javascript
|
|
function intersectRect(r1, r2) {
|
|
return !(
|
|
r2.left > r1.right ||
|
|
r2.right < r1.left ||
|
|
r2.top > r1.bottom ||
|
|
r2.bottom < r1.top
|
|
);
|
|
}
|
|
```
|
|
|
|
**تعمل هذه الخوارزمية عن طريق:**
|
|
- **اختبار** أربعة شروط فصل بين المستطيلات
|
|
- **تعيد** `false` إذا كان أي شرط فصل صحيحًا
|
|
- **تشير** إلى التصادم عندما لا يوجد فصل
|
|
- **تستخدم** منطق النفي لاختبار التقاطع بكفاءة
|
|
|
|
#### 3. تنفيذ نظام إطلاق الليزر
|
|
|
|
هنا تصبح الأمور مثيرة! دعنا نعد نظام إطلاق الليزر.
|
|
|
|
##### ثوابت الرسائل
|
|
|
|
أولاً، دعنا نحدد بعض أنواع الرسائل حتى تتمكن أجزاء مختلفة من اللعبة من التواصل مع بعضها البعض:
|
|
|
|
```javascript
|
|
KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
|
|
COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER",
|
|
COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
|
|
```
|
|
|
|
**توفر هذه الثوابت:**
|
|
- **توحيد** أسماء الأحداث في التطبيق
|
|
- **تمكين** التواصل المتسق بين أنظمة اللعبة
|
|
- **منع** الأخطاء الإملائية في تسجيل معالجات الأحداث
|
|
|
|
##### التعامل مع إدخال لوحة المفاتيح
|
|
|
|
أضف اكتشاف مفتاح المسافة إلى مستمع حدث المفتاح الخاص بك:
|
|
|
|
```javascript
|
|
} else if(evt.keyCode === 32) {
|
|
eventEmitter.emit(Messages.KEY_EVENT_SPACE);
|
|
}
|
|
```
|
|
|
|
**هذا المعالج للإدخال:**
|
|
- **يكتشف** ضغطات مفتاح المسافة باستخدام keyCode 32
|
|
- **يبث** رسالة حدث موحدة
|
|
- **يمكن** منطق الإطلاق المنفصل
|
|
|
|
##### إعداد مستمع الحدث
|
|
|
|
سجل سلوك الإطلاق في وظيفة `initGame()` الخاصة بك:
|
|
|
|
```javascript
|
|
eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
|
|
if (hero.canFire()) {
|
|
hero.fire();
|
|
}
|
|
});
|
|
```
|
|
|
|
**هذا المستمع للحدث:**
|
|
- **يستجيب** لأحداث مفتاح المسافة
|
|
- **يتحقق** من حالة تبريد الإطلاق
|
|
- **يفعل** إنشاء الليزر عند السماح بذلك
|
|
|
|
أضف معالجة التصادم لتفاعلات الليزر مع العدو:
|
|
|
|
```javascript
|
|
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
|
|
first.dead = true;
|
|
second.dead = true;
|
|
});
|
|
```
|
|
|
|
**هذا المعالج للتصادم:**
|
|
- **يتلقى** بيانات حدث التصادم مع كلا الكائنين
|
|
- **يحدد** كلا الكائنين للإزالة
|
|
- **يضمن** التنظيف المناسب بعد التصادم
|
|
|
|
#### 4. إنشاء فئة الليزر
|
|
|
|
نفذ مقذوف ليزر يتحرك للأعلى ويدير دورة حياته الخاصة:
|
|
|
|
```javascript
|
|
class Laser extends GameObject {
|
|
constructor(x, y) {
|
|
super(x, y);
|
|
this.width = 9;
|
|
this.height = 33;
|
|
this.type = 'Laser';
|
|
this.img = laserImg;
|
|
|
|
let id = setInterval(() => {
|
|
if (this.y > 0) {
|
|
this.y -= 15;
|
|
} else {
|
|
this.dead = true;
|
|
clearInterval(id);
|
|
}
|
|
}, 100);
|
|
}
|
|
}
|
|
```
|
|
|
|
**تنفيذ هذه الفئة:**
|
|
- **يمدد** GameObject ليرث الوظائف الأساسية
|
|
- **يضبط** الأبعاد المناسبة لصورة الليزر
|
|
- **ينشئ** حركة تلقائية للأعلى باستخدام `setInterval()`
|
|
- **يتعامل** مع التدمير الذاتي عند الوصول إلى أعلى الشاشة
|
|
- **يدير** توقيت الرسوم المتحركة والتنظيف الخاص به
|
|
|
|
#### 5. تنفيذ نظام اكتشاف التصادمات
|
|
|
|
أنشئ وظيفة شاملة لاكتشاف التصادمات:
|
|
|
|
```javascript
|
|
function updateGameObjects() {
|
|
const enemies = gameObjects.filter(go => go.type === 'Enemy');
|
|
const lasers = gameObjects.filter(go => go.type === "Laser");
|
|
|
|
// Test laser-enemy collisions
|
|
lasers.forEach((laser) => {
|
|
enemies.forEach((enemy) => {
|
|
if (intersectRect(laser.rectFromGameObject(), enemy.rectFromGameObject())) {
|
|
eventEmitter.emit(Messages.COLLISION_ENEMY_LASER, {
|
|
first: laser,
|
|
second: enemy,
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
// Remove destroyed objects
|
|
gameObjects = gameObjects.filter(go => !go.dead);
|
|
}
|
|
```
|
|
|
|
**هذا النظام للتصادمات:**
|
|
- **يصفي** كائنات اللعبة حسب النوع لاختبار فعال
|
|
- **يختبر** كل ليزر ضد كل عدو للتقاطعات
|
|
- **يبث** أحداث التصادم عند اكتشاف التقاطعات
|
|
- **ينظف** الكائنات المدمرة بعد معالجة التصادمات
|
|
|
|
> ⚠️ **هام**: أضف `updateGameObjects()` إلى الحلقة الرئيسية للعبة في `window.onload` لتمكين اكتشاف التصادمات.
|
|
|
|
#### 6. إضافة نظام التبريد إلى فئة البطل
|
|
|
|
عزز فئة البطل بميكانيكية الإطلاق وتحديد معدل الإطلاق:
|
|
|
|
```javascript
|
|
class Hero extends GameObject {
|
|
constructor(x, y) {
|
|
super(x, y);
|
|
this.width = 99;
|
|
this.height = 75;
|
|
this.type = "Hero";
|
|
this.speed = { x: 0, y: 0 };
|
|
this.cooldown = 0;
|
|
}
|
|
|
|
fire() {
|
|
gameObjects.push(new Laser(this.x + 45, this.y - 10));
|
|
this.cooldown = 500;
|
|
|
|
let id = setInterval(() => {
|
|
if (this.cooldown > 0) {
|
|
this.cooldown -= 100;
|
|
} else {
|
|
clearInterval(id);
|
|
}
|
|
}, 200);
|
|
}
|
|
|
|
canFire() {
|
|
return this.cooldown === 0;
|
|
}
|
|
}
|
|
```
|
|
|
|
**فهم فئة البطل المحسنة:**
|
|
- **يبدأ** مؤقت التبريد عند الصفر (جاهز للإطلاق)
|
|
- **ينشئ** كائنات الليزر المتمركزة فوق سفينة البطل
|
|
- **يضبط** فترة التبريد لمنع الإطلاق السريع
|
|
- **يقلل** مؤقت التبريد باستخدام تحديثات تعتمد على الفاصل الزمني
|
|
- **يوفر** فحص حالة الإطلاق من خلال طريقة `canFire()`
|
|
|
|
### اختبار التنفيذ الخاص بك
|
|
|
|
تتميز لعبة الفضاء الخاصة بك الآن بنظام اكتشاف التصادمات الكامل وميكانيكية القتال. 🚀 اختبر هذه القدرات الجديدة:
|
|
- **تنقل** باستخدام مفاتيح الأسهم للتحقق من التحكم في الحركة
|
|
- **أطلق الليزر** باستخدام مفتاح المسافة - لاحظ كيف يمنع التبريد النقر المتكرر
|
|
- **راقب التصادمات** عندما تصيب الليزرات الأعداء، مما يؤدي إلى الإزالة
|
|
- **تحقق من التنظيف** حيث تختفي الكائنات المدمرة من اللعبة
|
|
|
|
لقد نجحت في تنفيذ نظام اكتشاف التصادمات باستخدام نفس المبادئ الرياضية التي توجه الملاحة الفضائية والروبوتات.
|
|
|
|
## تحدي GitHub Copilot Agent 🚀
|
|
|
|
استخدم وضع الوكيل لإكمال التحدي التالي:
|
|
|
|
**الوصف:** عزز نظام اكتشاف التصادمات من خلال تنفيذ تعزيزات تظهر بشكل عشوائي وتوفر قدرات مؤقتة عند جمعها بواسطة سفينة البطل.
|
|
|
|
**المهمة:** أنشئ فئة PowerUp التي تمد GameObject ونفذ اكتشاف التصادم بين البطل والتعزيزات. أضف نوعين على الأقل من التعزيزات: واحد يزيد معدل الإطلاق (يقلل التبريد) وآخر ينشئ درعًا مؤقتًا. قم بتضمين منطق الظهور الذي ينشئ التعزيزات على فترات ومواقع عشوائية.
|
|
|
|
---
|
|
|
|
## 🚀 التحدي
|
|
|
|
أضف انفجارًا! ألقِ نظرة على أصول اللعبة في [مستودع فن الفضاء](../../../../6-space-game/solution/spaceArt/readme.txt) وحاول إضافة انفجار عندما يصيب الليزر كائنًا فضائيًا.
|
|
|
|
## اختبار ما بعد المحاضرة
|
|
|
|
[اختبار ما بعد المحاضرة](https://ff-quizzes.netlify.app/web/quiz/36)
|
|
|
|
## المراجعة والدراسة الذاتية
|
|
|
|
جرب الفواصل الزمنية في لعبتك حتى الآن. ماذا يحدث عندما تغيرها؟ اقرأ المزيد عن [أحداث توقيت JavaScript](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/).
|
|
|
|
## الواجب
|
|
|
|
[استكشاف التصادمات](assignment.md)
|
|
|
|
---
|
|
|
|
**إخلاء المسؤولية**:
|
|
تم ترجمة هذا المستند باستخدام خدمة الترجمة بالذكاء الاصطناعي [Co-op Translator](https://github.com/Azure/co-op-translator). بينما نسعى لتحقيق الدقة، يرجى العلم أن الترجمات الآلية قد تحتوي على أخطاء أو عدم دقة. يجب اعتبار المستند الأصلي بلغته الأصلية المصدر الرسمي. للحصول على معلومات حاسمة، يُوصى بالترجمة البشرية الاحترافية. نحن غير مسؤولين عن أي سوء فهم أو تفسيرات خاطئة ناتجة عن استخدام هذه الترجمة. |