canvas {
background: #000; /* 黑色背景 */
cursor: pointer; /* 可交互提示 */
}
特殊效果:
update() {
// 弹簧约束计算
const dx = p0.x - p1.x;
const dy = p0.y - p1.y;
const dist = Math.sqrt(dx*dx + dy*dy);
const dz = (link.distance - dist) * link.force;
// 速度衰减模拟
point.vx *= 0.995;
point.vy *= 0.995;
// 重力模拟
point.y += 0.01;
}
draw() {
// 关节绘制
ctx.save();
ctx.translate(link.p0.x, link.p0.y);
ctx.rotate(a);
ctx.drawImage(link.image, ...);
ctx.restore();
// 阴影效果
ctx.drawImage(link.shadow, ...);
}
pointer.down(e) {
// 碰撞检测
const d = Math.sqrt(dx*dx + dy*dy);
if(d < 60) {
dancerDrag = dancer;
pointDrag = point;
}
}
const struct = {
points: [ // 11个关键节点
{x:0,y:-4,f(s,d){/* 头部运动 */}},
{x:0,y:-16,f(s,d){/* 颈部运动 */}},
// ...其他节点定义
],
links: [ // 10个连接部件
{p0:3,p1:7,size:12,lum:0.5},
{p0:1,p1:3,size:24,lum:0.5},
// ...其他连接定义
]
};
function run() {
// 清屏与背景绘制
ctx.fillStyle = "#222";
ctx.fillRect(0, canvas.height*0.85, canvas.width, canvas.height*0.15);
// 更新所有机器人状态
dancers.forEach(d => d.update());
// 分层绘制
dancers.sort((a,b) => a.size - b.size);
dancers.forEach(d => d.draw());
}
point.vy *= 0.995; // 空气阻力
point.y += 0.01; // 重力常数
- 基于弹簧约束的软体模拟
- 速度衰减和重力加速度的复合模型
// 先绘制阴影
ctx.drawImage(link.shadow, ...);
// 再绘制本体
ctx.drawImage(link.image, ...);
- 根据机器人尺寸分层渲染
- 阴影与本体分离绘制
if(this.size < 16 && this.frame > 600) {
dancers.push(new Robot(...)); // 生成新机器人
dancers.sort(); // 重新排序绘制层级
}