JS报错TypeError: player.animate is not a function 求助
问题排查与修复方案
报错核心原因
触发Uncaught TypeError: player.animate is not a function的直接原因:animate是你定义在全局作用域的独立渲染循环函数,不是Sprite类的原型方法,player、enemy作为Sprite类的实例,本身没有挂载animate方法,强行调用就会抛出类型错误。
代码中存在的其他关联bug
除了上述调用错误,你的代码还有6处会导致运行异常的问题:
- 实例化
player和enemy时,没有给Sprite构造函数传必填的height参数,后续触底判断逻辑中this.height为undefined,会导致重力碰撞逻辑完全失效 c.fillStyle是canvas上下文的属性,不是可调用的方法,你写的c.fillStyle('black')属于错误调用,会抛出函数不存在的报错,正确写法是赋值操作- 清屏逻辑里用的
c.width、c.height不存在,2d渲染上下文没有这两个属性,应该取canvas元素本身的宽高 - 重力加速度重复计算:
update方法开头已经给y轴速度加了一次重力,后面else分支又重复加了一次,会导致下落速度比预期快一倍 - 触底判断时直接把整个
this.velocity赋值为0,会把x轴方向的速度也清空,后续如果加水平移动逻辑会失效,应该只重置y轴方向的速度 - 动画循环不需要给实例分别调用,全局的
animate函数内部已经通过requestAnimationFrame做了递归,只需要调用一次就能启动整个渲染循环
修复后可直接运行的代码
const canvas = document.querySelector('canvas'); const c = canvas.getContext('2d'); canvas.width = 1024; canvas.height = 576; c.fillRect(0 ,0 , canvas.width, canvas.height); const gravity = 0.2; class Sprite { constructor({position,velocity,height}) { this.position = position; this.velocity = velocity; this.height = height; } draw(){ c.fillStyle = 'red'; c.fillRect(this.position.x,this.position.y, 50 , 150 ); } update(){ this.draw() this.position.y += this.velocity.y; if(this.position.y + this.height + this.velocity.y >= canvas.height){ this.velocity.y = 0; } else { this.velocity.y += gravity; } } } const player = new Sprite({ position :{ x:0, y:0 }, velocity : { x : 0, y : 10 }, height: 150 // 补全缺失的height参数,和draw方法里绘制的高度一致 }); const enemy = new Sprite({ position :{ x:400, y:100 }, velocity : { x : 0, y : 10 }, height: 150 // 补全缺失的height参数 }); console.log(player); function animate() { window.requestAnimationFrame(animate); c.fillStyle = 'black'; // 修正为属性赋值 c.fillRect(0,0,canvas.width,canvas.height); // 修正为取canvas元素的宽高 player.update(); enemy.update(); } // 只需要调用一次全局animate函数启动循环即可,不需要实例调用 animate();
内容的提问来源于stack exchange,提问作者SikkPythons
相关产品推荐
相关产品推荐

