OOP HTML Canvas乒乓球游戏:实例化新Paddle时删除已绘图形问题
问题:Canvas乒乓球游戏中实例化新 paddle 会删除已有 paddle 的原因
我正在开发一款基于OOP的HTML Canvas乒乓球游戏,我的Paddle类代码如下:
class Paddle extends Canvas { #width #height #y #index #x constructor(id,i) { super(id); this.#index=i; this.#y = 0; this.resize(); } draw() { this.ctx.beginPath(); this.ctx.rect(this.#x, this.#y, this.#width, this.#height); this.ctx.fill(); this.ctx.closePath(); } update() { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.draw(); } resize() { this._resize(); this.#width = Math.pow(this.canvas.width, 1 / 2) * 2; this.#height = this.canvas.height / 4; if(this.#index === 0){ console.log("left") this.#x=0; }else{ console.log("right") this.#x=this.canvas.width - this.#width; } this.draw(); } set y(value) { this.#y = value; this.update(); } }
当我实例化新的Paddle对象时,新的paddle会被绘制,但已有的另一个paddle会被删除,可通过以下代码复现:
setTimeout(function(){ let rightPaddle = new Paddle('paddle',1); },1000) let leftPaddle = new Paddle('paddle',0);
问题原因
核心问题在于所有Paddle实例共享同一个Canvas上下文,且每个实例的update方法都会清空整个画布:
- 两个Paddle实例都指向同一个Canvas元素(构造函数传入相同的id
'paddle'),因此它们使用的是同一个绘图上下文ctx。 - 当第二个Paddle实例初始化时,会调用
resize和draw,而update方法里的clearRect会清空整个画布,之后只绘制当前实例的paddle,直接覆盖了第一个Paddle的内容。 - 每个Paddle的
update逻辑只负责绘制自己,没有考虑其他实例的存在,导致画布清空后无法保留之前的绘图内容。
解决思路
- 将画布的清空逻辑从Paddle类中剥离,创建一个全局的渲染循环:每次循环先统一清空画布,再遍历所有Paddle实例调用它们的
draw方法。 - 删除Paddle类
update方法中的clearRect调用,让全局渲染来处理画布的清空操作,确保所有Paddle都能被重新绘制。
内容的提问来源于stack exchange,提问作者talel
相关产品推荐
相关产品推荐

