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

SFML开发国际象棋游戏:非窗口绘制函数无法加载纹理的问题

问题根源

SFML 的 Sprite 并不存储纹理的像素数据,它仅持有一个指向 Texture 对象的引用。你在 load_textures() 函数中声明的 Texture texture 是局部变量,函数执行完毕后这个局部变量会被销毁,导致 boardSprite 引用的纹理变成无效状态——这就是渲染时显示白色矩形的原因。

而将纹理加载代码放在 draw_board() 内时,局部 Texture 变量的生命周期覆盖了整个渲染循环,纹理始终有效,因此能正常显示。

解决方案

把 Texture 改为 GameRender 类的成员变量,让它的生命周期与类实例保持一致,避免提前销毁。

1. 修改类声明,添加纹理成员

class GameRender {
private:
    sf::Texture boardTexture;  // 作为类成员保存纹理,延长生命周期
    sf::Sprite boardSprite;
    // 你的其他成员变量(如window等)
};

2. 更新 load_textures() 函数

void GameRender::load_textures(){
    if (!boardTexture.loadFromFile("../graphics/textures/board.png")){
        throw std::runtime_error("Failed to load board texture");
    }
    boardSprite.setTexture(boardTexture);
}

3. 优化纹理加载时机(可选)

建议在 GameRender 的构造函数中调用一次 load_textures(),而不是在 draw_board() 开头反复加载:

GameRender::GameRender() {
    // 初始化window等操作...
    load_textures();
}

void GameRender::draw_board(){
    // 移除这里的load_textures()调用
    Event event;
    Vector2u prevWinSize = window.getSize();
    const float desiredAspectRatio = 1.0f / 1.0f;
    const float basicScaleX = static_cast<float>(prevWinSize.x) / boardSprite.getGlobalBounds().width;
    const float basicScaleY = static_cast<float>(prevWinSize.y) / boardSprite.getGlobalBounds().height;
    boardSprite.setScale(basicScaleX, basicScaleY);

    while (window.isOpen()){
        // 原循环代码保持不变
    }
}

这样修改后,纹理会在类初始化时加载一次,生命周期与类实例绑定,boardSprite 引用的纹理始终有效,就能正常渲染棋盘了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:44:52