You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:25:38