Canvas+Js制作动量守恒的小球碰撞
目的:通过js实现小球碰撞并实现动量守恒
canvas我们就不多说了,有用着呢。
我们可以通过canvas画2D图形(圆、方块、三角形等等)3D图形(球体、正方体等待)。
当然这只是基础的皮毛而已,canvas的强大之处在于可以做游戏,导入模型,粒子效果,实现漫游又或者全景和VR。
这里我们介绍纯js写的2D小球碰撞。(主要是博主的Three.js不咋地)
好吧,老规矩,先上图!
额。。。很尴尬的是博主的截图功底不咋地,没有截下碰撞的瞬间。
话不多说,开始教程。
首先我们需要创建画布给它一个id方便后面监听处理。
<body>
<canvas id="myCanvas"></canvas>
</body>
然后是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,又大功告成了。自己动手试试吧!
懒人福利!!!
完整代码。
<html>
<head>
<style>
body{margin:0;}
</style>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
<script>
//声明画布大小为屏幕的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); //碰撞检测 动量守恒
//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); setInterval(animation,30);
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); }
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);
}
</script>
</html>
欢迎交流学习!!!
不定时随缘更新。
Canvas+Js制作动量守恒的小球碰撞的更多相关文章
- js实现多个小球碰撞
实现思路:小球的移动,是通过改变小球的left和top值来改变,坐标分别为(x,y)当x/y值加到最大,即加到父级的宽度或者高度时,使x值或者y值减小,同理当x值或者y值减到最小时,同样的使x值或者y ...
- HTML5 Canvas彩色小球碰撞运动特效
脚本简介 HTML5 Canvas彩色小球碰撞运动特效是一款基于canvas加面向对象制作的运动小球动画特效. 效果展示 http://hovertree.com/texiao/html5/39/ ...
- 利用canvas制作乱跑的小球
canvas制作乱跑的小球 说明:将下面的代码放到html的body就可以,键盘控制上(W)下(S)左(A)右(D) <body> <canvas id="canvas&q ...
- 小游戏——js+h5[canvas]+cs3制作【五子棋】小游戏
五子棋小游戏学习—— 有一个问题是,棋盘线的颜色,在canvas中,明明设置了灰色,但在我的预览中还是黑色的,很重的颜色. 以下是复刻的源码: <!DOCTYPE html> <ht ...
- js实现小球碰撞游戏
效果图: 效果图消失只是截的gif图的问题 源码: <!DOCTYPE html> <html lang="en"> <head> <m ...
- 使用canvas通过js制作一个小型英雄抓怪兽的2D小游戏
首先,这是一个HTML: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...
- 使用WebGL + Three.js制作动画场景
使用WebGL + Three.js制作动画场景 3D图像,技术,打造产品,还有互联网:这些只是我爱好的一小部分. 现在,感谢WebGL的出现-一个新的JavaScriptAPI,它可以在不依赖任何插 ...
- Expression Design与Blend制作滚动的小球动画教程
原文:Expression Design与Blend制作滚动的小球动画教程 一,开发工具 Microsoft Expression Design & Blend 4.0 (3.0亦可). 这两 ...
- js制作带有遮罩弹出层实现登录小窗口
要实现的效果如下 点击“登录”按钮后,弹出登录小窗口,并且有遮罩层(这个名词还是百度知道的,以前只知道效果,却不知道名字) 在没有点击“登录”按钮之前登录小窗口不显示,点击“登录”按钮后小窗口显示,并 ...
随机推荐
- 设计社区类Web原型制作分享-Behance
Behance 是著名设计社区,创意设计人士可以展示自己的作品,发现别人分享的创意作品. 网站有二级导航,主要用到的交互组件有弹出面板,通过弹出面板来隐藏展现搜索框.并且用到的组件有播放器.菜单栏.下 ...
- 在Mockplus中,如何做鼠标悬停时菜单下拉的效果?
了解Mockplus的用户会知道,该原型工具目前并不直接支持鼠标悬停功能.但我经过尝试,发现想用它实现一个鼠标悬停事件并不是什么难事,比如网页设计中很常见的鼠标悬停时菜单下拉的效果,只要换个思路,利用 ...
- Monte carlo
转载 http://blog.sciencenet.cn/blog-324394-292355.html 蒙特卡罗(Monte Carlo)方法,也称为计算机随机模拟方法,是一种基于"随机数 ...
- android 网站上下的 adt 不能显示没有安装的
问题描述 使用SDK Manager更新时出现问题Failed to fetch URL https://dl-ssl.google.com/android/repository/repository ...
- SQLALchemy--ORM框架
SQLAlchemy 1.介绍 SQLAlchemy是一个基于Python实现的ORM框架.该框架建立在 DB API之上,使用关系对象映射进行数据库操作,简言之便是:将类和对象转换成SQL,然后使用 ...
- 2018.08.28 codeforces600E(dsu on tree)
传送门 一道烂大街的dsu on tree板题. 感觉挺有趣的^_^ 代码真心简单啊! 就是先处理轻儿子,然后处理重儿子,其中处理轻儿子后需要手动消除影响. 代码: #include<bits/ ...
- Java多线程-并发协作(生产者消费者模型)
对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一样,Hello World!都是最经典的例子. 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓 ...
- POJ 2462 / HDU 1154 Cutting a Polygon
就这样莫名其妙的过了,不过可以确定之前都是被精度卡死了.真心受不了精度问题了. 题意:一条直线在一个不规则多边形内的长度,包括边重合部分. 首先计算出所有交点,然后按想x,y的大小进行二级排序. 然后 ...
- pgAdmin4 汉化
- Openlayers地图量算功能
http://openlayers.org/en/latest/examples/measure.html?q=measure 按官网的例子来就行,新建对象时注意加上命名空间 var vect ...