百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Html5 Canvas动画基础(碰撞检测)(js碰撞检测 不规则图形)

toyiye 2024-04-04 11:27 20 浏览 0 评论

在Canvas中进行碰撞检测,大家往往直接采用游戏引擎(Cocos2d-JS、Egret)或物理引擎(Box2D)内置的碰撞检测功能,好奇的你有思考过它们的内部运行机制吗?下面将针对基本的碰撞检测技术进行讲解:

1、基于矩形的碰撞检测

所谓碰撞检测就是判断物体间是否发生重叠,这里我们假设讨论的碰撞体都是矩形物体。下面示例中我们将创建两个rect对象A和B(以下简称A,B),其中A位置固定,B跟随鼠标移动,当A,B重叠时控制台将提示intercect!!

1、创建Rect对象

这里我们新建Rect.js,建立Rect对象并为其添加原型方法draw,该方法将根据当前对象的属性(位置、大小)绘制到传入的画布对象(context)中。

代码如下 :

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、获取鼠标位置

因为B需要跟随鼠标移动所以我们需要检测鼠标在画布的当前位置。创建Capturemouse函数检测鼠标在传入的文档节点(element)上的移动并返回一个mouse对象(其中包含了鼠标的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;
 mouse.y = y;
 },false);
 return mouse;
}

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对象发生重叠将返回true。

代码如下:

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、动画循环

新建animationjs,设置requestAnimationFrame()动画函数。

在循环体中将做以下两件事:

  1. “清空”当前canvas中内容,为绘制下一帧做准备。
  2. 检测A,B是否发生重叠,若重叠则在控制台输出interact!!!
  3. 检测当前鼠标在canvas上的移动并将鼠标位置更新到B的位置属性中。
  4. 根据新的位置属性重新绘制A,B(当然,A的位置不会更新但因为每次循环将清空canvas所以需要重新绘制)

代码如下:

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、初始化

新建Init.js ,获取canvas元素并绑定鼠标移动检测,初始化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 = new Rect(100,100,100,100);
 drawAnimation();
}

2、基于圆形的碰撞检测

说完矩形碰撞,我们再来聊聊圆形碰撞,同样我们将创建两个Circle对象A和B(以下简称A,B),其中A位置固定,B跟随鼠标移动,当A,B重叠时控制台将提示intercect!!

1、创建circle对象

function 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、检测圆形碰撞

圆形间碰撞检测可以简单地通过两圆心间距离与两圆半径之和的比较做判断,当两圆心距离小于两圆半径之和时则发生碰撞。

如下图:

所以我们首先需要做的是计算出两圆心间的距离,这里我们将用到两点间的距离公式,如下:

当取得两圆心间的距离之后将与两圆半径之和比较,如果距离小于半径之和则返回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);
 return distance < (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(context);
}

4、初始化

更新Init.js ,初始化Circle对象A和B,最后开启动画循环。

代码如下:

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、基于矩形与圆形间的碰撞检测

前面讲解都是单一形状间的碰撞检测,下面我们将检测矩形和圆形间的碰撞。

1、检测碰撞

和矩形检测一样,我们先看看没有发生碰撞的四种情况。

如下图:

以下是对这四种状态的判断:

  1. Circle.y + Circle.radius < Rect.y
  2. Circle.x - Circle.radius > Rect.x + Rect.width
  3. Circle.y - Circle.radius > Rect.y + Rect.height
  4. Circle.x + Circle.radius < Rect.x

更新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、动画循环

更新animation.js,这里我们将circle对象跟随鼠标运动,并检测与固定位置的rect对象的碰撞。

代码如下:

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');
 Capturemouse(canvas);
 circle = new Circle(100,100,100);
 rect = new Rect(canvas.width/2,canvas.height/2,100,100);
 drawAnimation();
}

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码