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

Phaser 3按Tailwind断点缩放GameObject时遇sudokuScene未定义报错

问题解决:Phaser 3 场景未加载报错及响应式尺寸调整

报错原因分析

  • 创建Phaser.Game后立即获取game.scene.keys.SudokuGameObjects,此时场景尚未完成初始化,导致sudokuScene为undefined。
  • 原生window.resize事件绑定时机过早,场景create方法未执行完成就调用resizeGameObject,触发错误。
  • create方法中this.box被重复赋值给文本对象,矩形对象引用丢失,后续setSize操作失效。
  • 获取屏幕宽度的方式错误:canvas.style.width无法正确获取Tailwind设置的实际渲染宽度(w-full通过CSS继承生效,不会直接写入元素style属性)。

修复方案及代码调整

核心优化点

  1. 改用Phaser内置的Resize事件,确保场景初始化完成后再响应尺寸变化。
  2. 分开存储矩形和文本对象,避免引用覆盖。
  3. 使用Phaser自身的视口宽度匹配Tailwind断点规则,保证逻辑一致性。

修改后的主文件代码

import SudokuGameObjects from "./Classes/SudokuGameObjects";

const gameCanvas = document.createElement('canvas');
gameCanvas.id = 'gameCanvas';
gameCanvas.classList.add("w-full", "h-full", "mx-auto", "m-0");

const config = {
    type: Phaser.CANVAS,
    transparent: true,
    canvas: document.getElementById("gameCanvasContainer").appendChild(gameCanvas),
    scale: {
        zoom: 1,
        mode: Phaser.Scale.RESIZE,
        width: window.innerWidth,
        height: window.innerHeight
    },
    scene: [SudokuGameObjects],
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 300 }
        }
    },
    render: {
        pixelArt: false,
        roundPixels: true
    },
};

new Phaser.Game(config);

修改后的SudokuGameObjects文件代码

export default class SudokuGameObjects extends Phaser.Scene
{
    constructor() 
    {
        super({key: 'SudokuGameObjects', active: true});
        this.rectBox = null;
        this.textBox = null;
    }

    resizeGameObject()
    {
        const viewportWidth = this.scale.width;
        // 匹配Tailwind断点:≥1536px用300x300,<1280px用150x150
        if (viewportWidth >= 1536) {
            this.rectBox.setDisplaySize(300, 300);
            this.textBox.setFontSize(32);
        } else if (viewportWidth < 1280) {
            this.rectBox.setDisplaySize(150, 150);
            this.textBox.setFontSize(16);
        }
        // 可选:1280-1535px区间可自定义尺寸规则
    }

    create() 
    {
        // 创建矩形对象
        this.rectBox = this.add.rectangle(300, 200, 100, 100, 0xff0000).setOrigin(0.5);
        this.rectBox.setDisplaySize(300, 300);
        
        // 创建文本对象,单独存储引用
        this.textBox = this.add.text(300, 200, '1', { 
            fontFamily: 'Figtree', 
            fontSize: 32, 
            color: '#ffffff', 
            stroke: '#ffffff', 
            strokeThickness: 1 
        }).setOrigin(0.5);

        // 绑定Phaser内置resize事件
        this.scale.on('resize', () => {
            this.resizeGameObject();
        });

        // 页面加载时初始化一次尺寸
        this.resizeGameObject();
    }
}

关键说明

  • 用this.scale.on('resize')替代原生window事件,确保场景完全初始化后再执行尺寸调整,彻底解决undefined报错。
  • this.scale.width直接获取Phaser视口宽度,和Tailwind的断点逻辑(xl=1280px,2xl=1536px)完全匹配。
  • 分开存储矩形和文本对象,避免引用覆盖导致的操作失效问题。
  • 初始化时主动调用resizeGameObject,保证页面加载完成就应用正确的尺寸。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 16:33:12