【问题标题】:C#, Windows Form, redraw pictureBoxC#、Windows 窗体、重绘图片框
【发布时间】:2018-04-18 13:32:14
【问题描述】:

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

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

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

以下代码片段:

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

绘制事件(创建表格):

        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();
        }
    }

谢谢!

【问题讨论】:

  • 在 RefreshRacoons 和 RefreshWolves 的每个循环中,您都从头开始。另外:您不会将结果重新分配给 pbox.image 但您必须.. 不知道为什么在基础工作之前将线程和同步问题复杂化。
  • 我找到了方法“pictureBoxElem.Refresh()”并尝试了它(并将创建和处理移出循环),现在动物改变了它们的位置,谢谢!我不知道为什么他们首先显示,而下一个图标没有这样做
  • 我在这里没有看到任何代码来随机化狼或浣熊的位置
  • 我不明白为什么,它们正确随机化(在调试中检查),现在程序完全正常工作(我不知道如何关闭问题)
  • 发布您自己的答案,如果有,请接受。

标签: c# winforms picturebox


【解决方案1】:

我通常的免责声明是这样的:Windows 窗体不是游戏开发的正确环境。回合制单人游戏或热门多人游戏可以工作,如果你不过度使用动画。但是纸牌和扫雷几乎是可能的上限。

有许多专用显示技术/引擎可用于游戏开发。但最终,任何允许您直接、低级别的绘图访问并具有某种游戏循环的东西都应该可以解决。虽然您可以在某种程度上在 Windows 窗体中伪造这一点,但当您拥有一辆完全装满的汽车并且点火装置中的钥匙就在那里时,您基本上最终会重新发明轮子。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 2017-05-21
    • 1970-01-01
    相关资源
    最近更新 更多