当前位置:编程学习 > html/css >>

基于HTML5的小球物理测试系统

你的浏览器不支持canvas,推荐使用chrome进行浏览。 半径: 
颜色: 
速度: 
弹性(0-1): 
入射角(0-360): 
起始X坐标(0-400): 
起始Y坐标(0-400): 
 

功能说明:

  一个基于HTML5 canvas的小球物理测试系统,用户可以手动为新的小球设置不同的属性值(颜色,半径,速度等),从而在canvas中发射小球,小球在运动过程中会收到重力,弹性以及摩擦力的影响。

实现原理:

在小球飞行过程中,以初始速度,入射角以及重力系数作为依据,正交分解得出小球X轴和Y轴上的分速度,通过定时器不断刷新canvas,显示出小球飞行的动画。当小球和墙壁产生碰撞时,以小球弹性为依据计算能量损耗,当小球在墙壁滚动时,以墙壁摩擦系数为依据计算其能量损耗。

代码分析:

var bounceWall = (function() {   

 return function(canvasId,backgroundColor) {   

this.init(canvasId, backgroundColor);   

}

})();

构造函数,其中调用了prototype中的init方法进行初始化。需要传入的参数是canvas的ID,和canvas的背景色,如果不传入backgroundColor参数,背景色默认为黑色。

bounceWall.prototype = (function() {   

  var CanvasSupport = Modernizr.canvas;

//检查浏览器是否支持canvas     var newBall = function(radius, color, speed, direction, currentX, currentY, elasticity) {       

this.radius = parseFloat(radius);                           

 //半径        this.color = color;                                         

//颜色        this.speed = parseFloat(speed);                             

 //速度        this.elasticity = parseFloat(elasticity);                   

//弹性         this.direction = parseFloat(direction);                     

 //入射角        this.currentX = parseFloat(currentX);                       

//初始X坐标        this.currentY = parseFloat(currentY);                       

 //初始Y坐标        this.dx = speed * Math.cos(this.direction * Math.PI / 180); 

 //计算其X轴方向的初始速度        this.dy = speed * Math.sin(this.direction * Math.PI / 180); 

//计算其Y轴方向的初始速度        this.nextX = this.currentX + this.dx;                       

 //根据速度和初速度得出其下次移动到的X坐标        this.nextY = this.currentY + this.dy;                       

 //根据速度和初速度得出其下次移动到的Y坐标    };     

开始进入到bounce wall的prototype,首先使用Modernizr检测是否可以使用canvas。Modernizr是一个可以用于检测浏览器是否支持一些新功能的js库,可以下载直接使用。

     之后出现的是小球的构造函数newBall,用户需要传入一系列的特性对其进行初始化,具体已经在注释中标出。需要特别注意的是其中的nextX和nextY记录的是小球下一次出现位置的坐标,它根据现在的位置(currentX和currentY)以及小球X轴和Y轴上的分速度(dx和dy)计算得出。nextX和nextY属性的用处主要是保证小球能和墙壁发生完全的碰撞,会在后面的代码分析。

    /* 绘制canvas的背景 */    var drawBackground = function(contextObj, backgroundColor, canvasWidth, canvasHeight) {       

contextObj.fillStyle = backgroundColor;       

 contextObj.fillRect(0, 0, parseInt(canvasWidth), parseInt(canvasHeight));   

 };

之后的函数是用户绘制canvas的背景,依据的属性是用户设定的背景色,canvas的宽度和高度。

 /* 更新小球状态 */   

var updateBallState = function(ballObj, canvasWidth, canvasHeight, gravityValue, friction) {       

 ballObj.currentX = ballObj.nextX;       

 ballObj.currentY = ballObj.nextY;       

ballObj.nextX = ballObj.currentX + ballObj.dx;       

ballObj.nextY = ballObj.currentY + ballObj.dy;       

/* 测试对墙壁产生是否X轴碰撞 */      

  if (ballObj.nextX < ballObj.radius) {           

ballObj.nextX = ballObj.radius;           

ballObj.dx = Math.max(0, (ballObj.dx + ((1 - ballObj.elasticity) * Math.abs(ballObj.dx))) * -1 - 1);       

 }       

else if ((ballObj.nextX + ballObj.radius) > parseInt(canvasWidth)) {           

 ballObj.nextX = parseInt(canvasWidth) - ballObj.radius;           

 ballObj.dx = Math.min(0, (ballObj.dx - ((1 - ballObj.elasticity) * Math.abs(ballObj.dx))) * -1 + 1);       

 }       

 /* 水平运动时受摩擦力影响 */       

 else if (ballObj.currentY >= (parseInt(canvasHeight) - ballObj.radius)) {          

  if (ballObj.dx > 0) {               

 ballObj.dx = Math.max(0, ballObj.dx - (ballObj.dx * friction) - 0.01);           

}          

  else if (ballObj.dx < 0) {               

 ballObj.dx = Math.min(0, ballObj.dx - (ballObj.dx * friction) + 0.01);           

 }      

  }      

  /* 测试对墙壁产生是否Y轴碰撞 */      

  if (ballObj.nextY < ballObj.radius) {           

ballObj.nextY = ballObj.radius;           

ballObj.dy = Math.max(0, (ballObj.dy + ((1 - ballObj.elasticity) * Math.abs(ballObj.dy))) * -

补充:web前端 , HTML/CSS  ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,