Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#WinForm项目中显示移动像素的轨迹_C#_Winforms - Fatal编程技术网

在C#WinForm项目中显示移动像素的轨迹

在C#WinForm项目中显示移动像素的轨迹,c#,winforms,C#,Winforms,我正在做一个与蚁群问题有关的个人项目。 我成功地为一个控制台项目开发了所有东西,现在我想用windows窗体将代码转换成更具图形化的布局 使用表单下方的代码可以正确显示一个移动的像素,但我无法找到显示移动的左轨迹的方法。我试图删除pictureBox1.Invalidate(),但这使我在起点处看到了一个静态像素 我不想重新分析地图矩阵并绘制信息素轨迹,只想留下绘制的位置,就像我在纸上用钢笔画东西一样 public void RenderAnts(object sender, Paint

我正在做一个与蚁群问题有关的个人项目。 我成功地为一个控制台项目开发了所有东西,现在我想用windows窗体将代码转换成更具图形化的布局

使用表单下方的代码可以正确显示一个移动的像素,但我无法找到显示移动的左轨迹的方法。我试图删除pictureBox1.Invalidate(),但这使我在起点处看到了一个静态像素

我不想重新分析地图矩阵并绘制信息素轨迹,只想留下绘制的位置,就像我在纸上用钢笔画东西一样

    public void RenderAnts(object sender, PaintEventArgs e)
    {
        pictureBox1.Invalidate();
        foreach (Ant a in ants)
        {
            Brush c;
            c = Brushes.DarkBlue;
            if (a.role == AntRole.Scout)
            {
                a.Move(i);
                c = Brushes.Red;
            }
            e.Graphics.FillRectangle(c, a.position.x, a.position.y, 1, 1);
        }
        pictureBox1.Show();
    }
添加
列表
表单字段,其中
是蚂蚁
位置
字段的类型。在每个
移动中
将当前蚂蚁位置添加到此列表。我模拟通过鼠标点击
PictureBox
移动。绘制事件处理程序只是绘制位置

见样本

public partial class Form1 : Form
{
    public Form1()
    {
        //InitializeComponent();
        pictureBox1 = new PictureBox { Parent = this, Dock = DockStyle.Fill };

        ants.Add(new Ant { Role = AntRole.Scout, Position = new Point(50, 50) });
        ants.Add(new Ant { Role = AntRole.Scout, Position = new Point(150, 150) });
        ants.Add(new Ant { Role = AntRole.Scout, Position = new Point(100, 100) });

        pictureBox1.Paint += RenderAnts;

        pictureBox1.Click += (s, e) =>
        {
            for (int i = 0; i < 100; i++)
                foreach (Ant a in ants)
                {
                    if (a.Role == AntRole.Scout)
                    {
                        a.Move();
                        antTrails.Add(a.Position);
                    }
                }
            pictureBox1.Refresh();
        };
    }
    PictureBox pictureBox1;
    List<Ant> ants = new List<Ant>();
    List<Point> antTrails = new List<Point>();

    public void RenderAnts(object sender, PaintEventArgs e)
    {
        foreach (var point in antTrails)
            e.Graphics.FillRectangle(Brushes.Red, point.X, point.Y, 1, 1);
    }
}

public class Ant
{
    public AntRole Role;
    public Point Position;
    static Random rnd = new Random();

    public void Move()
    {
        int r = rnd.Next(4);
        if (r == 0)
            Position.X--;
        else if (r == 1)
            Position.X++;
        else if (r == 2)
            Position.Y--;
        else
            Position.Y++;
    }
}

