To perform collision detection in Canvas, people often directly use the built-in collision detection function of the game engine (Cocos2d-JS, Egret) or physics engine (Box2D). Are you curious, have you ever thought about their internal operating mechanisms? The basic collision detection technology will be explained below:
1. Rectangle-based collision detectionThe so-called collision detection is to determine whether there is overlap between objects. Here we assume that the colliders discussed are all rectangular objects. In the following example, we will create two rect objects A and B (hereinafter referred to as A, B). The position of A is fixed and B moves with the mouse. When A and B overlap, the console will prompt intercect! !
1. Create a Rect objectHere we create a new Rect.js, create a Rect object and add a prototype method draw to it. This method will draw to the incoming canvas object (context) based on the properties (position, size) of the current object.
The code is as follows:
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); context.restore();}2. Get the mouse position
Because B needs to follow the mouse movement, we need to detect the current position of the mouse on the canvas. Create a Capturemouse function to detect mouse movement on the incoming document node (element) and return a mouse object (which contains the x, y coordinates of the mouse).
The code is as follows:
function Capturemouse (element) { 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; y -=element.offsetTop; mouse.x = x; mouse.y = y; },false); return mouse;}3. Collision detection
Detect whether A and B overlap. When discussing whether overlap occurs, we can first look at the four situations without overlap, as shown below:
The following is the judgment of these four states:
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
Now that we know how to judge the non-overlapping state, how to judge the overlapping state? That’s right, the opposite! , we create the function Interaect and add it to Init.js. This function passes in two Rect object parameters and will return true when the two Rect objects overlap.
The code is as follows:
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.width < rectA.x)}4. Animation loop
Create a new animationjs and set the requestAnimationFrame() animation function.
In the loop body, the following two things will be done:
The code is as follows:
function 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.y = mouse.y; } rectA.draw(context); rectB.draw(context);}
3. Initialization
Create a new Init.js, obtain the canvas element and bind mouse movement detection, initialize Rect objects A and B, and finally start the animation loop.
The code is as follows:
window.onload = function () { canvas = document.getElementById('collCanvas'); context = canvas.getContext('2d'); Capturemouse(canvas); rectA = new Rect(canvas.width/2,canvas.height/ 2,100,100); rectB = new Rect(100,100,100,100); drawAnimation();}2. Circle-based collision detection
After talking about rectangular collision, let's talk about circular collision. Similarly, we will create two Circle objects A and B (hereinafter referred to as A, B). The position of A is fixed, and B follows the mouse movement. When A and B overlap, the console Intercect will be prompted! !
1. Create a circle objectfunction Circle(x,y,radius) { this.x = x; this.y = y; this.radius = radius;}Circle.prototype.draw = function(context){ context.save(); context.translate( this.x,this.y); context.beginPath(); context.arc(0,0,this.radius,0,Math.PI*2,false); context.fill(); context.restore();}2. Detect circular collision
Collision detection between circles can be judged simply by comparing the distance between the centers of the two circles with the sum of the radii of the two circles. When the distance between the centers of the two circles is less than the sum of the radii of the two circles, a collision occurs.
As shown below:
So the first thing we need to do is to calculate the distance between the centers of the two circles. Here we will use the distance formula between two points, as follows:
When the distance between the centers of two circles is obtained, it will be compared with the sum of the radii of the two circles. If the distance is less than the sum of the radii, true will be returned.
Now we update the Interaect function.
The code is as follows:
function Intersect(circleA,circleB) { var dx = circleA.x-circleB.x; var dy = circleA.y-circleB.y; var distance = Math.sqrt(dx*dx+dy*dy); return distance < ( circleA.radius + circleB.radius);}3. Animation loop
Update animation.js, here we replace the Rect object with a Circle object.
The code is as follows:
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(context);}4. Initialization
Update Init.js, initialize Circle objects A and B, and finally start the animation loop.
The code is as follows:
window.onload = function () { canvas = document.getElementById('collCanvas'); context = canvas.getContext('2d'); Capturemouse(canvas); circleA = new Circle(canvas.width/2,canvas.height/ 2,100); circleB = new Circle(100,100,100); drawAnimation();}3. Based on collision detection between rectangle and circle
The previous explanations are about collision detection between single shapes. Next we will detect collisions between rectangles and circles.
1. Detect collision
As with rectangle detection, let's first look at the four situations where no collision occurs.
As shown below:
The following is the judgment of these four states:
Update the Interaect function, invert the non-overlapping state, and pass in the Rect object and Circle object to the function. When the Rect object and the Circle object overlap, true will be returned.
The code is as follows:
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.height || Circle.x + Circle.radius < Rect.x)}2. Animation loop
Update animation.js, here we follow the circle object to the mouse movement and detect collision with the fixed-position rect object.
The code is as follows:
function drawAnimation() { window.requestAnimationFrame(drawAnimation); context.clearRect(0, 0, canvas.width, canvas.height); if(Intersect(rect,circle)){ console.log('interact!!!!' ); } if(mouse.x){ circle.x = mouse.x; circle.y = mouse.y; } circle.draw(context); rect.draw(context);}3. Initialization
Update Init.js, initialize the Circle object and Rect object, and finally start the animation loop.
The code is as follows:
window.onload = function () { canvas = document.getElementById('collCanvas'); context = canvas.getContext('2d'); Capturemouse(canvas); circle = new Circle(100,100,100); rect = new Rect(canvas. width/2,canvas.height/2,100,100); drawAnimation();}
The above is the entire content of this article. I hope it will be helpful to everyone’s study. I also hope everyone will support VeVb Wulin Network.