C#, Windows Form, 重画pictureBox

C#, Windows Form, redraw pictureBox

我的 C# 游戏有问题。 有一个随机放置狼和浣熊的矩阵。当用户单击 "new game" 按钮时,我需要为动物生成新位置并重新绘制我的 canvas (PicureBox)。 所以,我生成没有问题,但是 pictureBox 中动物的位置没有改变(但它显示,当第一次生成时)。

我还尝试创建几个带有动物图标的图片框(并在游戏过程中移动它),但它们没有显示(我在 this.Controls 中添加了它,但没有任何反应)。也许浏览器中有一些表单管理器,如 web-inspector 可以查看到底发生了什么?

我不想将项目移动到 WPF 应用程序。

下面的代码片段:

private static Bitmap _gameArea = new Bitmap(_gameAreaSize, _gameAreaSize);

Painted事件(创建一个table):

        private void drawTable(object sender, PaintEventArgs e)
    {
        Pen p = new Pen(Color.LightSlateGray);

        var g = Graphics.FromImage(_gameArea);
       for (int i = 0; i < Configs.MatrixSize + 1; i++)
        {
            float coord = i * _cellSize;
            if (coord.Equals(_gameAreaSize))
                coord = _gameAreaSize - 1;

           g.DrawLine(p, coord, 0, coord, _gameAreaSize);
           g.DrawLine(p, 0, coord, _gameAreaSize, coord);
        }
        pictureBox1.BackgroundImage = _gameArea;

        g.Dispose();
    }

游戏开始和新游戏点击:

        GameLogic.InitGame(); // change positions, without threads
        RefreshMap();

刷新地图:

        private static void RefreshMap()
    {
        var g = Graphics.FromImage(_gameArea);
        g.Clear(Color.White);
        g.Dispose();

        RefreshRacoons();
        RefreshWolves();
    }

我试过这样做:

        private static void RefreshMap()
    {
        var sync = SynchronizationContext.Current;

        new Thread(__ =>
            sync.Post(_ =>
            {
                var g = Graphics.FromImage(_gameArea);
                g.Clear(Color.White);
                g.Dispose();

                RefreshRacoons();
                RefreshWolves();
            }, null)).Start();
    }

并刷新(使用和不使用 synContext)

private static void RefreshRacoons()
    {
        foreach (var racoon in GameLogic.Racoons)
        {
           var g = Graphics.FromImage(_gameArea);
           g.DrawImage(_racoonImg,
               _cellSize * racoon.X + _offsetX,
               _cellSize * racoon.Y + _offsetY,
               _animalIconWidth,
               _animalIconHeight);

           g.Dispose();

        }
    }
    private static void RefreshWolves()
    {
        var sync = SynchronizationContext.Current;

        foreach (var wolf in GameLogic.Wolves)
        {
            new Thread(__ =>
                sync.Post(_ =>
                {
                    var g = Graphics.FromImage(_gameArea);
                    g.DrawImage(_wolfImg,
                        _cellSize * wolf.X + _offsetX,
                        _cellSize * wolf.Y + _offsetY,
                        _animalIconWidth,
                        _animalIconHeight);
                    g.Dispose();
                }, null)).Start();
        }
    }

谢谢!

我通常的免责声明是这样的:Windows Forms 不是适合游戏开发的环境。回合制单人游戏或热座多人游戏都可以,只要你不过度使用动画。但是纸牌和扫雷几乎是可能的上限。

有许多专用显示器 technologies/Engines 可用于游戏开发。但最终,任何允许您直接、低级别绘图访问并具有某种游戏循环的东西都应该可行。虽然你可以在某种程度上用 Windows 形式伪造它,但当你有一辆完全装满的汽车,点火器中的钥匙就站在那里时,你基本上最终会重新发明轮子。

对于 .NET Framework,过时的解决方案是 XNA Framework。但如果你选择 .NET Core,至少有 3 个官方解决方案: https://www.microsoft.com/net/learn/apps/gaming

大多数都可以与 Mono 一起使用,有些甚至可以与 .NET Framework 一起使用(我自己还没有尝试过)。