# 24、《每周一点canvas动画》——3D物理效果

#### 1.速度与加速度

window. = function() {
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
ball = new Ball(40, "red");
var xpos = 0,
//初始化 3D坐标
ypos = 0,
zpos = 0,
vx = 0,
//初始化 3D速度
vy = 0,
vz = 0,
friction = 0.98,
fl = 250,
vpX = canvas.width / 2,
//消失点
vpY = canvas.height / 2; //按键控制
switch (e.keyCode) {
case 38:
//up
vy -= 1;
break;
case 40:
//down
vy += 1;
break;
case 37:
//left
vx -= 1;
break;
case 39:
//right
vx += 1;
break;
case 16:
// shift
vz += 1;
break;
case 17:
//control
vz -= 1;
break;
}
}, false); //动画循环
(function drawFrame() {
window.requestAnimationFrame(drawFrame, canvas);
context.clearRect(0, 0, canvas.width, canvas.height);
xpos += vx; //位置变化
ypos += vy;
zpos += vz;
vx *= friction;
vy *= friction;
vz *= friction; //三维环境设置
if (zpos > -fl) {
var scale = fl / (fl + zpos);
ball.scaleX = ball.scaleY = scale;
ball.x = vpX + xpos * scale;
ball.y = vpY + ypos * scale;
ball.visible = true;
} else {
ball.visible = false;
} //绘制小球
if (ball.visible) {
ball.draw(context);
}
}())
}

#### 2.反弹

##### 2.1 单物体反弹

top = - 100
bottom = 100
left = - 100
right = 100
front = - 100
back = 100

if (xpos + ball.radius > right) {
vx *= bounce;
} else if (xpos - ball.radius < left) {
vx *= bounce;
}
if (ypos + ball.radius > bottom) {
vy *= bounce;
} else if (ypos - ball.radius < top) {
vy *= bounce;
}
if (zpos + ball.radius > back) {
vz *= bounce;
} else if (zpos - ball.radius < front) {
vz *= bounce;
}

##### 2.2 多物体反弹

this.xpos = 0;
this.ypos = 0;
this.zpos = 0;
this.vz = 0;
this.vx = 0;
this.vy = 0;

functionmove(ball) {
ball.xpos += ball.vx;
ball.ypos += ball.vy;
ball.zpos += ball.vz; /*.......边界碰撞检测代码，与上部分一样.......*/
// 3D环境设置
if (ball.zpos > -fl) {
var scale = fl / (fl + ball.zpos);
ball.scaleX = ball.scaleY = scale;
ball.x = vpX + ball.xpos * scale;
ball.y = vpY + ball.ypos * scale;
ball.visible = true;
} else {
ball.visible = false;
} //绘制小球
if (ball.visible) {
ball.draw(context);
}
}(function drawFrame() {
window.requestAnimationFrame(drawFrame, canvas);
context.clearRect(0, 0, canvas.width, canvas.height); //看这里，套路
balls.forEach(move);
}())

#### 3. Z-sort

var arr = [9, 7, 3, 2, 4];
arr.sort(function(a, b) {
returna - b;
});
console.log(arr); // [ 2, 3, 4, 7, 9] 其中，a - b < 0a排在b前面 a - b = 0a,b顺序不变 a - b > 0b排在a前面

functionsort(a, b){ return(b.zpos - a.zpos); }

ok,本节到这就结束了，下一节我们介绍更多的3D物理效果实现，敬请期待!

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120