البرمجة والذكاء الاصطناعي · الصف الأول الثانوي · الترم الأول
تطوير لعبة تكسير القوالب (1) و(2) بمساعدة الذكاء الاصطناعي
تطوير لعبة تكسير القوالب بلغة JavaScript بمساعدة الذكاء الاصطناعي التوليدي: فهم عناصر اللعبة (الكرة والمضرب والقوالب)، وحلقة الرسم، والحركة بالمتغيرات dx وdy، والارتداد والاصطدام، ثم التعديل اليدوي (حجم الكرة ولون القوالب وعددها) والتطوير (زاوية الارتداد والسرعة والنتيجة وعدد المحاولات).
آخر تحديث: · كيف نراجع المحتوى
مقدمة
- الوحدة الثالثة عشرة: الذكاء الاصطناعي التوليدي — الموضوعان 13-9 و13-10
لعبة تكسير القوالب من أشهر الألعاب القديمة: كرة ترتد، ومضرب تحركه أنت، وصفوف من القوالب تتكسر عند اصطدام الكرة بها. في هذين الموضوعين يكتب الذكاء الاصطناعي التوليدي كود اللعبة، لكنك أنت من يفهمه ويعدّله بيده، ثم يطوّره بإضافات جديدة. ستعرض عملك في حصة قادمة.
أهداف التعلم
- أن تستخدم الذكاء الاصطناعي التوليدي لإنشاء لعبة بسيطة بملفات HTML وCSS وJavaScript منفصلة.
- أن تحدد في الكود أجزاء اللعبة: الكرة والمضرب والقوالب والنتيجة.
- أن تشرح كيف تتحرك الكرة وترتد وتكسر القوالب.
- أن تعدّل قيم الكود يدويًّا وتطور اللعبة بميزات جديدة.
- أن تكتب ما واجهته من صعوبات وما استخدمته من استراتيجيات.
شرح الدرس
(1) إنشاء اللعبة وفهمها
- أمر توجيهي: “اصنع لعبة تكسير قوالب بسيطة. اجعل أكواد HTML وCSS وJavaScript منفصلة”.
- انسخ كل كود في تبويبه في المحرر، ثم شغّل اللعبة.
- اطلب: “اشرح هذا الكود”، واسأل نفسك: ما القدر الذي فهمته؟
- أعد تسمية المحادثة إلى “تطوير لعبة تكسير القوالب” لتكمل فيها لاحقًا.
أفكار برمجية داخل اللعبة
| الفكرة | كيف تعمل |
|---|---|
| لوحة الرسم (Canvas) | الوسم <canvas> مساحة نرسم عليها الكرة والمضرب والقوالب بـ JavaScript |
| حلقة الرسم | الدالة draw تمسح اللوحة وترسم كل شيء من جديد، ثم تطلب تشغيل نفسها مرة أخرى بالدالة requestAnimationFrame؛ فتتكرر عشرات المرات في الثانية فيبدو الشكل متحركًا |
| الحركة | موضع الكرة x وy، وفي كل مرة نضيف إليهما dx وdy (مقدار الحركة) |
| الارتداد | عند اصطدام الكرة بجدار جانبي نعكس إشارة dx (dx = -dx)، وعند السقف نعكس dy |
| القوالب | مصفوفة ثنائية الأبعاد (صفوف وأعمدة) كالتي درستها في Python، ولكل قالب حالة: موجود أو مكسور |
| الاصطدام | إذا وقعت الكرة داخل حدود قالب: نعكس dy، ونجعل القالب مكسورًا، ونزيد النتيجة |
(2) تطوير اللعبة
أولًا: تعديلات يدوية بدون الذكاء الاصطناعي — فكر في البرنامج بنفسك وعدّله:
- تكبير حجم الكرة: ابحث عن المتغير الذي يحدد نصف قطرها (مثل
ballRadius) وزد قيمته. - تغيير لون القوالب: ابحث عن اللون في سطر رسم القوالب (مثل
ctx.fillStyle = "orange") وغيّره. - زيادة عدد القوالب: زد عدد الصفوف
rowsأو الأعمدةcols، مع مراعاة أن تتسع لها اللوحة.
ثانيًا: تطوير بمساعدة الذكاء الاصطناعي أو يدويًّا:
- “اجعل زاوية الكرة تتغير في كل مرة تصطدم فيها باللاعب”.
- تغيير سرعة الكرة، وعرض النتيجة (Score)، وتعيين عدد المحاولات (Lives)، وتغيير صلابة القوالب (مثل قالب يحتاج ضربتين).
أمثلة وتطبيقات
مثال: نسخة مبسطة من ملف JavaScript للعبة (الكود المولَّد عندك سيختلف، لكن الأفكار نفسها):
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
// الكرة
let x = 240, y = 280;
let dx = 2, dy = -2;
const ballRadius = 8;
// المضرب (اللاعب)
const paddleWidth = 80, paddleHeight = 10;
let paddleX = 200;
// القوالب: مصفوفة ثنائية الأبعاد
const rows = 3, cols = 6;
const brickWidth = 70, brickHeight = 20, gap = 8;
const bricks = [];
for (let r = 0; r < rows; r++) {
bricks[r] = [];
for (let c = 0; c < cols; c++) {
bricks[r][c] = { alive: true };
}
}
let score = 0;
let lives = 3;
document.addEventListener("mousemove", (e) => {
paddleX = e.offsetX - paddleWidth / 2;
});
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// رسم القوالب واكتشاف اصطدام الكرة بها
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
const b = bricks[r][c];
if (!b.alive) continue;
const bx = c * (brickWidth + gap) + 10;
const by = r * (brickHeight + gap) + 30;
ctx.fillStyle = "orange";
ctx.fillRect(bx, by, brickWidth, brickHeight);
if (x > bx && x < bx + brickWidth && y > by && y < by + brickHeight) {
dy = -dy;
b.alive = false;
score = score + 1;
}
}
}
// رسم الكرة والمضرب
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "blue";
ctx.fill();
ctx.fillStyle = "black";
ctx.fillRect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
ctx.fillText("Score: " + score + " Lives: " + lives, 10, 15);
// الارتداد عن الجدران
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) dx = -dx;
if (y + dy < ballRadius) dy = -dy;
// الوصول إلى الأسفل: مضرب أم ضياع محاولة؟
if (y + dy > canvas.height - ballRadius - paddleHeight) {
if (x > paddleX && x < paddleX + paddleWidth) {
dy = -dy;
} else {
lives = lives - 1;
if (lives === 0) {
alert("انتهت اللعبة! نتيجتك: " + score);
document.location.reload();
return;
}
x = 240; y = 280; dx = 2; dy = -2;
}
}
x = x + dx;
y = y + dy;
requestAnimationFrame(draw);
}
draw();
ويحتاج ملف HTML إلى لوحة رسم وربط الملف: <canvas id="game" width="480" height="320"></canvas> ثم <script src="game.js"></script>.
قراءة الكود:
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) dx = -dx;معناها: إذا كانت الخطوة القادمة ستتجاوز الجدار الأيمن أو الأيسر فاعكس الاتجاه الأفقي. والرمز||يعني “أو”.- عند سقوط الكرة إلى أسفل: إذا كانت فوق المضرب ترتد، وإلا تنقص المحاولات
lives، وعند انتهائها تنتهي اللعبة.
تطوير: تغيير زاوية الارتداد حسب مكان الاصطدام بالمضرب — نستبدل dy = -dy; داخل شرط المضرب بما يلي:
dy = -dy;
const hitPoint = x - (paddleX + paddleWidth / 2);
dx = hitPoint * 0.1;
إذا اصطدمت الكرة بمنتصف المضرب تكون hitPoint قريبة من الصفر فترتد الكرة رأسيًّا تقريبًا، وكلما اصطدمت قرب طرف المضرب زاد ميلها يمينًا أو يسارًا.
تطوير: زيادة السرعة — نضاعف قيم الحركة الابتدائية، مثل dx = 3 وdy = -3 بدل 2.
اكتب ما فهمته بعد التعديل:
- الصعوبات: مثل “لم أعرف أي قيمة أغيرها لتكبير الكرة”، أو “صعب أن أجد مكان رسم الكرة في الكود الطويل”.
- الاستراتيجيات (نقاط الإبداع): مثل “خمنت المعنى من أسماء المتغيرات وبحثت عن الأجزاء المرتبطة بها”، أو “غيرت القيم قليلًا وجربت الحركة بعد كل تعديل”.
ملاحظات مهمة
- غيّر قيمة واحدة في كل مرة ثم جرّب؛ حتى تعرف أثر كل تعديل، وتعود بسهولة إذا ظهر خطأ.
- احتفظ بنسخة من الكود الذي يعمل قبل أي تعديل كبير.
- أسماء المتغيرات الواضحة (مثل
ballRadiusوlives) تسهّل فهم الكود؛ فاستخدمها في برامجك. - في نظام إحداثيات اللوحة تبدأ النقطة (0, 0) من أعلى يسار اللوحة، ويزيد
yكلما نزلنا لأسفل؛ لذلكdyالسالبة تعني الصعود.
المفاهيم الأساسية
- حلقة الرسم: مسح ثم رسم ثم تكرار بـ
requestAnimationFrame. - الحركة: إضافة
dxوdyإلى موضع الكرة، والارتداد بعكس الإشارة. - القوالب: مصفوفة ثنائية الأبعاد، والاصطدام يكسر القالب ويزيد النتيجة.
- التطوير: التعديل اليدوي للقيم، ثم إضافة ميزات مثل الزاوية والسرعة والنتيجة والمحاولات.
ملخص الدرس
أنشأنا بمساعدة الذكاء الاصطناعي التوليدي لعبة تكسير القوالب، وفهمنا أن حلقة الرسم تعيد رسم اللعبة باستمرار، وأن الكرة تتحرك بإضافة dx وdy إلى موضعها وترتد بعكس إشارتهما، وأن القوالب مصفوفة ثنائية الأبعاد تتكسر عند الاصطدام. ثم عدّلنا الكود بأنفسنا وطورناه بتغيير الزاوية والسرعة وعرض النتيجة وعدد المحاولات، ودوّنا الصعوبات والاستراتيجيات.
أسئلة للتدريب
- ما وظيفة الدالة
requestAnimationFrameفي اللعبة؟ - لماذا نكتب
dx = -dxعند اصطدام الكرة بالجدار الجانبي؟ - أي متغير تغيّره لتكبير الكرة؟ وأي متغير لزيادة صفوف القوالب؟
- اشرح كيف يجعل الكود
dx = hitPoint * 0.1زاوية الارتداد تتغير. - اذكر صعوبة واجهتك أو قد تواجهك عند تعديل كود طويل، واستراتيجية للتغلب عليها.