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

PixiJS精灵表加载后无法访问纹理,报错textures未定义

PixiJS精灵表纹理访问问题解决办法

在开发基础国际象棋游戏时,使用PixiJS的精灵表API遇到报错textures is undefined,核心原因是对app.loader的异步特性理解不足,无法在loader回调外部正确访问加载后的纹理数据。使用的棋子精灵表如下:

棋子精灵表

当前代码及问题

业务代码

const app = new PIXI.Application();
document.body.appendChild(app.view);

key = ['w_king', 'w_queen', 'w_bishop', 'w_knight', 'w_castle', 'w_pawn', 
'b_king', 'b_queen', 'b_bishop', 'b_knight', 'b_castle', 'b_pawn'];

app.loader.add('spritesheet', 'pieces.json')
    .load( _=> 
        {
        const textures = key.map(k => PIXI.Texture.from(k));
        });

var sprite = PIXI.Sprite(textures[1]);

app.stage.addChild(sprite)

对应的pieces.json内容

{"frames": 
    {
        "w_king":{ 
            "frame":{"x":0,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":32}},
        "w_queen":{ 
            "frame":{"x":426,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":426}},
        "w_bishop":{ 
            "frame":{"x":852,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":426}},
        "w_knight":{ 
            "frame":{"x":1278,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":426}},
        "w_castle":{ 
            "frame":{"x":1704,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":426}},
        "w_pawn":{ 
            "frame":{"x":2130,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":426}},
        "b_king":{ 
            "frame":{"x":0,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":32}},
        "b_queen":{ 
            "frame":{"x":426,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":426}},
        "b_bishop":{ 
            "frame":{"x":852,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":426}},
        "b_knight":{ 
            "frame":{"x":1278,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":426}},
        "b_castle":{ 
            "frame":{"x":1704,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":426}},
        "b_pawn":{ 
            "frame":{"x":2130,"y":0,"w":426,"h":426}, 
            "sourceSize":{"w":426,"h":426}, 
            "spriteSourceSize":{"x":0,"y":0,"w":426,"h":426}}},
    "meta":{ 
        "image":"spriteSheet.png", 
        "format":"RGBA8888", 
        "size":{"w":2560,"h":853}, 
        "scale":1}}

问题根源

app.loader.load()是异步操作,后台加载资源时不会阻塞后续代码执行。回调内部定义的textures是局部变量,外部无法访问;更关键的是,回调还未执行时,外部代码就已尝试访问textures[1],此时textures尚未被定义,因此触发报错。

修正方案

所有依赖加载后资源的代码,必须放在load()回调内部,或使用Promise/async-await处理异步流程。

方案1:回调内处理全逻辑

把创建精灵、添加到舞台的代码移到回调函数中:

const app = new PIXI.Application();
document.body.appendChild(app.view);

const key = ['w_king', 'w_queen', 'w_bishop', 'w_knight', 'w_castle', 'w_pawn', 
'b_king', 'b_queen', 'b_bishop', 'b_knight', 'b_castle', 'b_pawn'];

app.loader.add('spritesheet', 'pieces.json')
    .load(() => {
        const textures = key.map(k => PIXI.Texture.from(k));
        const sprite = PIXI.Sprite(textures[1]);
        // 原纹理尺寸过大,缩小到合适比例
        sprite.scale.set(0.2);
        app.stage.addChild(sprite);
    });

方案2:Promise封装加载流程

如果需要更灵活的异步控制,可将加载过程封装为Promise:

const app = new PIXI.Application();
document.body.appendChild(app.view);

const key = ['w_king', 'w_queen', 'w_bishop', 'w_knight', 'w_castle', 'w_pawn', 
'b_king', 'b_queen', 'b_bishop', 'b_knight', 'b_castle', 'b_pawn'];

function loadSpritesheet() {
    return new Promise((resolve) => {
        app.loader.add('spritesheet', 'pieces.json')
            .load(() => {
                const textures = key.map(k => PIXI.Texture.from(k));
                resolve(textures);
            });
    });
}

// 使用async-await简化异步代码
async function initGame() {
    const textures = await loadSpritesheet();
    const sprite = PIXI.Sprite(textures[1]);
    sprite.scale.set(0.2);
    app.stage.addChild(sprite);
}

initGame();

额外注意事项

  • JSON文件中w_king和b_king的spriteSourceSize.h值为32,属于错误配置,应改为426,否则国王棋子会被裁剪显示。
  • 原纹理尺寸为426x426,直接添加到舞台会占据过大空间,建议通过sprite.scale.set()调整到合适大小。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:20:32