使用HTML Canvas与JavaScript类绘制100个移动圆形失败问题求助
问题修复方案
错误点1:数组元素添加方式错误
你直接把circleArray赋值成单个Circle实例,而非往数组中添加元素,循环结束后circleArray会变成单个对象而非数组,后续遍历circleArray.length必然报错。
修正:使用数组push方法添加实例:
circleArray.push(new Circle(x,y,dx,dy,radius))
错误点2:update方法调用draw的方式错误
circleArray.draw()写法错误,数组本身没有draw方法,应该调用当前Circle实例的draw方法,即this.draw()。
修正:把circleArray.draw()替换为this.draw()
错误点3:Canvas上下文未初始化
代码中的c变量未定义,浏览器无法识别要操作的Canvas对象,必须先获取Canvas元素并创建2D上下文。
修正:在代码开头添加:
const c = document.querySelector('canvas').getContext('2d'); // 同步设置Canvas尺寸与窗口一致 document.querySelector('canvas').width = innerWidth; document.querySelector('canvas').height = innerHeight;
注意:HTML页面中需要先存在<canvas></canvas>标签。
错误点4:速度计算逻辑错误
dx = (Math.random() - 0.5 * 5)运算优先级错误,0.5先与5相乘,导致速度范围不符合预期,应先做减法再乘法,让速度区间落在-2.5到2.5之间。
修正:改为(Math.random() - 0.5) * 5,dy同理。
修正后的完整代码
// 初始化Canvas上下文 const c = document.querySelector('canvas').getContext('2d'); document.querySelector('canvas').width = innerWidth; document.querySelector('canvas').height = innerHeight; class Circle { constructor(x, y, dx, dy, radius) { this.x = x this.y = y this.dx = dx this.dy = dy this.radius = radius } draw() { c.beginPath() c.arc(this.x, this.y, this.radius, 0, Math.PI * 2); c.strokeStyle = "blue" c.stroke() } update() { if (this.x + this.radius > innerWidth || this.x - this.radius < 0) { this.dx = -this.dx } if (this.y + this.radius > innerHeight || this.y - this.radius < 0) { this.dy = -this.dy } this.x += this.dx this.y += this.dy // 修正y轴移动逻辑,与碰撞判断保持一致 this.draw() } } let circleArray = [] for (let i = 0; i < 100; i++){ let radius = 30 // 修正初始位置,避免圆形一开始就超出屏幕 let x = Math.random() * (innerWidth - radius * 2) + radius; let y = Math.random() * (innerHeight - radius * 2) + radius; let dx = (Math.random() - 0.5) * 5 let dy = (Math.random() - 0.5) * 5 circleArray.push(new Circle(x,y,dx,dy,radius)) } function animation() { requestAnimationFrame(animation) c.clearRect(0, 0, innerWidth, innerHeight) for(let i = 0; i < circleArray.length; i++){ circleArray[i].update() } } animation()
额外优化:调整了圆形初始位置的计算逻辑,避免圆形一开始就超出屏幕边界;修正了y轴移动方向,让碰撞后的移动逻辑与判断条件一致。
内容的提问来源于stack exchange,提问作者raj singh
相关产品推荐
相关产品推荐

