كم هو جميل هذا العالمconsole.log () هي طريقة جيدة لإخراج معلومات تصحيح الأخطاء إلى وحدة تحكم الويب. يمكنك عرض الأرقام والسلاسل والمصفوفات والكائنات والوظائف والنص العادي ، بالإضافة إلى ذلك ، يمكنك إضافة التنسيق واللون والخلفية وبعض الأنماط الأخرى إلى كل هذا ... هل هذا كل شيء؟ هل هذا كل هذا وحده يمكن أن تفعل؟ حسنًا ... ماذا عن التنفيذ في وحدة التحكم الخاصة بمنصة بسيطة أو خوارزمية صب راي أو فيزياء الأنسجة؟
بالنسبة لأولئك الذين أتوا إلى هنا فقط لأرى ، سأترك رابطًا للعرض التجريبي في البداية:
جيثب: جيثبمثال حي: تجريبيافتح الصفحة ، اضغط F12 ، قم بتمديد وحدة التحكم على نطاق أوسع وانتقل إلى العرض التوضيحي الذي يثير اهتمامك. وبالطبع تحتاج إلى التركيز على الصفحة لتتمكن من التحكم في الصورة في وحدة التحكم.
يُنصح بالعمل في chrome ، ولكن قد تكون هناك حالة قد لا تكون الأحرف المستخدمة لعرض الصورة مدعومة وعرضها كمربعات. كخيار ، قم بتنزيل الكود بنفسك وقم بتغيير أحرف المخرجات للآخرين.
والآن أكثر قليلاً عن هذا
وحدة التحكم كقماش
دعونا نلقي نظرة على طريقة console.log () ووحدة التحكم ككل ، وليس كأداة لتصحيح الأخطاء ، ولكن كقماش. نعم ، كمكان يمكننا أن نرسم فيه القليل ونجعله يتحرك. بالإضافة إلى ذلك ، لا أحد ألغى أحرف Unicode.
لقد طبقت طرقًا "للرسم" في وحدة التحكم ، مثل أساليب العمل باستخدام قماش. ولكن مقارنةً بقماش حقيقي ، فإن الإخراج إلى وحدة التحكم ، علاوة على ذلك ، فإن إعادة الرسم تفرض قيودًا كبيرة ، والتي للأسف لا يمكن الالتفاف عليها (على الأقل أعتقد ذلك). عنهم بالترتيب.
حجم بكسل
عند الرسم على القماش ، نحن نتعامل مع وحدات البكسل ، والتي لها حجم ، انتباه ، بكسل على شاشتك! عند عرضه في وحدة التحكم ، يأخذ "البكسل" مفهومًا مختلفًا قليلاً. نعم ، بالنسبة إلى وحدة التحكم ، هذا هو بكسل خاص به ، ولكن بالنسبة إلى بكسل حقيقي ، هل هو مجرد شخصية خاصة ، على سبيل المثال ، مثل؟ ولكن هناك قيود طفيفة على الأحرف ، أو بالأحرى توصية: يجب أن يكون لها ارتفاع يساوي ارتفاع فاصل الأسطر في وحدة التحكم. لكن هذا فقط إذا أردنا الحصول على صورة جميلة (قدر الإمكان).
إعادة رسم
هذه هي المشكلة الرئيسية منذ ذلك الحين وحدة التحكم غير مصممة لتحديث البيانات بشكل متكرر. نأتي بهم هناك ، نستنتج ونستنتج. هناك console.clear () يقوم بمسحه ، لكنني أعتقد أنه نادرًا ما يتم استخدامه. نعم ، ولكن ليس في حالتي ، حيث يعتمد كل شيء على حقيقة أنك تحتاج إلى تنظيفه باستمرار وعرض النص مرة أخرى. هنا واحد فقط console.clear () يسبب التحميل الزائد الخاص به بالكامل ، والذي يرافقه وميض مللي ثانية. وإذا كنت بحاجة إلى إعادة رسمها باستمرار مع بعض الترددات ، فمن الأفضل للأشخاص الذين يعانون من الحساسية المفرطة عدم النظر إليها. لكن لسوء الحظ لا يمكن فعل شيء حيال ذلك.
اللون
كما كتبت في البداية ، يمكن تطبيق التنسيق على الإخراج ، لكن في حالتي قررت ألا أكون مضمونًا مع صورة بالأبيض والأسود ، ويمكن تحقيق ذلك بفضل مجموعة واسعة من أحرف Unicode.
يمكن رؤية قيود أكثر تفصيلا على الأمثلة الحية ، الروابط التي تركتها في نهاية المقال. يمكنك التعرف على نفسك بالفعل ، ولكن الآن سوف أصف عملية الرسم نفسها. كل هذا قمت بتصميمه في مكتبة صغيرة يمكنني من خلالها تنفيذ ألعاب بسيطة وخوارزمية Raycasting
نوجه في وحدة التحكم
لقد اعتمدت أسماء الطرق ، وكذلك عملية الرسم من اللوحة القماشية (فيما بعد سأشرح السبب) وهذا ما انتهى إليه الأمر
engine.jsconst canvas = { width: 70, height: 40, getContext(type) { if (type != '2d') { return console.log('Only 2d'); } return new Context2D(type); } } class Context2D { constructor(type) { this.fillStyle = '?'; this.emptyStyle = '?'; this.map = []; for (let i = 0; i < canvas.height; i++) { this.map[i] = []; for (let j = 0; j < canvas.width; j++) { this.map[i][j] = this.emptyStyle; } } this.path = []; this.clear(); } fillRect(x, y, width, height) { for (let i = y; i < y + height; i++) { for (let j = x; j < x + width; j++) { if (!this.map[i]) break; this.map[i][j] = this.fillStyle; } } this.draw(); } strokeRect(x, y, width, height) { for (let j = x; j < x + width; j++) { this.map[y][j] = this.fillStyle; this.map[y + height - 1][j] = this.fillStyle; } for (let i = y + 1; i < y + height - 1; i++) { this.map[i][x] = this.fillStyle; this.map[i][x + width - 1] = this.fillStyle; } this.draw(); } clearRect(x, y, width, height) { for (let i = y; i < y + height; i++) { for (let j = x; j < x + width; j++) { this.map[i][j] = this.emptyStyle; } } this.draw(); } beginPath() { this.path = []; } moveTo(x, y) { this.path.push([Math.round(x), Math.round(y), true]); } lineTo(x, y) { this.path.push([Math.round(x), Math.round(y)]); } closePath() { if (!this.path.length) return false this.path.push([this.path[0][0], this.path[0][1]]); } stroke() { const path = this.path; for (let i = 0; i < path.length - 1; i++) { const x0 = path[i][0]; const y0 = path[i][1]; const x1 = path[i+1][0]; const y1 = path[i+1][1]; this.fillPixel(x1, y1); if (path[i+1][2]) continue; const deltaX = Math.abs(x1 - x0); const deltaY = Math.abs(y1 - y0); const signX = x0 < x1 ? 1 : -1; const signY = y0 < y1 ? 1 : -1; let error = deltaX - deltaY; let x = x0; let y = y0; while(x !== x1 || y !== y1) { this.fillPixel(x, y) const error2 = error * 2; if (error2 > -deltaY) { error -= deltaY; x += signX; } if (error2 < deltaX) { error += deltaX; y += signY; } } } this.draw(); } fillPixel(x, y) { if (!this.map[y]) return false; this.map[y][x] = this.fillStyle; } arc(x1, y1, r) { let x = 0; let y = r; let delta = 1 - 2 * r; let error = 0; while (y >= 0) { this.moveTo(x1 + x, y1 + y); this.moveTo(x1 + x, y1 - y); this.moveTo(x1 - x, y1 + y); this.moveTo(x1 - x, y1 - y); error = 2 * (delta + y) - 1; if (delta < 0 && error <= 0) { delta += 2 * ++x + 1; continue; } if (delta > 0 && error > 0) { delta -= 2 * --y + 1; continue; } delta += 2 * (++x - y--); } this.draw() } draw() { this.clear();
نحن الآن ندرج هذا الملف في ملف html ، ونفتح وحدة التحكم ويمكننا تجربة عدة طرق
canvas.width = 70 canvas.height = 30 const ctx = canvas.getContext('2d') ctx.beginPath() ctx.moveTo(30, 5) ctx.lineTo(30, 25) ctx.moveTo(30, 15) ctx.lineTo(35, 13) ctx.lineTo(38, 13) ctx.lineTo(40, 16) ctx.lineTo(40, 25) ctx.stroke()
ها هي النتيجة

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

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