在Canvas案例-炫酷的数字时钟中,展现了案例的最终效果,并简单介绍了案例用到的知识点和案例中的对象,如今先介绍Ball对象,代码有什么问题欢迎你们指出。javascript
效果以下 java
跟个前面的效果,下面是我列举的关键属性bash
posX, posY, vx, vy, gravity, bounce, canMove 对象位置、运动参数dom
alive, birth, life 对象生命参数ide
light, color, radius 对象状态参数函数
// 给出代码
function Ball(data) {
this.posX = data.posX || 0;
this.posY = data.posY || 0;
this.radius = data.radius || 10;
this.vx = data.vx || Math.random() - 0.5;
this.vy = data.vy || Math.random() - 0.5;
this.alive = true;
this.canMove = false;
this.birth = null;
this.light = false;
this.color = data.color || `#${Math.random().toString(16).substr(3, 6)}`;
}
Ball.prototype = {
init(data) {
this.initData(data);
this.blender();
return this;
},
initData(data) {
this.WIDTH = data.WIDTH;
this.HEIGHT = data.HEIGHT;
this.ctx = data.ctx;
this.life = 1000 * 15;
this.gravity = 0.08;
this.bounce = -0.7;
},
}
复制代码
这里说一下为何把参数分两部分,initData里的属性全部Ball实例都同样,没有必要单独设置,放到原型上,算是优化吧,减小没必要要的开销。post
值得注意的是颜色的随机使用了截取Math.random()的16进制串,想当年仍是傻傻的用学习
Math.ceil(Math.random() * 255)复制代码
这里的canMove用了控制Ball是否能够移动,light控制是否启用颜色,还记得数字时钟的数字先后没有改变的时候是固定不动的吗,并且仍是没有颜色优化
固然是清除无用的对象,释放内存了。好比那些小球出了画布已经没有做用了,就能够清除了,这里使用alive标记,这样能够很方便的清除这些无用对象。其实这里面还有一些对象的vx可能特别小,若是等这些对象移出画布等待的事件会很长,因此这里设置了life来记录小球的生命,生命到期就会被标记ui
具体实现以下:
// 标记生命到期的对象
if (new Date() - this.birth > this.life) {
this.alive = false;
}
// 标记移出画布的对象
if (this.posX - this.radius <= 0 || this.posX >= WIDTH) {
this.alive = false;
}复制代码
回想高中咱们学习的物理知识—抛物线运动
v = at v = v0 + at h = 1/2 * at^2
然而实际却没法用这些,由于这里咱们拿不到时间t,那么咱们就要换个思路了
好比x方向作匀速运动,那么vx势必是定值,而后每次跟新把当前的posX = posX + vx,这样
就能够实现匀速运动了
同理,y方向作加速运动,那么vy势必是变值,不只每次跟新把当前的posY = posY + vy,还要把这个重力加速度vy = gravity + vy ,这样就能够实现加速运动了
为了达到每次弹跳有衰减,这里引入bounce参数,经过把这个参数设置一个(-1~0)便可实现反弹和衰减,一箭双雕。
// collide函数中
if (this.posY - this.radius <= 0 || this.posY + this.radius >= HEIGHT) {
// 这里的min max是碰撞检测一个经典的作法
this.posY = Math.min(this.posY, HEIGHT - this.radius);
this.posY = Math.max(this.posY, 0);
this.vy *= this.bounce;
}
// update函数中
if (this.canMove) {
this.posX += this.vx;
this.posY += this.vy;
this.collide();
this.vy += this.gravity;
}复制代码
好了,至此咱们已经完成了Ball对象的构建,使用这个对象已经能够完成一些基本效果,好比下图这些。有什么问题能够留言交流,下期是Tile对象的构建。