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

Phaser刮奖游戏重启问题:点击重玩按钮恢复遮盖层报错

解决Phaser刮奖游戏重玩功能失效与报错问题

问题核心分析

报错Cannot read properties of null (reading 'draw')的本质原因:

  • 首次调用createTexture时已创建coverTexture纹理,重玩时直接调用textures.createCanvas会因为同名纹理已存在,返回无效对象(或null),导致后续draw方法调用失败。
  • 重玩时未清理旧游戏元素(遮盖层图片、底层图、百分比文本、定时器),造成元素堆积且状态混乱。

分步解决方案

1. 重玩前清理旧资源与状态

修改playAgainFct的点击回调,先彻底清理旧元素再重新初始化:

playAgain.on(Phaser.Input.Events.GAMEOBJECT_POINTER_DOWN, () => {
  // 清理定时器
  if (this.checkTimer) {
    this.checkTimer.remove();
    this.checkTimer = null;
  }

  // 销毁旧的刮奖相关元素
  if (this.coverImageElement) this.coverImageElement.destroy();
  if (this.skyImageElement) this.skyImageElement.destroy();
  if (this.precent) this.precent.destroy();

  // 移除旧的coverTexture纹理(解决draw方法报错的关键)
  if (this.textures.exists("coverTexture")) {
    this.textures.remove("coverTexture");
  }

  // 重置刮奖状态
  this.isPointerDown = false;
  
  // 清理粒子系统(如果有)
  this.destroyParticles();

  // 重新初始化刮奖功能
  this.createTexture();
  this.scratchOff();
});

2. 保存元素引用以便清理

修改scratchOff方法,将创建的图片和文本保存为实例属性,方便后续销毁:

scratchOff() {
  this.precent = this.add.text(10, 10, "");

  // 保存遮盖层图片引用
  this.coverImageElement = this.add.image(this.screenCenter[0] - 171, this.screenCenter[1], "coverTexture")
    .setInteractive()
    .setScale(0.76)
    .setDepth(1);
  
  // 保存底层图片引用
  this.skyImageElement = this.add.image(this.screenCenter[0] - 171, this.screenCenter[1], SKY_IMAGE)
    .setScale(0.76)
    .setDepth(0);

  // 绑定交互事件(移除原代码冗余的多层if判断)
  this.coverImageElement.on("pointerdown", this.startDrawing, this);
  this.coverImageElement.on("pointerup", this.stopDrawing, this);
  this.coverImageElement.on("pointermove", this.clearCover, this);

  this.checkTimer = this.time.addEvent({
    delay: 250,
    loop: true,
    callback: this.checkPercent,
    callbackScope: this,
  });
}

3. 增强createTexture方法的鲁棒性

在创建新纹理前先移除旧纹理,确保每次都是全新初始化:

createTexture() {
  // 双重保险:先移除已存在的同名纹理
  if (this.textures.exists("coverTexture")) {
    this.textures.remove("coverTexture");
  }

  this.coverImage = this.textures.get(SKY_IMAGE_BLACK).getSourceImage();
  this.coverHelperCanvas = this.textures.createCanvas("coverTexture", this.coverImage.width, this.coverImage.height);
  
  // 确保画布有效再执行后续操作
  if (this.coverHelperCanvas) {
    this.coverHelperCanvas.draw(0, 0, this.coverImage);
    this.coverHelperCanvas.context.globalCompositeOperation = "destination-out";
    this.canvasCollection = this.coverHelperCanvas;
  }
}

额外注意事项

  • 确保SKY_IMAGE_BLACK和SKY_IMAGE纹理在游戏启动阶段已正确加载,避免getSourceImage()返回null。
  • 如果有自定义粒子系统,需确保destroyParticles()方法能彻底清理旧粒子实例。

内容的提问来源于stack exchange,提问作者georgio bejjani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 20:32:40