Canvas에서 충돌 감지를 수행하기 위해 사람들은 게임 엔진(Cocos2d-JS, Egret) 또는 물리 엔진(Box2D)에 내장된 충돌 감지 기능을 직접 사용하는 경우가 많습니다. 내부 작동 메커니즘에 대해 생각해 본 적이 있습니까? 기본적인 충돌 감지 기술은 다음과 같습니다.
1. 직사각형 기반 충돌 감지소위 충돌 감지는 객체 사이에 겹침이 있는지 확인하는 것입니다. 여기서 논의되는 충돌체는 모두 직사각형 객체라고 가정합니다. 다음 예에서는 두 개의 직사각형 객체 A와 B(이하 A, B라고 함)를 생성합니다. A의 위치는 고정되고 B는 마우스로 이동합니다. A와 B가 겹치면 콘솔에 intercect!가 표시됩니다. !
1. Rect 객체 생성여기서는 새로운 Rect.js를 생성하고 Rect 객체를 생성한 후 여기에 draw 프로토타입 메소드를 추가합니다. 이 메소드는 현재 객체의 속성(위치, 크기)을 기반으로 들어오는 캔버스 객체(컨텍스트)를 그립니다.
코드는 다음과 같습니다:
function Rect(x,y,width,height) { this.x = x; this.y = y; this.height = height;}Rect.prototype.draw = function(context){ 컨텍스트. save(); context.translate(this.x,this.y); context.fillRect(0,0,this.width,this.height); 2. 마우스 위치 가져오기B는 마우스 움직임을 따라야 하기 때문에 캔버스에서 마우스의 현재 위치를 감지해야 합니다. 들어오는 문서 노드(요소)에서 마우스 움직임을 감지하고 마우스 개체(마우스의 x, y 좌표가 포함됨)를 반환하는 Capturemouse 함수를 만듭니다.
코드는 다음과 같습니다:
function 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.clientY+document.body.scrollTop+ document.documentElement.scrollTop; } x -=element.offsetLeft; mouse.x = mouse.y = y; }, false) 마우스 반환;} 3. 충돌 감지A와 B의 중첩 여부를 감지하면 중첩이 발생하는지 여부를 논의할 때 먼저 아래와 같이 중첩되지 않는 네 가지 상황을 살펴볼 수 있습니다.
이들 4개 주의 판결은 다음과 같다.
1. 렉트B.y+렉트B.높이 < 렉A.y
2. 렉트B.y > 렉A.x +렉트A.폭
3. RECB.Y > RECA.Y + RECA.높이
4. 렉트B.x+렉트B.폭 < 렉트A.x
이제 겹치지 않는 상태를 판단하는 방법을 알았으니, 겹치는 상태를 어떻게 판단할까요? 맞아요, 그 반대예요! , Interaect 함수를 생성하여 Init.js에 추가합니다. 이 함수는 두 개의 Rect 개체 매개변수를 전달하고 두 개의 Rect 개체가 겹칠 때 true를 반환합니다.
코드는 다음과 같습니다:
function Intersect(ectA,ectB) { return !(ectB.y+ectB.height < ectA.y || retB.y > retA.x +ectA.width || retB.y > retA.y + retA.height|| 렉트B.x+렉트B.너비 < 렉트A.x)} 4. 애니메이션 루프새로운 animationjs를 생성하고 requestAnimationFrame() 애니메이션 기능을 설정하세요.
루프 본문에서는 다음 두 가지 작업이 수행됩니다.
코드는 다음과 같습니다:
function drawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, canvas.width, canvas.height); if(Intersect(ectA,ectB)){ console.log('interact!!!!' ); } if(mouse.x){ retB.x = mouse.x; retB.y = mouse.y } retA.draw(context); retB.draw(컨텍스트);}3. 초기화
새로운 Init.js를 생성하고, 캔버스 요소를 얻고, 마우스 움직임 감지를 바인딩하고, Rect 객체 A와 B를 초기화하고, 마지막으로 애니메이션 루프를 시작합니다.
코드는 다음과 같습니다:
window.onload = function () { canvas = document.getElementById('collCanvas'); context = canvas.getContext('2d'); Capturemouse(canvas) = new Rect(canvas.width/2,canvas.height/ 2,100,100); 렉트B = 새로운 렉트(100,100,100,100); drawAnimation();} 2. 원 기반 충돌 감지직사각형 충돌에 대해 이야기한 후, 마찬가지로 원형 충돌에 대해 이야기하겠습니다. A와 B(이하 A, B)의 위치는 고정되어 있고 A와 B는 마우스 움직임을 따릅니다. B 오버랩, 콘솔 Intercect가 프롬프트됩니다! !
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); context.restore();} 2. 원형 충돌 감지원 사이의 충돌 감지는 두 원의 중심 사이의 거리를 두 원의 반지름의 합과 비교함으로써 간단하게 판단할 수 있습니다. 두 원, 충돌이 발생합니다.
아래와 같이:
따라서 가장 먼저 해야 할 일은 두 원의 중심 사이의 거리를 계산하는 것입니다. 여기서는 다음과 같이 두 점 사이의 거리 공식을 사용합니다.
두 원의 중심 사이의 거리를 구하면 두 원의 반지름의 합과 비교하여 거리가 반지름의 합보다 작으면 true가 반환됩니다.
이제 Interaect 기능을 업데이트합니다.
코드는 다음과 같습니다:
function Intersect(circleA,circleB) { var dx = CircleA.x-circleB.x; var dy = CircleA.y-circleB.y; var distance = Math.sqrt(dx*dx+dy*dy); CircleA.radius + CircleB.radius);} 3. 애니메이션 루프animation.js를 업데이트합니다. 여기서는 Rect 개체를 Circle 개체로 바꿉니다.
코드는 다음과 같습니다:
function drawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, canvas.width, canvas.height); if(Intersect(circleA,circleB)){ console.log('interact!!!!' ); } if(mouse.x){ CircleB.x = mouse.x; CircleB.y = mouse.y } CircleA.draw(context); CircleB.draw(컨텍스트);} 4. 초기화Init.js를 업데이트하고 Circle 개체 A와 B를 초기화한 다음 마지막으로 애니메이션 루프를 시작합니다.
코드는 다음과 같습니다:
window.onload = function () { canvas = document.getElementById('collCanvas'); context = canvas.getContext('2d'); CircleA = new Circle(canvas.width/2,canvas.height/ 2,100); CircleB = new Circle(100,100,100); 3. 직사각형과 원 사이의 충돌 감지 기반이전 설명은 단일 도형 간의 충돌 감지에 관한 것입니다. 다음으로 직사각형과 원 간의 충돌을 감지하겠습니다.
1. 충돌 감지
직사각형 감지와 마찬가지로 먼저 충돌이 발생하지 않는 네 가지 상황을 살펴보겠습니다.
아래와 같이:
이들 4개 주의 판결은 다음과 같다.
Interaect 함수를 업데이트하고, 겹치지 않는 상태를 반전시키고, Rect 객체와 Circle 객체를 함수에 전달합니다. Rect 객체와 Circle 객체가 겹치면 true가 반환됩니다.
코드는 다음과 같습니다:
function Intersect(Rect,Circle) { return !(Circle.y + Circle.radius < Rect.y || Circle.x - Circle.radius > Rect.x + Rect.width || Circle.y - Circle.radius > Rect .y + 직사각형 높이 || Circle.x + Circle.radius < Rect.x)} 2. 애니메이션 루프animation.js를 업데이트합니다. 여기서는 원 개체를 따라 마우스 움직임을 따라가며 고정 위치 사각형 개체와의 충돌을 감지합니다.
코드는 다음과 같습니다:
function drawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, canvas.width, canvas.height); if(Intersect(ect,circle)){ console.log('interact!!!!' ); } if(mouse.x){ Circle.x = mouse.x; Circle.y = mouse.y; } Circle.draw(context); 3. 초기화Init.js를 업데이트하고 Circle 개체와 Rect 개체를 초기화한 다음 마지막으로 애니메이션 루프를 시작합니다.
코드는 다음과 같습니다:
window.onload = function () { canvas = document.getElementById('collCanvas'); context = canvas.getContext('2d'); Capturemouse(canvas); Circle = new Circle(100,100,100); 너비/2,canvas.height/2,100,100);위의 내용은 이 기사의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다. 또한 모든 분들이 VeVb Wulin Network를 지지해 주시길 바랍니다.