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

C#开发密室逃脱游戏时2D Tile数组迁移到新Form后无法绘制问题求助

问题根因

你遇到的绘制失效是WinForm绘制机制的典型问题:

  • 你通过CreateGraphics()绘制的内容是临时的,只要窗体触发重绘(比如首次加载自动执行Paint逻辑、窗体被其他窗口遮挡、最小化还原、拖动改变大小),之前绘制的内容就会被默认重绘逻辑清空。
  • 旧Form能正常运行只是刚好GameSetUp调用时机在首次Paint之后,新Form的初始化顺序变化,displayRoom执行完后窗体触发了首次Paint,直接覆盖了你绘制的所有内容。

解决方案(推荐标准写法)

不要手动调用CreateGraphics绘制,将绘制逻辑放到Form的Paint事件中,每次窗体重绘会自动执行该逻辑,内容不会丢失。

修改步骤

  1. 将Room对象改为Form的全局成员,不要在GameSetUp中定义为局部变量:
// 放在Form类内部、方法外的位置
private Room room1;
  1. 调整GameSetUp方法,删除原来的room1.displayRoom(this)调用,绑定Paint事件:
public void GameSetUp()
{
    this.Height = 560;
    this.Width = 535;

    room1 = new Room();
    room1.buildRoom();
    room1.setPoints("room1");
    this.Text = "Room 1";
    
    // 绑定Paint事件,后续所有绘制由Paint事件统一处理
    this.Paint += RoomPaintHandler;

    Character user = new Character();
    StateManager.C = user;
    StateManager.C.addCharacter(room1, this, "room1");
}
  1. 新增Paint事件处理方法,实现绘制逻辑:
private void RoomPaintHandler(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    // 可选:开启抗锯齿提升绘制效果
    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
    
    // using语法会自动释放Pen资源,避免GDI泄漏
    using (Pen p = new Pen(Brushes.Black, 2))
    {
        for (int x = 0; x < 10; x++)
        {
            for (int y = 0; y < 10; y++)
            {
                var tile = room1.Board[x, y];
                g.DrawRectangle(p, tile.rect);
                
                if(tile.getEntry())
                    g.FillRectangle(Brushes.Green, tile.rect);
                else if (tile.getExit())
                    g.FillRectangle(Brushes.Red, tile.rect);
                else if (tile.getProblem())
                    g.FillRectangle(Brushes.SaddleBrown, tile.rect);
                else
                    g.FillRectangle(Brushes.Bisque, tile.rect);
            }
        }
    }
    
    // 角色绘制逻辑也可以在这里添加
}
  1. 如果后续场景更新需要刷新画面,只需要调用this.Invalidate()即可触发Paint事件重新绘制。

临时快速修复方案

如果不想改动现有结构,就调整GameSetUp的调用时机,不要在Form构造函数或Load事件中调用,改到Form的Shown事件中调用即可。这个事件是窗体首次完全显示后才触发,绘制内容不会被首次Paint覆盖。但该方案的缺陷是后续窗体被遮挡、最小化还原后,绘制内容还是会消失,仅适合临时测试使用。

其他排查点

如果修改后还是不显示,可以检查以下几点:

  • 确认新Form的BackColor没有和你绘制的Tile颜色(比如Bisque)完全一致,导致视觉上看不出绘制效果
  • 单步调试Paint事件,确认room1.Board数组没有空引用,每个Tile的rect坐标都在窗体可见范围内
  • 确认Form没有开启透明背景、层叠窗口等特殊属性影响绘制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 18:06:01