Чтобы выполнить обнаружение столкновений в Canvas, люди часто напрямую используют встроенную функцию обнаружения столкновений игрового движка (Cocos2d-JS, Egret) или физического движка (Box2D). Вам интересно, задумывались ли вы когда-нибудь об их внутренних механизмах работы? Ниже будет описана основная технология обнаружения столкновений:
1. Обнаружение столкновений на основе прямоугольниковТак называемое обнаружение столкновений предназначено для определения наличия перекрытия между объектами. Здесь мы предполагаем, что все обсуждаемые коллайдеры являются прямоугольными объектами. В следующем примере мы создадим два прямоугольных объекта A и B (далее именуемые A, B). Положение A фиксировано, а B перемещается с помощью мыши. Когда A и B перекрываются, консоль выдает сообщение «перекреститься». !
1. Создайте объект Rect.Здесь мы создаем новый Rect.js, создаем объект Rect и добавляем к нему прототип метода draw. Этот метод будет рисовать входящий объект холста (контекст) на основе свойств (положения, размера) текущего объекта.
Код выглядит следующим образом:
function Rect(x,y,width,height) { this.x = x; this.y = y; this.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. Получите положение мыши
Поскольку B необходимо следить за движением мыши, нам необходимо определить текущее положение мыши на холсте. Создайте функцию Capturemouse для обнаружения движения мыши на узле (элементе) входящего документа и возврата объекта мыши (который содержит координаты мыши x, y).
Код выглядит следующим образом:
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; }, false); вернуть мышь;}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 и возвращает true, когда два объекта Rect перекрываются.
Код выглядит следующим образом:
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. Цикл анимации
Создайте новый файл анимации и установите функцию анимации requestAnimationFrame().
В теле цикла будут выполнены следующие две вещи:
Код выглядит следующим образом:
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(контекст); rectB.draw(контекст);}
3. Инициализация
Создайте новый Init.js, получите элемент холста и привяжите обнаружение движения мыши, инициализируйте объекты Rect A и B и, наконец, запустите цикл анимации.
Код выглядит следующим образом:
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 = новый прямоугольник (100 100 100 100); рисоватьАнимацию();}2. Обнаружение столкновений по кругу
После разговора о прямоугольном столкновении давайте поговорим о круговом столкновении. Аналогичным образом мы создадим два объекта Circle A и B (далее называемые A, B). Положение A фиксировано, и 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. Обнаружение кругового столкновения
Об обнаружении столкновения между кругами можно судить просто путем сравнения расстояния между центрами двух кругов с суммой радиусов двух кругов, когда расстояние между центрами двух кругов меньше суммы радиусов. два круга, происходит столкновение.
Как показано ниже:
Итак, первое, что нам нужно сделать, это вычислить расстояние между центрами двух кругов. Здесь мы будем использовать формулу расстояния между двумя точками следующим образом:
Когда расстояние между центрами двух кругов будет получено, оно будет сравниваться с суммой радиусов двух кругов. Если расстояние меньше суммы радиусов, будет возвращено значение 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); кругА.радиус + кругБ.радиус);}3. Цикл анимации
Обновите анимацию.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); кругB.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/); 2100); кругB = новый круг (100,100,100);3. На основе обнаружения столкновений между прямоугольником и кругом.
Предыдущие объяснения касаются обнаружения столкновений между отдельными фигурами. Далее мы обнаружим столкновения между прямоугольниками и кругами.
1. Обнаружить столкновение
Как и в случае с обнаружением прямоугольников, давайте сначала рассмотрим четыре ситуации, в которых столкновений не происходит.
Как показано ниже:
Ниже приводится решение этих четырех государств:
Обновите функцию 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 + Rect.height || Circle.x + Circle.radius < Rect.x)}2. Цикл анимации
Обновите файл анимации.js, здесь мы следуем за движением мыши за объектом-кругом и обнаруживаем столкновение с объектом-прямоугольником с фиксированным положением.
Код выглядит следующим образом:
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. Инициализация
Обновите Init.js, инициализируйте объекты Circle и Rect и, наконец, запустите цикл анимации.
Код выглядит следующим образом:
window.onload = function () {canvas = document.getElementById('collCanvas'); context = Canvas.getContext('2d'); Circle = new Circle(100,100,100); ширина/2,canvas.height/2,100,100; drawAnimation();}
Выше приведено все содержание этой статьи. Я надеюсь, что она будет полезна для изучения всеми. Я также надеюсь, что все поддержат сеть VeVb Wulin.