Para realizar la detección de colisiones en Canvas, las personas a menudo usan directamente la función de detección de colisiones incorporada del motor del juego (Cocos2d-JS, Egret) o del motor de física (Box2D). ¿Tienes curiosidad? ¿Alguna vez has pensado en sus mecanismos operativos internos? La tecnología básica de detección de colisiones se explicará a continuación:
1. Detección de colisiones basada en rectángulosLa llamada detección de colisiones es para determinar si hay superposición entre objetos. Aquí asumimos que los colisionadores discutidos son todos objetos rectangulares. En el siguiente ejemplo, crearemos dos objetos rectos A y B (en lo sucesivo, A, B. La posición de A es fija y B se mueve con el mouse. Cuando A y B se superponen, la consola solicitará intercect. !
1. Crea un objeto RectAquí creamos un nuevo Rect.js, creamos un objeto Rect y le agregamos un método prototipo. Este método dibujará en el objeto de lienzo entrante (contexto) en función de las propiedades (posición, tamaño) del objeto actual.
El código es el siguiente:
función Rect(x,y,ancho,alto) { this.x = x; this.y = y; this.width = ancho; this.height = height;}Rect.prototype.draw = function(context){ contexto. guardar(); contexto.translate(este.x,este.y); contexto.fillRect(0,0,este.ancho,este.alto.restore();}2. Obtener la posición del mouse
Debido a que B necesita seguir el movimiento del mouse, debemos detectar la posición actual del mouse en el lienzo. Cree una función Capturemouse para detectar el movimiento del mouse en el nodo (elemento) del documento entrante y devolver un objeto del mouse (que contiene las coordenadas x, y del mouse).
El código es el siguiente:
function Capturemouse (elemento) { var mouse={x:null,y:null}; element.addEventListener('mousemove',function (evento) { var x, y; if(event.pageX || event.pageY){ x = evento.páginaX; y = evento.páginaY }else{ x = evento.clienteX+document.body.scrollLeft+ document.documentElement.scrollLeft; y = event.clientY+document.body.scrollTop+ document.documentElement.scrollTop; } x -=element.offsetLeft; },falso); devolver ratón;}3. Detección de colisiones
Detectar si A y B se superponen Al discutir si se produce una superposición, primero podemos observar las cuatro situaciones sin superposición, como se muestra a continuación:
El siguiente es el juicio de estos cuatro estados:
1. rectB.y+rectB.altura < rectA.y
2. rectB.y > rectA.x +rectA.ancho
3. rectB.y > rectA.y + rectA.altura
4. rectB.x+rectB.ancho < rectA.x
Ahora que sabemos cómo juzgar el estado no superpuesto, ¿cómo juzgar el estado superpuesto? ¡Así es, todo lo contrario! , creamos la función Interaect y la agregamos a Init.js. Esta función pasa dos parámetros del objeto Rect y devolverá verdadero cuando los dos objetos Rect se superpongan.
El código es el siguiente:
function 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.ancho < rectA.x)}4. Bucle de animación
Cree un nuevo AnimationJS y configure la función de animación RequestAnimationFrame().
En el cuerpo del bucle, se harán las dos cosas siguientes:
El código es el siguiente:
function drawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, canvas.width, canvas.height); if(Intersect(rectA,rectB)){ console.log('interactuar!!!!' ); } if(mouse.x){ rectB.x = mouse.x; rectB.y = mouse.y } rectA.draw(contexto); rectB.draw(contexto);}
3. Inicialización
Cree un nuevo Init.js, obtenga el elemento lienzo y vincule la detección de movimiento del mouse, inicialice los objetos Rect A y B y finalmente inicie el ciclo de animación.
El código es el siguiente:
ventana.onload = función () { lienzo = document.getElementById('collCanvas'); contexto = lienzo.getContext('2d'); Capturemouse(lienzo) = nuevo Rect(canvas.width/2,canvas.height/ 2,100,100); rectB = nuevo Rect(100,100,100,100); dibujarAnimación();}2. Detección de colisiones basada en círculos
Después de hablar de colisión rectangular, hablemos de colisión circular. De manera similar, crearemos dos objetos circulares A y B (en lo sucesivo, A y B). La posición de A es fija y B sigue el movimiento del mouse. B se superpone, se le solicitará Intercect en la consola. !
1. Crea un objeto circular.función Círculo(x,y,radio) { this.x = x; this.y = y; this.radius = radio;}Círculo.prototipo.draw = función(contexto){ contexto.save(); this.x,this.y); contexto.beginPath(); contexto.arc(0,0,this.radius,0,Math.PI*2,false); contexto.restaurar();}2. Detectar colisión circular
La detección de colisiones entre círculos se puede juzgar simplemente comparando la distancia entre los centros de los dos círculos con la suma de los radios de los dos círculos cuando la distancia entre los centros de los dos círculos es menor que la suma de los radios de los dos círculos. dos círculos, se produce una colisión.
Como se muestra a continuación:
Entonces, lo primero que debemos hacer es calcular la distancia entre los centros de los dos círculos. Aquí usaremos la fórmula de distancia entre dos puntos, de la siguiente manera:
Cuando se obtiene la distancia entre los centros de dos círculos, se comparará con la suma de los radios de los dos círculos. Si la distancia es menor que la suma de los radios, se devolverá verdadero.
Ahora actualizamos la función Interaect.
El código es el siguiente:
function Intersect(circleA,circleB) { var dx = circuloA.x-circleB.x; var dy = circuloA.y-circleB.y; var distancia = Math.sqrt(dx*dx+dy*dy); círculoA.radio + círculoB.radio);}3. Bucle de animación
Actualice Animation.js, aquí reemplazamos el objeto Rect con un objeto Circle.
El código es el siguiente:
function drawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, canvas.width, canvas.height); if(Intersect(circleA,circleB)){ console.log('interactuar!!!!' } if(mouse.x){ círculoB.x = mouse.x; círculoB.y = mouse.y } círculoA.draw(contexto); circuloB.draw(contexto);}4. Inicialización
Actualice Init.js, inicialice los objetos Circle A y B y finalmente inicie el ciclo de animación.
El código es el siguiente:
window.onload = function () { canvas = document.getElementById('collCanvas'); contexto = canvas.getContext('2d'); Capturemouse(canvasA = new Circle(canvas.width/2,canvas.height/); 2,100); círculoB = nuevo Círculo(100,100,100); dibujarAnimación();}3. Basado en la detección de colisiones entre rectángulo y círculo.
Las explicaciones anteriores tratan sobre la detección de colisiones entre formas individuales. A continuación detectaremos colisiones entre rectángulos y círculos.
1. Detectar colisión
Al igual que con la detección de rectángulos, veamos primero las cuatro situaciones en las que no se produce ninguna colisión.
Como se muestra a continuación:
El siguiente es el juicio de estos cuatro estados:
Actualice la función Interaect, invierta el estado no superpuesto y pase el objeto Rect y el objeto Circle a la función. Cuando el objeto Rect y el objeto Circle se superpongan, se devolverá verdadero.
El código es el siguiente:
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 + Rect.altura || Círculo.x + Círculo.radio < Rect.x)}2. Bucle de animación
Actualice Animation.js, aquí seguimos el objeto circular hasta el movimiento del mouse y detectamos la colisión con el objeto recto de posición fija.
El código es el siguiente:
function drawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, canvas.width, canvas.height); if(Intersect(rect,circle)){ console.log('interactuar!!!!' ); } if(mouse.x){ círculo.x = mouse.x; círculo.y = mouse.y } círculo.draw(contexto);3. Inicialización
Actualice Init.js, inicialice el objeto Circle y el objeto Rect y finalmente inicie el ciclo de animación.
El código es el siguiente:
ventana.onload = función () { lienzo = document.getElementById('collCanvas'); contexto = lienzo.getContext('2d'); círculo = nuevo Círculo(100,100,100); ancho/2,canvas.height/2,100,100); drawAnimation();}
Lo anterior es el contenido completo de este artículo. Espero que sea útil para el estudio de todos. También espero que todos apoyen VeVb Wulin Network.