public enum AntRole
{
    Normal,
    Scout
}
公共部分类表单1:表单
{
公共表格1()
{
//初始化组件();
pictureBox1=new PictureBox{Parent=this,Dock=DockStyle.Fill};
Add(新蚂蚁{Role=AntRole.Scout,Position=newpoint(50,50)});
Add(新的Ant{Role=AntRole.Scout,Position=newpoint(150150)});
Add(新的Ant{Role=AntRole.Scout,Position=newpoint(100100)});
pictureBox1.Paint+=渲染器;
pictureBox1.单击+=(s,e)=>
{
对于(int i=0;i<100;i++)
foreach(蚂蚁中的蚂蚁a)
{
if(a.Role==AntRole.Scout)
{
a、 Move();
添加(a.位置);
}
}
pictureBox1.Refresh();
};
}
PictureBox pictureBox1;
列表蚂蚁=新列表();
List antTrails=新列表();
公共无效渲染器(对象发送器、PaintEventArgs e)
{
foreach(antTrails中的变量点)
e、 图形.圆角矩形(画笔.Red,点.X,点.Y,1,1);
}
}
公共类蚂蚁
{
公共窦孔作用;
公共点位置;
静态随机rnd=新随机();
公开作废动议()
{
int r=rnd.Next(4);
如果(r==0)
位置X--;
else如果(r==1)
Position.X++;
else如果(r==2)
位置Y--;
其他的
Position.Y++;
}
}
公共上颌窦
{
正常,,
侦察兵
}

运行并尝试单击鼠标。

这里有一个解决方案,它将轨迹绘制成位图,并将新蚂蚁绘制到曲面上:

准备位图:

Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);
pictureBox1.Image = bmp;
现在,修改的绘制事件:

void RenderAnts(object sender, PaintEventArgs e)
{
    //pictureBox1.Invalidate();   // don't do this here!

    using (Graphics G = Graphics.FromImage(pictureBox1.Image))
    foreach (ant a in ants)
    {
        c = Brushes.DarkBlue;
        if (a.role == AntRole.Scout)
        {
            a.Move(i);
            c = Brushes.Red;
        }
        // this draws onto the surface:
        e.Graphics.FillRectangle(c, a.position.x, a.position.y, 1, 1);
        // and this into the Image bitmap below:
        G.FillRectangle(Brushes.Gray, a.position.x, a.position.y, 1, 1);
    }

}
请注意,曲面位于图像上方

我不确定你的代码的细节;尤其是变量
i
不清楚。。你可能想考虑浮动的位置…

不要从
Paint
事件调用
pictureBox1.Invalidate()
,因为这通常会再次触发
Paint
事件。。相反,这可能会移动到动画计时器滴答声或按钮单击等

还要注意
using
子句,它确保我创建的
Graphics
对象被释放


本例假设您已经可以正确绘制蚂蚁本身,只需添加轨迹。

使用矩形F而不是矩形。最后两个参数(1,1)是宽度和高度,它们是浮点数。使其变小,以便不过度写入旧点。创建位图并在其上绘制,而不是在绘制事件期间直接绘制到picturebox中。绘制过程不会在无效周期内保持像素不变。请勿从绘制事件或从绘制事件调用的事件调用pictureBox1.Invalidate()!因此,在移除无效和显示后,你应该看到你所有的蚂蚁,前提是它们的位置实际上是正确的。如果我正确地应用了你的解决方案假设,它会画出轨迹,但会同时出现。你也一样吗?我正在寻找的行为是重新绘制每一步。@sipronanceaaigor-在
单击
事件中,我应用了
for
循环来演示100条轨迹。删除这个循环。好的,我知道它是如何工作的,现在我已经能够正常运行它了。是否有某种通用处理程序可以避免单击或鼠标移动?我在想一个简单的循环,直到有一个线程退出。Sleep(amount)来减慢模拟OK,考虑到计时器,我可以问你另一个处理程序吗?抱歉,但我无法让它运行,我开始关注@alexander reply。“i”是完整源代码中的一个输入错误。在使alexander的代码正常工作后,我正在寻找您的代码,但它在第一次迭代中出现,我不知道如何使其正确运行。抱歉,这是我第一次在WinForms中使用图形。前两行是否运行一次?如何触发渲染器?从计时器开始。滴答声?它们只运行一次,但我没有触发任何东西。我原以为“Application.Run(new ShowAnts());”会在表单生命周期内一直循环主方法。嗯,不会。空闲时间内不会发生任何事情。如果你什么都不做,你的蚂蚁怎么移动???通常的方法是让计时器带有一个包含
pictureBox1.Invalidate()的勾号事件。。计时器的间隔可能为200毫秒,每秒触发滴答声5次。。