canvas 碰撞反弹

作者: 放飞吧自我 | 来源:发表于2017-12-28 20:52 被阅读25次

之前我们学习js的时候都写过碰撞反弹,canvas里的碰撞反弹也可以用同样的条件判断,现在我们回顾一下之前的判断

外接矩形碰撞

4C4433E2-72F6-49FD-8429-3A39A65B5945.png

我们根据上面的判断来写一下效果

var canvas = document.getElementById("mycanvas");
var context = canvas.getContext("2d");
        

运动方块的构造函数

        function Rect(x,y,w,h,color,speedx,speedy){
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
            this.color = color;
            this.speedx = speedx;
            this.speedy = speedy;
        }
        Rect.prototype.draw=function(){
            context.beginPath();
            context.fillStyle = this.color;
            context.fillRect(this.x,this.y,this.w,this.h);
        }
        Rect.prototype.move=function(){
            this.x +=this.speedx;
            this.y +=this.speedy;
            //碰壁检测
            if(this.x<0||this.x>canvas.width-this.w){
                this.speedx *=-1;
            }
            if(this.y<0||this.y>canvas.height-this.h){
                this.speedy *=-1;
            }
        }

实例化方块,运动的函数

方式一:通过判断方块位置
        var rect1 = new Rect(0,0,50,50,"green",1,3)
        var rect2 = new Rect(450,0,50,50,"red",2,4)
        function act1(){
            context.clearRect(0,0,canvas.width,canvas.height);
            rect1.draw();
            rect1.move();
            rect2.draw();
            rect2.move();
            //碰撞检测
            if((rect1.x+rect1.w)>rect2.x&&rect1.x<(rect2.x+rect2.w) && (rect1.y+rect1.h)>rect2.y&&rect1.y<(rect2.y+rect2.h)){
                console.log(11111111111)
                rect1.speedx *=-1;
                rect1.speedy *=-1;
                rect2.speedx *=-1;
                rect2.speedy *=-1;
            }
                      window.requestAnimationFrame(act1);
        }
        act1()
通过判断方块是否重叠
var rect1 = new Rect(0,0,50,50,"green",1,3)
        var rect2 = new Rect(450,0,50,50,"red",2,4)
        function act1(){
            context.clearRect(0,0,canvas.width,canvas.height);
            rect1.draw();
            rect1.move();
            rect2.draw();
            rect2.move();
            //像素碰撞
            if(isCrash(rect1,rect2)){
                console.log(22222222)
                rect1.speedx *=-1;
                rect1.speedy *=-1;
                rect2.speedx *=-1;
                rect2.speedy *=-1;
            };
            window.requestAnimationFrame(act1);
        }
        act1()
        
        function isCrash(rect1,rect2){
            var min1x = rect1.x;
            var max1x = rect1.x+rect1.w;
            var min2x = rect2.x;
            var max2x = rect2.x+rect2.w;
            
            var min1y = rect1.y;
            var max1y = rect1.y+rect1.h;
            var min2y = rect2.y;
            var max2y = rect2.y+rect2.h;
            
            //假设碰撞出新的方块
            var nminx = Math.max(min1x,min2x);
            var nmaxx = Math.min(max1x,max2x);
            
            var nminy = Math.max(min1y,min2y);
            var nmaxy = Math.min(max1y,max2y);
            
            if(nmaxx >nminx && nmaxy>nminy){
                return true;
            }
        }

外接圆碰撞

480C32A5-3801-4BF2-B936-864601260910.png
var canvas = document.getElementById("mycanvas");
        var context = canvas.getContext("2d");
        
        function Ball(x,y,r,color,speedx,speedy){
            this.x = x;
            this.y = y;
            this.r = r;
            this.color = color;
            this.speedx = speedx;
            this.speedy = speedy;
        }
        Ball.prototype.draw=function(){
            context.beginPath();
            context.fillStyle = this.color;
            context.arc(this.x,this.y,this.r,0,Math.PI*2);
            context.fill();
        }
        Ball.prototype.move=function(){
            this.x +=this.speedx;
            this.y +=this.speedy;
            //碰壁检测
            if(this.x<this.r||this.x>canvas.width-this.r){
                this.speedx *=-1;
            }
            if(this.y<this.r||this.y>canvas.height-this.r){
                this.speedy *=-1;
            }
        }
        var Ball1 = new Ball(50,50,25,"green",1,3)
        var Ball2 = new Ball(450,50,20,"red",2,4)
        function act1(){
            context.clearRect(0,0,canvas.width,canvas.height);
            Ball1.draw();
            Ball1.move();
            Ball2.draw();
            Ball2.move();
            
            //碰撞检测
            if(Math.pow(Ball1.x-Ball2.x,2)+Math.pow(Ball1.y-Ball2.y,2)<Math.pow(Ball1.r+Ball2.r,2)){
                Ball1.speedx *=-1;
                Ball1.speedy *=-1;
                Ball2.speedx *=-1;
                Ball2.speedy *=-1;
            }
            window.requestAnimationFrame(act1);
        }
        act1()

最后显示:

QQ20171228-204510-HD.gif

像素碰撞

F43640B5-94DF-49B0-89A5-3E7A2A8BA681.png

