首页前端开发HTMLHtml5 Canvas动画基础碰撞检测的实现

Html5 Canvas动画基础碰撞检测的实现

时间2024-01-25 00:01:16发布访客分类HTML浏览841
导读:收集整理的这篇文章主要介绍了Html5 Canvas动画基础碰撞检测的实现,觉得挺不错的,现在分享给大家,也给大家做个参考。 在Canvas中进行碰撞检测,大家往往直接采用游戏引擎(Cocos2d-JS、Egret 或物理引擎(B...
收集整理的这篇文章主要介绍了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(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()动画函数。

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

  • “清空”当前canvas中内容,为绘制下一帧做准备。
  • 检测A,B是否发生重叠,若重叠则在控制台输出interact!!!
  • 检测当前鼠标在canvas上的移动并将鼠标位置更新到B的位置属性中。
  • 根据新的位置属性重新绘制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、检测碰撞

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

如下图:

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

  • 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(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();
}
    

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

上一篇: html5+css如何实现中间大两头小的...下一篇:canvas压缩图片以及卡片制作的方...猜你在找的html5相关文章 关于移动端h5开发相关内容总结2022-05-17html5教程-学表单的第二天2018-12-10html5教程-HTML5浏览器支持2018-12-10html5教程-HTML5智能表单2018-12-10html5教程-微信H5使用resLoader实现加载页效果2018-12-10html5教程-day01-初级-JS0-热身运动JS入门教程2018-12-10html5教程-html5shiv.js和respond.min.js2018-12-10html5教程-不同浏览器对于html5 audio标签和音频格式的兼容性2018-12-10html5教程-使用Html5实现手风琴案例2018-12-10html5教程-html5笔记2018-12-10 其他相关热搜词更多phpjavapython程序员load

若转载请注明出处: Html5 Canvas动画基础碰撞检测的实现
本文地址: https://pptw.com/jishu/585904.html
canvas压缩图片以及卡片制作的方法示例 深入理解HTML5定时器requestAnimationFrame的使用

游客 回复需填写必要信息