Показать след движущегося пикселя в проекте C# WinForm

Я работаю над личным проектом, связанным с проблемой колонии муравьев. Я успешно разработал все для консольного проекта, и теперь я хочу перенести код в более графическое расположение с формами окон.

Использование кода ниже формы показывает правильно один движущийся пиксель, но я не могу найти способ показать левый след движения. Я попытался удалить 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();
    }

2 ответа

Решение

Добавлять List<Point> поле формы, где Point это тип муравья Position поле. На каждой Move добавить текущие позиции муравьев в этот список. Я эмулирую движение мышью 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
}

Запустите и попробуйте щелкнуть мышью.

Вот решение, которое объединяет рисование следа в растровое изображение и новых муравьев на поверхности:

Подготовьте растровое изображение:

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 неясно.. А вы действительно можете рассмотреть поплавки на позиции..

Не звони pictureBox1.Invalidate() от Paint событие, как это обычно вызовет Paint событие снова.. Вместо этого, вероятно, следует перейти к отметке таймера анимации или нажатию кнопки и т. д.

Также обратите внимание на using пункт, который гарантирует, что Graphics объект, который я создаю, расположен.

В примере предполагается, что вы уже можете правильно нарисовать муравьев и просто добавляете следы.

Другие вопросы по тегам