反弹
反弹的处理原理很简单,在运动对象碰到边界后,我们将其放置到与边缘紧貼的位置,之后将其方向反向即可(因为边界是水平或竖直的,我们只需要考虑一个方向上的分速度反向,如果碰撞面是倾斜的,就需要进行坐标系统的旋转,这个之后会专门介绍)。
仍然拿小球系统来分析,只需要在每一帧绘制小球前执行以下代码即可:
if (ball.x + ball.radius > right) {
ball.x = right - ball.radius;
vx *=bounce;
} else if (ball.x - ball.radius < left) {
ball.x = left + ball.radius;
vx *=bounce;
}
if (ball.y + ball.radius > bottom) {
ball.y = bottom - ball.radius;
vy *= bounce;
} else if (ball.y - ball.radius < top) {
ball.y = top + ball.radius;
vy *= bounce;
}
其中的bounce是一个常量,如果是完全弹性碰撞,则bounce=-1。如果在反弹时有损耗,可以将其值根据实际情况进行调整。此处我们的碰撞处理是最简单的处理方式,如果运动物体的速度非常快,那其效果会与我们预想的有一些偏差,如下面两幅图的对比就可以看出差异。
左图是我们使用程序处理的结果示意
左图是小球在实际物理世界中的运行示意
5.2 摩擦力
在实际环境中,运动对象在运动时会有摩擦力阻止其运动。对于摩擦力的处理有两种方式,下面仍以小球系统为例分别介绍。
理论方法
摩擦力是用来减少对象速度的力。所以,其方向是与速度方向相反的。按前面介绍的速度与三角函数方面的理论,我们可以得到速度为:
var speed=Math.sqrt(ball.vx*ball.vx+ball.vy*ball.vy);
var angle=Math.atan2(ball.vy,ball.vx);
接下来,我们就可以从速度中减去摩擦力产生的速度减少常数值。但要注意,在速度减少到已经小于摩擦力产生的速度减少常数时,我们就不需要再给速度减去摩擦力产生的速度常数了,否则就会产生反向的速度,此时只需要将速度置零即可。
if(speed>friction){
speed-=friction;
}else{
speed=0;
}
ball.vx=speed*Math.cos(angle);
ball.vy=speed*Math.sin(angle);
上述代码中的friction为摩擦力产生的速度减少常数。我们只需要将上述代码放入帧函数animationLoop中小球绘制前,就可以为系统添加摩擦力处理了。
简易方案
从前面的理论处理方法,我们可以看到,一个确定的系统,我们只需要给正交分解后的各个坐标轴上分速度持续地乘以一个速度衰减常数(0到1之间),这样速度会逐渐减少到无限接近0。精确到一定程度,速度已经小到用户无法分辨。
具体实现时,只需要将如下两行代码放入帧函数animationLoop中小球绘制前即可:
ball.vx*=friction;
ball.vy*=friction;
有时候,为了优化系统性能。我们可以对当前的速度进行判断,如果小于一个指定常数,则不进行速度处理,如:
if(Math.abs(ball.vx)>0.0001){
ball.vx*=friction;
}
5.2.3 实例对比
我们对之前的两种方式,在一个系统中进行对比。代码如下:
window.onload=function(){
var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
//使用理论方式运算
var friction=0.01;
//使用简易方式计算
var friction2=0.992;
//实例化并设置初始值
var ball=new Ball();
var ball2=new Ball();
ball2.color='#00ff00';
ball.x=ball2.x=canvas.width/2;
ball.y=ball2.y=canvas.height/2;
ball.vx=ball2.vx=Math.random()*10-5;
ball.vy=ball2.vy=Math.random()*10-5;
(function drawFrame(){
window.requestAnimFrame(drawFrame,canvas);
context.clearRect(0,0,canvas.width,canvas.height);
//理论方式处理第一个小球,先球合速度,再减去摩擦速度,再分解小球分速度与位置
var speed=Math.sqrt(ball.vx*ball.vx+ball.vy*ball.vy);
var angle=Math.atan2(ball.vy,ball.vx);
if(speed>friction){
speed-=friction;
}else{
speed=0;
}
ball.vx=Math.cos(angle)*speed;
ball.vy=Math.sin(angle)*speed;
ball.x+=ball.vx;
ball.y+=ball.vy;
ball.draw(context);
//直接乘以摩擦常数
ball2.vx*=friction2;
ball2.vy*=friction2;
ball2.x+=ball2.vx;
ball2.y+=ball2.vy;
ball2.draw(context);
})();
};
- 大小: 17.6 KB
- 大小: 16 KB
分享到:
相关推荐
canvas拼图游戏,基于html + canvas画布实现
H5 canvas 实现小游戏 H5 canvas 实现小游戏 H5 canvas 实现小游戏 H5 canvas 实现小游戏
HTML5 Canvas 赛车游戏动画DEMO演示 键盘控制车的方向
利用canvas画布,进行撞击,消除操作的小游戏
canvas端午节小游戏
canvas拼图小游戏
html5 开发技术 游戏.很好玩的html5+canvas技术实现的拼图游戏
试验性质的一个微信小程序,用canvas做的一个类似flappy-bird的小游戏。 包含一些基本的功能:躲避障碍物、计分、排行榜等等。后端的工程也一并上传了,在java目录中,很简单的一个SpringMVC工程。 游戏原型见这里。...
通过一个简单的例子,讲解如何在HTML5 canvas中开发游戏,主要是定时器的用法值得大家借鉴
canvas端午节吃粽子小游戏,兼容移动端
HTML5 Canvas赛车游戏动画,赛车游戏动画演示。
canvas 飞机大战小游戏
canvas 实现2d 简单小游戏,点击出现蓝色攻击方块,攻击黑色方块得分,触碰红色方块游戏结束,黑色方块想灭完,游戏等级提升
HTML 5 CANVAS游戏开发实战HTML 5 CANVAS游戏开发实战HTML 5 CANVAS游戏开发实战
canvas-弹珠游戏
HTML 5 CANVAS游戏开发实战
canvas打砖块小游戏
1.open-type=“share”,onShareAppMessage实现分享微信功能。2.canvas绘制分享海报。
HTML5+CANVAS游戏开发实战,很值得学习,就算不是做游戏,但是对js的进阶也很有好处。
canvas版的2048小游戏,canvas版的2048小游戏,canvas版的2048小游戏,canvas版的2048小游戏,canvas版的2048小游戏