博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Canvas+Js制作动量守恒的小球碰撞
阅读量:4609 次
发布时间:2019-06-09

本文共 3769 字,大约阅读时间需要 12 分钟。

目的:通过js实现小球碰撞并实现动量守恒

canvas我们就不多说了,有用着呢。

我们可以通过canvas画2D图形(圆、方块、三角形等等)3D图形(球体、正方体等待)。

当然这只是基础的皮毛而已,canvas的强大之处在于可以做游戏,导入模型,粒子效果,实现漫游又或者全景和VR。

这里我们介绍纯js写的2D小球碰撞。(主要是博主的Three.js不咋地)

好吧,老规矩,先上图!

额。。。很尴尬的是博主的截图功底不咋地,没有截下碰撞的瞬间。

话不多说,开始教程。

首先我们需要创建画布给它一个id方便后面监听处理。

然后是Js代码

//声明画布大小为屏幕的1/3    var width = window.innerWidth/3;    var  height = window.innerHeight/3;    var canvas = document.getElementById("myCanvas");    canvas.width = width;    canvas.height = height;    //创建2d画笔    var ctx = canvas.getContext("2d");    //填充颜色设置为黑色(背景色)    ctx.fillStyle = "#000";    //将整个画布填充    ctx.fillRect(0,0,width,height);

这是Canvas最基本的操作,我们解释一下fillRect(x,y,width,height);这个函数。

x和y填充的起始坐标点,width和height是填充区域的宽和高。

 由于我们创建的是带有物理性质的小球,所以我们用一个函数封装创建小球的代码。

以后创建小球直接调用它就行了。

function Ball(x,y,vx,vy,ax,ay,size,rou,color,ctx){    //参数传值    //x,y为坐标点 vx,vy为小球水平和垂直方向上的速度 ax,ay为加速度     //size 为大小 rou为密度 color颜色 ctx画笔    this.x = x;    this.y = y;    this.vx = vx;    this.vy = vy;    this.rou = rou;    this.size = size;    this.ax = ax;    this.ay = ay;    this.m = Math.PI*this.size*this.size*rou;//求出质量        this.draw = function(ctx){        ctx.fillStyle=color;        //console.log(this.x, this.y,this.size);        ctx.beginPath();        ctx.arc(this.x, this.y, this.size, 0, Math.PI*2,false);//画圆        ctx.fill();        ctx.closePath();    }    this.draw(ctx);}

接下来实例化出两个小球。

//碰撞检测 动量守恒    //x,y,vx,vy,ax,ay,size,rou,color,ctx    var balla = new Ball(20,0.5*height,5,-3,0,0,8,1,"#ff0",ctx);    var ballb = new Ball(width-20,0.5*height,-3,5,0,0,13,1,"#0ff",ctx);    var ballc = new Ball(width/2,0.5*height,7,4,0,0,13,1,"#0ff",ctx);

然后我们封装了一个函数来实现小球是实时更新。

function animation(){        //小球的速度等于速度加上加速度        balla.vx+= balla.ax;        balla.vy+=balla.ay;        //小球的位移等于小球现在的坐标加上速度        balla.x+= balla.vx;        balla.y+=balla.vy;        ballb.vx+= ballb.ax;        ballb.vy+=ballb.ay;        ballb.x+= ballb.vx;        ballb.y+=ballb.vy;        //基于距离的碰撞检测        var pointdis=(balla.x-ballb.x)*(balla.x-ballb.x)+(balla.y-ballb.y)*(balla.y-ballb.y);//坐标距离        var pointsize=(balla.size+ballb.size)*(balla.size+ballb.size);//半径距离        if( pointdis <= pointsize)        {            console.log("haha");            //这里是能量守恒公式            var ballavx =((balla.m-ballb.m)*balla.vx+2*ballb.m*ballb.vx)/(balla.m+ballb.m);            var ballavy =((balla.m-ballb.m)*balla.vy+2*ballb.m*ballb.vy)/(balla.m+ballb.m);            var ballbvx=((ballb.m-balla.m)*ballb.vx+2*balla.m*balla.vx)/(balla.m+ballb.m);            var ballbvy=((ballb.m-balla.m)*ballb.vy+2*balla.m*balla.vy)/(balla.m+ballb.m);            balla.vx = ballavx;            balla.vy = ballavy;            ballb.vx = ballbvx;            ballb.vy = ballbvy;            //小Bug改进            if(Math.abs(balla.vx-ballb.vx)<0.01&&Math.abs(balla.vy-ballb.vy)<0.01)            {                console.log(balla.vx);                balla.vx=-balla.vx;                balla.vy=-balla.vy;                return;            }        }                //判断是否碰撞到画布的边缘        if(balla.x+balla.size>=width||balla.x-balla.size<=0)        {            balla.vx*=-0.98;        }        if(balla.y+balla.size>=height||balla.y-balla.size<=0)        {            balla.vy*=-0.98;        }        if(ballb.x+ballb.size>=width||ballb.x-ballb.size<=0)        {            ballb.vx*=-0.98;        }        if(ballb.y+ballb.size>=height||ballb.y-ballb.size<=0)        {            ballb.vy*=-0.98;        }                //清空画布,画出小球        ctx.fillStyle = "#000";        ctx.fillRect(0,0,width,height);        balla.draw(ctx);        ballb.draw(ctx);        //console.log(ballb.vy);    }

最后我们让他30毫秒更新一次。

setInterval(animation,30);

OK,又大功告成了。自己动手试试吧!

懒人福利!!!

完整代码。

欢迎交流学习!!!

不定时随缘更新。

转载于:https://www.cnblogs.com/tcxq/p/10118927.html

你可能感兴趣的文章
基础练习 Huffuman树
查看>>
8.28笔记
查看>>
[转]springSecurity源码分析—DelegatingFilterProxy类的作用
查看>>
Bootstrap 时间控件timepicker与datepicker
查看>>
Net文本编辑器,语法高亮,折叠,自动补全,提示
查看>>
【转】用emWin进度条控件做个表盘控件,效果不错
查看>>
emwin之创建窗口与窗口回调函数的句柄是一致的
查看>>
JAVA笔记(基本数据类型)
查看>>
判断数字的正则表达式
查看>>
CAN通信工作原理个人心得
查看>>
关于Django 错误 doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS...
查看>>
ubuntu下双网卡桥接
查看>>
关闭socket连接最好的方法
查看>>
python 时间模块学习
查看>>
进程、线程和协程的区别(转)
查看>>
c# 生成二维码 QRCoder
查看>>
Java中的ArrayList的初始容量和容量分配
查看>>
MEF: MSDN 杂志上的文章(7) 约定程序集 ???
查看>>
游标使用-循环语句
查看>>
Matlab——系统预定义的变量 常用数学函数
查看>>