Html5 Canvas动画基础碰撞检测的实现
在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(,,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()动画函数。
在循环体中将做以下两件事:
“清空”当前canvas中内容,为绘制下一帧做准备。
检测A,B是否发生重叠,若重叠则在控制台输出interact!!!
检测当前鼠标在canvas上的移动并将鼠标位置更新到B的位置属性中。
根据新的位置属性重新绘制A,B(当然,A的位置不会更新但因为每次循环将清空canvas所以需要重新绘制)
代码如下:
function drawAnimation() {
window.requestAnimationFrame(drawAnimation);
context.clearRect(, , 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/,canvas.height/,,);
rectB = new Rect(,,,);
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(,,this.radius,,Math.PI*,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(, , 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/,canvas.height/,);
circleB = new Circle(,,);
drawAnimation();
}
3、基于矩形与圆形间的碰撞检测
前面讲解都是单一形状间的碰撞检测,下面我们将检测矩形和圆形间的碰撞。
1、检测碰撞
和矩形检测一样,我们先看看没有发生碰撞的四种情况。
如下图:
以下是对这四种状态的判断:
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
更新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(, , 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(,,);
rect = new Rect(canvas.width/,canvas.height/,,);
drawAnimation();
}
相信很多人在刚接触前端或者中期时候总会遇到一些问题及瓶颈期,如学了一段时间没有方向感或者坚持不下去一个人学习枯燥乏味有问题也不知道怎么解决,对此我整理了一些资料 喜欢我的文章想与更多资深大牛一起讨论和学习的话 欢迎加入我的学习交流群907694362
Html5 Canvas动画基础碰撞检测的实现的更多相关文章
- [js高手之路]html5 canvas动画教程 - 边界判断与小球粒子模拟喷泉,散弹效果
备注:本文后面的代码,如果加载了ball.js,那么请使用这篇文章[js高手之路] html5 canvas动画教程 - 匀速运动的ball.js代码. 本文,我们要做点有意思的效果,首先,来一个简单 ...
- HTML5+JavaScript动画基础 完整版 中文pdf扫描版
<HTML5+JavaScript动画基础>包括了基础知识.基础动画.高级动画.3D动画和其他技术5大部分,分别介绍了动画的基本概念.动画的JavaScript基础.动画中的三角学.渲染技 ...
- 7 个顶级的 HTML5 Canvas 动画赏析
HTML5确实是一项改革浏览器乃至整个软件行业的新技术,它可以帮助我们Web开发者很方便地在网页上实现动画特效,而无需臃肿的Flash作为支撑.本文分享7个顶级的HTML5 Canvas 动画,都有非 ...
- 8个经典炫酷的HTML5 Canvas动画欣赏
HTML5非常强大,尤其是Canvas技术的应用,让HTML5几乎可以完成所有Flash能完成的效果.本文精选了8个经典炫酷的HTML5 Canvas动画欣赏,每一个都提供全部的源代码,希望对你有所帮 ...
- 7个惊艳的HTML5 Canvas动画效果及源码
HTML5非常强大,尤其是现在大部分浏览器都支持HTML5和CSS3,用HTML5制作的动画也多了起来.另外,Canvas上绘制图形非常简单,本文就分享了一些强大的HTML5 Cnavas动画,一起来 ...
- Html5 Canvas动画旋转的小方块;
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- HTML5 Canvas动画效果演示
HTML5 Canvas动画效果演示 主要思想: 首先要准备一张有连续帧的图片,然后利用HTML5 Canvas的draw方法在不同的时间 间隔绘制不同的帧,这样看起来就像动画在播放. 关键技术点: ...
- HTML5 Canvas动画效果演示 - 流浪的鱼 - 博客频道 - CSDN.NET
HTML5 Canvas动画效果演示 - 流浪的鱼 - 博客频道 - CSDN.NET HTML5 Canvas动画效果演示
- HTML5 Canvas动画效果实现原理
在线演示 使用HTML5画布可以帮助我们高速实现简单的动画效果.基本原理例如以下: 每隔一定时间绘制图形而且清除图形,用来模拟出一个动画过程,能够使用context.clearRect(0, 0, x ...
随机推荐
- netcore 创建腾讯云私有镜像 发布到docker 实战
上一篇博客写的 netcoer上传到docker ,编译 并发布,传送门:FineUICore基础版部署到docker实战 这是一种笨方法,理想的方法是,在本地编译成镜像,然后推送到镜像仓库,服务器的 ...
- JPA中实现双向一对一的关联关系
场景 JPA入门简介与搭建HelloWorld(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103473937 ...
- 4.Android-adt安卓打包过程、adb指令学习
本章学习adt安卓打包过程.adb指令学习.并通过adb将打包的APK发给设备 1.打包 在eclipse中已经帮我们实现打包了. 具体打包流程如下: 最终一个APK包含了如下: classes.de ...
- javascript中的对象拷贝
js中的数据类型 在介绍javascript中的对象的拷贝之前,我先介绍一个基础的东西,javascript中的数据类型. 我们做前端的应该都知到在es6 之前,javascript中的数据类型Boo ...
- TCPUDPDbg(TCP UDP 网络调试工具)
下载链接:https://pan.baidu.com/s/1oan44qop73X5VuBcE-rjeA 提取码:v0oa
- 字符串模式匹配——KMP算法
KMP算法匹配字符串 朴素匹配算法 字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就 ...
- Java源码记录 - AbstractMap
路径java.util.AbstractMap ()构造方法 /** * 唯一的构造器.(一般由子类隐式调用) */ protexted AbstractMap(){ } size()返回当前map的 ...
- Cookie插件的使用
jQuery-cookie插件的使用 什么是插件? 基于jQuery的语法,按照一定规范书写,具有特定功能的脚本文件,称为插件. 插件除了js文件之外,有的还包含css文件,图片和字体等资源文件. 在 ...
- 从零开始学vuejs
最近一段时间都花在了学习vue上,还总是断断续续的,学习的效果不是很明显,思考了好久了,应该是没有进行一个系统的总结,导致很多知识点总是似是而非,而且也有一部分是思维还没有从java转变过来,废话不多 ...
- 百度地图API 拖拽或点击地图位置获取坐标
function setPlace(map,myValue,callback){ function getAddress(){ var pp = local.getResults().getPoi(0 ...