لإجراء اكتشاف الاصطدام في Canvas، غالبًا ما يستخدم الأشخاص بشكل مباشر وظيفة اكتشاف الاصطدام المضمنة في محرك اللعبة (Cocos2d-JS، Egret) أو محرك الفيزياء (Box2D). هل تشعر بالفضول، هل فكرت يومًا في آليات التشغيل الداخلية الخاصة بهم؟ سيتم شرح تقنية الكشف عن الاصطدام الأساسية أدناه:
1. كشف الاصطدام على أساس المستطيلما يسمى باكتشاف الاصطدام هو تحديد ما إذا كان هناك تداخل بين الكائنات. هنا نفترض أن المصادمات التي تمت مناقشتها كلها كائنات مستطيلة. في المثال التالي، سنقوم بإنشاء كائنين مستقيمين A وB (يشار إليهما فيما بعد بـ A وB). يتم تثبيت موضع A ويتحرك B باستخدام الماوس. عندما يتداخل A وB، ستطالبك وحدة التحكم بالتقاطع! !
1. قم بإنشاء كائن مستطيلهنا نقوم بإنشاء Rect.js جديد، وإنشاء كائن Rect وإضافة طريقة رسم نموذج أولي إليه. ستقوم هذه الطريقة بالرسم إلى كائن اللوحة القماشي الوارد (السياق) بناءً على خصائص (الموضع والحجم) للكائن الحالي.
الرمز هو كما يلي:
function Rect(x,y,width,height) { this.x = x; this.y = y; this.width = width; this.height = height;}Rect.prototype.draw = function(context){ context. save(); context.translate(this.x,this.y); context.fillRect(0,0,this.width,this.height);2. احصل على موضع الماوس
نظرًا لأن B يحتاج إلى متابعة حركة الماوس، فنحن بحاجة إلى اكتشاف الموضع الحالي للماوس على اللوحة القماشية. قم بإنشاء وظيفة Capturemouse لاكتشاف حركة الماوس على عقدة المستند الوارد (العنصر) وإرجاع كائن الماوس (الذي يحتوي على إحداثيات x وy للماوس).
الرمز هو كما يلي:
function Capturemouse (element) { var mouse={x:null,y:null}; element.addEventListener('mousemove',function (event) { var x, y; if(event.pageX || events.pageY){ x =event.pageX; document.documentElement.scrollLeft; y = events.clientY+document.body.scrollTop+ document.documentElement.scrollTop; } x -=element.offsetLeft; y -=element.offsetTop; },خطأ); إرجاع الماوس;}3. كشف الاصطدام
اكتشاف ما إذا كان هناك تداخل بين A وB عند مناقشة ما إذا كان هناك تداخل، يمكننا أولاً أن ننظر إلى المواقف الأربعة دون تداخل، كما هو موضح أدناه:
وفيما يلي حكم هذه الحالات الأربع:
1. rectB.y+rectB.height < rectA.y
2. rectB.y > rectA.x +rectA.width
3. rectB.y > rectA.y + rectA.height
4. rectB.x+rectB.width < rectA.x
والآن بعد أن عرفنا كيف نحكم على الحالة غير المتداخلة، كيف نحكم على الحالة المتداخلة؟ هذا صحيح، العكس! ، نقوم بإنشاء الدالة Interaect وإضافتها إلى Init.js. تمرر هذه الدالة معلمتين لكائن Rect وستعود صحيحًا عندما يتداخل كائنان Rect.
الرمز هو كما يلي:
دالة Intersect(rectA,rectB) { return !(rectB.y+rectB.height < rectA.y || rectB.y > rectA.x +rectA.width || rectB.y > rectA.y + rectA.height|| rectB.x+rectB.width < rectA.x)}4. حلقة الرسوم المتحركة
قم بإنشاء Animationjs جديد وقم بتعيين وظيفة الرسوم المتحركة requestAnimationFrame().
في جسم الحلقة، سيتم تنفيذ الأمرين التاليين:
الرمز هو كما يلي:
function drawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, Canvas.width, Canvas.height); } if(mouse.x){ rectB.x = mouse.x; rectB.draw(context);}
3. التهيئة
قم بإنشاء Init.js جديد، واحصل على عنصر اللوحة القماشية واكتشف حركة الماوس، وقم بتهيئة كائني Rect A وB، وأخيرًا ابدأ حلقة الرسوم المتحركة.
الرمز هو كما يلي:
window.onload = function () { Canvas = document.getElementById('collCanvas'); 2,100,100); drawAnimation();}2. كشف الاصطدام على أساس الدائرة
بعد الحديث عن الاصطدام المستطيل، دعونا نتحدث عن الاصطدام الدائري، وبالمثل، سوف نقوم بإنشاء كائنين دائريين A وB (يشار إليهما فيما بعد بـ A، B)، ويتبع B حركة الماوس B التداخل، سيُطلب من وحدة التحكم التقاطع! !
1. قم بإنشاء كائن دائرةfunction Circle(x,y,radius) { this.x = x; this.y = y; this.radius = radius;}Circle.prototype.draw = function(context){ context.save(); this.x,this.y); context.beginPath(); context.arc(0,0,this.radius,0,Math.PI*2,false); سياق.استعادة();}2. كشف الاصطدام الدائري
يمكن الحكم على اكتشاف التصادم بين الدائرتين ببساطة من خلال مقارنة المسافة بين مركزي الدائرتين بمجموع أنصاف أقطار الدائرتين عندما تكون المسافة بين مركزي الدائرتين أقل من مجموع أنصاف أقطار الدائرتين دائرتين، يحدث تصادم.
كما هو موضح أدناه:
لذا فإن أول ما يتعين علينا القيام به هو حساب المسافة بين مركزي الدائرتين، وسنستخدم هنا صيغة المسافة بين نقطتين، كما يلي:
عند الحصول على المسافة بين مركزي دائرتين، سيتم مقارنتها بمجموع نصف قطر الدائرتين، وإذا كانت المسافة أقل من مجموع نصف القطر، فسيتم إرجاع صحيح.
الآن نقوم بتحديث وظيفة Interaect.
الرمز هو كما يلي:
وظيفة Intersect(circleA,circleB) { var dx = CircleA.x-circleB.x; var dy = CircleA.y-circleB.y; var distance = Math.sqrt(dx*dx+dy*dy); دائرة أ. نصف القطر + دائرة ب. نصف القطر)؛}3. حلقة الرسوم المتحركة
قم بتحديث Animation.js، وهنا نستبدل كائن Rect بكائن Circle.
الرمز هو كما يلي:
function drawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, Canvas.width, Canvas.height); } if(mouse.x){ CircleB.x = mouse.x; CircleB.draw(context);}4. التهيئة
قم بتحديث Init.js، وقم بتهيئة كائني الدائرة A وB، وأخيرًا ابدأ حلقة الرسوم المتحركة.
الرمز هو كما يلي:
window.onload = function () { Canvas = document.getElementById('collCanvas'); 2,100); CircleB = new Circle(100,100,100);3. بناء على كشف التصادم بين المستطيل والدائرة
تتعلق التوضيحات السابقة باكتشاف الاصطدامات بين الأشكال الفردية. وبعد ذلك، سنكتشف الاصطدامات بين المستطيلات والدوائر.
1. كشف الاصطدام
كما هو الحال مع اكتشاف المستطيل، دعونا نلقي نظرة أولاً على المواقف الأربعة التي لا يحدث فيها أي تصادم.
كما هو موضح أدناه:
وفيما يلي حكم هذه الحالات الأربع:
قم بتحديث وظيفة Interaect، وعكس حالة عدم التداخل، وتمرير كائن Rect وكائن Circle إلى الوظيفة. عندما يتداخل كائن Rect وكائن Circle، سيتم إرجاع true.
الرمز هو كما يلي:
دالة Intersect(Rect,Circle) { return!(Circle.y + Circle.radius < Rect.y || Circle.x - Circle.radius > Rect.x + Rect.width || Circle.y - Circle.radius > Rect .y + Rect.height ||. Circle.x + Circle.radius < Rect.x)}2. حلقة الرسوم المتحركة
قم بتحديث Animation.js، حيث نتبع الكائن الدائري لحركة الماوس ونكتشف الاصطدام بالكائن المستقيم ذي الموضع الثابت.
الرمز هو كما يلي:
function drawAnimation() { window.requestAnimationFrame(drawAnimation); } if(mouse.x){ Circle.x = mouse.x;3. التهيئة
قم بتحديث Init.js، وقم بتهيئة كائن Circle وكائن Rect، وأخيرًا ابدأ حلقة الرسوم المتحركة.
الرمز هو كما يلي:
window.onload = function () { Canvas = document.getElementById('collCanvas'); width/2,canvas.height/2,100,100); drawAnimation();}
ما ورد أعلاه هو المحتوى الكامل لهذه المقالة وآمل أن يكون مفيدًا لدراسة الجميع وآمل أيضًا أن يدعم الجميع شبكة VeVb Wulin.