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

Monogame中如何更新RenderTarget2D显示?解决重绘崩溃问题

问题分析与解决方法

核心崩溃原因

崩溃源于切换RenderTarget时SpriteBatch处于活跃状态:Monogame不允许在SpriteBatch.Begin()之后、End()之前的状态下修改RenderTarget,否则会触发图形设备状态异常。此外,代码中还有几处潜在的风险点需要修正。


分步解决

1. 修复RenderTarget切换时的SpriteBatch状态冲突

修改Explosion方法,确保操作RenderTarget前SpriteBatch已结束,操作后恢复原状态:

public void Explosion()
{
    tiles[0,0] = 0;
    // 临时结束活跃的SpriteBatch(如果存在)
    bool wasActive = Globals.SpriteBatch.IsActive;
    if (wasActive)
    {
        Globals.SpriteBatch.End();
    }
    // 重绘地图到RenderTarget
    Activate();
    DrawMap();
    Globals.GraphicsDevice.SetRenderTarget(null);
    // 恢复之前的SpriteBatch状态
    if (wasActive)
    {
        Globals.SpriteBatch.Begin();
    }
}

2. 规范RenderTarget2D的创建参数

显式指定兼容的渲染目标参数,避免图形设备兼容性问题:

public Map()
{
    // 先加载纹理(避免字段初始化时机问题)
    wall = Globals.Content.Load<Texture2D>("wall");
    
    // 显式配置RenderTarget参数
    _target = new RenderTarget2D(
        Globals.GraphicsDevice,
        tiles.GetLength(1) * TILE_SIZE,
        tiles.GetLength(0) * TILE_SIZE,
        false, // 禁用mipmap(地图不需要)
        Globals.GraphicsDevice.PresentationParameters.BackBufferFormat,
        DepthFormat.None, // 禁用深度缓冲(地图不需要)
        0,
        RenderTargetUsage.PreserveContents // 保留渲染内容,避免意外丢失
    );
    
    Activate();
    DrawMap();
    Globals.GraphicsDevice.SetRenderTarget(null);
}

3. 调整纹理加载时机

将wall纹理的加载从类字段初始化移到构造函数,确保ContentManager已完全初始化:

// 仅声明字段,不在此处加载
private Texture2D wall;

public Map()
{
    // 构造函数内加载纹理
    wall = Globals.Content.Load<Texture2D>("wall");
    // 后续RenderTarget创建逻辑...
}

4. (可选)优化tiles的访问权限

当前tiles为static readonly,会导致所有Map实例共享同一地图数据。如果需要多个独立地图,移除static修饰符:

public readonly int[,] tiles = {
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
    {1, 0, 0, 1, 0, 1, 0, 1, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 0, 1, 0, 1, 0, 1, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 0, 1, 0, 1, 0, 1, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
};

验证效果

完成上述修改后,调用Explosion方法时会先处理SpriteBatch状态冲突,再安全更新RenderTarget,修改后的地图可以正常重绘到屏幕,不会触发崩溃。

内容的提问来源于stack exchange,提问作者Zelei Ádám István

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 07:17:06