在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對象的構建。