还存在一种碰撞叫做像素的碰撞,虽然图像所在矩形碰撞,但是不代表图像之间发生碰撞;
我们需要检测图像所在矩形是否相较,同时检测两图在相交矩形内的像素,存在一点在两个图上的 alpha 值不为 0,则发生碰撞。

我们利用上面矩形碰撞的方式二来写像素碰撞,方式一我们不能得到重叠的矩形

var canvas = document.getElementById("mycanvas");
        var context = canvas.getContext("2d");
        var img = new Image();
        img.src = "Chat.png";
        var play = new Image();
        play.src = "Play.png";
        img.onload = function(){
            context.beginPath();
            context.drawImage(img,100,100);
            var rect1 = new Rect(100,100,img.width,img.height);
            canvas.onmousedown = function(){
                canvas.onmousemove = function(e){
                    var ev = e||window.event;
                    var x = ev.clientX-canvas.offsetLeft;
                    var y = ev.clientY-canvas.offsetTop;
                    context.clearRect(0,0,canvas.width,canvas.height);
                    context.drawImage(play,x,y)
//                  context.drawImage(play,x-play.width/2,y-(play.height/2))
                    var rect2 = new Rect(x,y,play.width,play.height);
                    //实例化
                    context.drawImage(img,100,100);
                    var res = isCrash(rect1,rect2)
                    if(res.judge){
                        var newRect = res.rect;
                        //分别遍历碰撞区域的像素点
                        //清除某一区域的画布
                        context.clearRect(0,0,canvas.width,canvas.height)
                        //画蓝色图
                        context.drawImage(img,100,100);
                        //获取蓝图的像素点
                        var imgData1 = context.getImageData(res.rect.x,res.rect.y,res.rect.w,res.rect.h);
                        
                        context.clearRect(0,0,canvas.width,canvas.height)
                        //画绿色图
                        context.drawImage(play,x,y);
                        //获取绿色图的像素点
                        var imgData2 = context.getImageData(res.rect.x,res.rect.y,res.rect.w,res.rect.h);
                        context.drawImage(img,100,100);
                        for(var i=0;i<imgData1.data.length;i+=4){
                            if(imgData1.data[i+3]>0 && imgData2.data[i+3]>0){
                                console.log("像素碰撞了")
                                break;
                            }
                        }
                    };
                }
            }
        }
        canvas.onmouseup =function (){
            canvas.onmousemove = null;
        }
        function Rect(x,y,w,h){
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
        }
        function isCrash(rect1,rect2){
            var min1x = rect1.x;
            var max1x = rect1.x+rect1.w;
            var min2x = rect2.x;
            var max2x = rect2.x+rect2.w;
            
            var min1y = rect1.y;
            var max1y = rect1.y+rect1.h;
            var min2y = rect2.y;
            var max2y = rect2.y+rect2.h;
            
            //假设碰撞出新的方块
            var nminx = Math.max(min1x,min2x);
            var nmaxx = Math.min(max1x,max2x);
            
            var nminy = Math.max(min1y,min2y);
            var nmaxy = Math.min(max1y,max2y);
            
            var obj = new Rect(nminx,nminy,(nmaxx-nminx),(nmaxy-nminy));
            
            if(nmaxx >nminx && nmaxy>nminy){
                return {
                    judge:true,
                    rect:obj
                };
            }else{
                return {
                    judge:false
                };
            }
        }

相关文章

  • canvas 碰撞反弹

    之前我们学习js的时候都写过碰撞反弹,canvas里的碰撞反弹也可以用同样的条件判断,现在我们回顾一下之前的判断 ...

  • 构造函数&&类--canvas小球碰撞

    1. 构造函数 canvas小球碰撞 2. 类 canvas小球碰撞 有上可以看出,用类写面向对象的方法,...

  • Canvas弹球碰撞

    (以下为个人理解,可能有理解不当或不足之处,望大家批评指正。) Canvas(HTML5新增标签) Canvas ...

  • Canvas 碰撞检测

    canvas 的尺寸分为两种,一个是 canvas 作为 html 元素本身的尺寸,另外一个 canvas 作为绘...

  • canvas版像素碰撞

    canvas像素碰撞思路: 创建两个图片 将第一张图片拷贝到canvas中,带该图片加载完毕之后 拖动第二张图片,...

  • day12-作业

    实现鼠标点击屏幕产生小球,小球自动移动,与屏幕碰撞会反弹。小球之间碰撞,会随机吃掉。 定义部分颜色的模块

  • canvas笔记--圆形碰撞检测

    #mc { display: block; ...

  • Canvas实现球体碰撞交互效果

    一、Canvas简介 提到Canvas相信做前端开发的同学都不陌生,它是一个用于绘制图形的容器,我们会在一些特殊场...

  • Javascript:Canvas的小球碰壁反弹

    (萌新),我今天在网上看了看如何在Canvas画布上做出小球碰壁反弹的效果,然后自己试做一下,感觉良好,不知道还有...

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

    在Canvas中进行碰撞检测,大家往往直接采用游戏引擎(Cocos2d-JS、Egret)或物理引擎(Box2D)...

网友评论

    本文标题:canvas 碰撞反弹

    本文链接:https://www.haomeiwen.com/subject/esnvgxtx.html