1

在为我在 c# 中的个人蚁群项目提出这个问题(在 C# WinForm 项目中显示移动像素的轨迹)之后,我正在尝试应用第二个建议的解决方案:将轨迹绘制成位图和新蚂蚁到表面。

[...]Application.Run(new ShowAnts());[...]

public partial class ShowAnts : Form
{
    Bitmap bmp;
    int j = 0;
    public ShowAnts()
    {
        InitializeAntProgram();
        InitializeComponent();
        bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);
        pictureBox1.Image = bmp;
    }

    public void RenderAnts(object sender, PaintEventArgs e)
    {
        using (Graphics G = Graphics.FromImage(pictureBox1.Image))
        {
            while (j < 1000)
            {
                Map.EvaporatesPheromones();
                foreach (Vector2D food in foodSrcs)
                {
                    Map.SetMapPoint(food, 500);
                }
                foreach (Ant a in ants)
                {
                    Brush c;
                    c = Brushes.DarkBlue;
                    if (a.role == AntRole.Scout)
                    {
                        a.Move(j);
                        c = Brushes.Red;
                    }
                    e.Graphics.FillRectangle(Brushes.DarkBlue, a.position.x, a.position.y, 1, 1);
                    G.FillRectangle(Brushes.Gray, a.position.x, a.position.y, 1, 1);
                }
                j++;
            }
        }
    }
}

上面的代码显示了将蚂蚁运动绘制成 winform 的图形尝试。它完美地工作,但它只显示最终结果。我想展示一步一步的演变,在不重新解析我的地图信息的情况下保持图形轨迹信息。

请考虑我开发此“图形界面”的工作控制台项目已经存在,因此:

  • 一些变量设置在项目的其他地方(即:食物);
  • `a.Move(j);` 指的是蚂蚁逻辑本身(分析、决策、新单元格移动指的是地图数组);
  • `j` 计数器用于计算步数和设置任意停止,但没有实际用途;
  • 我已经将有关信息素、运动、位置等的所有信息存储到地图数组和其他一些变量中。
4

1 回答 1

0

查看您的代码以及上一个问题的注释,您似乎缺少可以为运动设置动画的部分。相反,您正在循环内部似乎是Paint事件。

这是一个快速解决方案。它添加了一个Timer触发事件的RenderAnts事件,该事件似乎与pictureBox1.Paint处理程序挂钩..:

一些类级别的变量:

 int counter = 0;
 int limit = 1000;
 Timer antTimer = new Timer(); 

启动代码:

 antTimer.Interval = 50;   // <-- pick your speed !!
 antTimer.Tick += (ss, ee) =>
 { pictureBox1.Invalidate(); counter++; if (counter > limit) antTimer.Stop(); };
 antTimer.Start();

速度为 50ms,即Ticks每秒 20 次。

Tick事件内联了一个微小的Lambdaepression,并且只有一个语句加上循环逻辑。由控件控制其Invalidating事件 ,从而触发该事件。pictureBox1PaintRenderAnts

另请注意,我称其为“快速修复”。通常你会区分动画的渲染和移动代码。但在这种情况下,这种细微差别并不重要。

现在我们改变RenderAnts方法,去掉循环:

public void RenderAnts(object sender, PaintEventArgs e)
{
    using (Graphics G = Graphics.FromImage(pictureBox1.Image))
    {
        Map.EvaporatesPheromones();
        foreach (Vector2D food in foodSrcs)
        {
           Map.SetMapPoint(food, 500);
        }
        foreach (Ant a in ants)
        {
           Brush c = Brushes.DarkBlue;
           if (a.role == AntRole.Scout)
           {
              a.Move(j);
              c = Brushes.Red;
           }
           e.Graphics.FillRectangle(c, a.position.x, a.position.y, 1, 1);
           G.FillRectangle(Brushes.Gray, a.position.x, a.position.y, 1, 1);
        }
    }
}

您可能还想添加一个 Start/Stop Button。还有一个TrackBar改变速度..

现在您应该能够以 20Hz 的频率观察蚂蚁的进度,留下灰色的痕迹。

于 2016-06-27T02:57:08.120 回答