ในการตรวจจับการชนกันใน Canvas ผู้คนมักจะใช้ฟังก์ชันการตรวจจับการชนในตัวของเอ็นจิ้นเกม (Cocos2d-JS, Egret) หรือเอ็นจิ้นฟิสิกส์ (Box2D) โดยตรง คุณเคยสงสัยเกี่ยวกับกลไกการทำงานภายในหรือไม่ เทคโนโลยีการตรวจจับการชนขั้นพื้นฐานจะอธิบายไว้ด้านล่าง:
1. การตรวจจับการชนกันแบบสี่เหลี่ยมผืนผ้าสิ่งที่เรียกว่าการตรวจจับการชนกันคือการพิจารณาว่ามีการทับซ้อนกันระหว่างวัตถุหรือไม่ ในที่นี้ เราถือว่าการชนกันที่กล่าวถึงนั้นเป็นวัตถุสี่เหลี่ยมทั้งหมด ในตัวอย่างต่อไปนี้ เราจะสร้างวัตถุสี่เหลี่ยม A และ B (ต่อไปนี้จะเรียกว่า A, B) ตำแหน่งของ A ได้รับการแก้ไขแล้ว และ B เคลื่อนที่ด้วยเมาส์ เมื่อ A และ B ทับซ้อนกัน คอนโซลจะพร้อมต์ตัดกัน! -
1. สร้างวัตถุ Rectที่นี่เราสร้าง Rect.js ใหม่ สร้างวัตถุ Rect และเพิ่มวิธีการวาดต้นแบบลงไป วิธีนี้จะวาดไปยังวัตถุผ้าใบขาเข้า (บริบท) ตามคุณสมบัติ (ตำแหน่ง ขนาด) ของวัตถุปัจจุบัน
รหัสมีดังนี้:
ฟังก์ชั่น Rect(x,y,width,height) { this.x = x; this.width = width; this.height = height;}Rect.prototype.draw = function(context){ บริบท บันทึก(); context.translate(this.x,this.y); context.fillRect(0,0,this.width,this.height);2. รับตำแหน่งเมาส์
เนื่องจาก B ต้องติดตามการเคลื่อนไหวของเมาส์ เราจึงต้องตรวจจับตำแหน่งปัจจุบันของเมาส์บนผืนผ้าใบ สร้างฟังก์ชัน Capturemouse เพื่อตรวจจับการเคลื่อนไหวของเมาส์บนโหนดเอกสารขาเข้า (องค์ประกอบ) และส่งคืนวัตถุเมาส์ (ซึ่งมีพิกัด x, y ของเมาส์)
รหัสมีดังนี้:
ฟังก์ชั่น Capturemouse (องค์ประกอบ) { var mouse={x:null,y:null}; element.addEventListener('mousemove',function (event) { var x, y; if(event.pageX || event.pageY){ x = event.pageX; y = event.pageY; }else{ x = event.clientX+document.body.scrollLeft+ document.documentElement.scrollLeft; y = event.client.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()
ในส่วนเนื้อหาของลูป จะทำสองสิ่งต่อไปนี้:
รหัสมีดังนี้:
ฟังก์ชั่น DrawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, canvas.width, canvas.height); if (Intersect(rectA,rectB)){ console.log('interact!!!!' ); } if(mouse.x){ rectB.x = mouse.x; rectB.draw (บริบท);}
3. การเริ่มต้น
สร้าง Init.js ใหม่ รับองค์ประกอบ Canvas และเชื่อมโยงการตรวจจับการเคลื่อนไหวของเมาส์ เริ่มต้นวัตถุ Rect A และ B และสุดท้ายคือเริ่มลูปแอนิเมชั่น
รหัสมีดังนี้:
window.onload = function () { canvas = document.getElementById('collCanvas'); บริบท = canvas.getContext('2d'); Capturemouse(canvas) = new Rect(canvas.width/2,canvas.height/ 2,100,100); วงจรเรียงกระแส B = วงจรใหม่ (100,100,100,100); วาดภาพเคลื่อนไหว();}2. การตรวจจับการชนกันแบบวงกลม
หลังจากพูดถึงการชนกันของสี่เหลี่ยมแล้ว เรามาพูดถึงการชนกันของวงกลมกัน B ซ้อนทับกัน คอนโซล Intercect จะได้รับแจ้ง! -
1. สร้างวัตถุวงกลมฟังก์ชั่น 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
รหัสมีดังนี้:
ฟังก์ชัน ตัดกัน (circleA,circleB) { var dx = circleA.x-circleB.x; var dy = circleA.y-circleB.y; var Distance = Math.sqrt(dx*dx+dy*dy); วงกลม A.radius + วงกลม B.radius);}3. วนรอบแอนิเมชั่น
อัปเดต Animation.js ที่นี่เราจะแทนที่วัตถุ Rect ด้วยวัตถุ Circle
รหัสมีดังนี้:
ฟังก์ชั่น DrawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, canvas.width, canvas.height); if (Intersect(circleA,circleB)){ console.log('interact!!!!' } if(mouse.x){ วงกลมB.x = mouse.x; circleB.y = mouse.y; } วงกลมB.draw (บริบท);}4. การเริ่มต้น
อัปเดต Init.js เริ่มต้นออบเจ็กต์ Circle A และ B และสุดท้ายเริ่มวนซ้ำแอนิเมชัน
รหัสมีดังนี้:
window.onload = function () { canvas = document.getElementById('collCanvas'); บริบท = canvas.getContext('2d'); Capturemouse(canvasA = วงกลมใหม่ (canvas.width/2,canvas.height/ 2,100); วงกลม B = วงกลมใหม่ (100,100,100);3. ขึ้นอยู่กับการตรวจจับการชนกันระหว่างสี่เหลี่ยมกับวงกลม
คำอธิบายก่อนหน้านี้เกี่ยวกับการตรวจจับการชนกันระหว่างรูปร่างเดี่ยว ต่อไปเราจะตรวจจับการชนกันระหว่างสี่เหลี่ยมและวงกลม
1. ตรวจจับการชนกัน
เช่นเดียวกับการตรวจจับสี่เหลี่ยม ก่อนอื่นเรามาดูสถานการณ์สี่ประการที่ไม่มีการชนกันเกิดขึ้น
ดังที่แสดงด้านล่าง:
ต่อไปนี้เป็นคำตัดสินของสี่รัฐนี้:
อัปเดตฟังก์ชัน Interaect สลับสถานะที่ไม่ทับซ้อนกัน และส่งผ่านวัตถุ Rect และ Circle ให้กับฟังก์ชัน เมื่อวัตถุ Rect และวัตถุ Circle ทับซ้อนกัน ค่าจริงจะถูกส่งกลับ
รหัสมีดังนี้:
ฟังก์ชั่น 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 ที่นี่เราจะติดตามวัตถุวงกลมตามการเคลื่อนไหวของเมาส์ และตรวจจับการชนกับวัตถุสี่เหลี่ยมที่มีตำแหน่งคงที่
รหัสมีดังนี้:
ฟังก์ชั่น DrawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, canvas.width, canvas.height); if (ตัดกัน (สี่เหลี่ยม, วงกลม)){ console.log ('โต้ตอบ!!!!' } if(mouse.x){ วงกลม.x = mouse.x; วงกลม.y = mouse.y; } วงกลม.วาด(บริบท);3. การเริ่มต้น
อัปเดต Init.js เริ่มต้นวัตถุ Circle และวัตถุ Rect และสุดท้ายเริ่มวนซ้ำภาพเคลื่อนไหว
รหัสมีดังนี้:
window.onload = function () { canvas = document.getElementById('collCanvas'); บริบท = canvas.getContext('2d'); Capturemouse(canvas) = วงกลมใหม่ (100,100,100); ความกว้าง/2,canvas.height/2,100,100);
ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการศึกษาของทุกคน ฉันหวังว่าทุกคนจะสนับสนุน VeVb Wulin Network