Показать след движущегося пикселя в проекте 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
объект, который я создаю, расположен.
В примере предполагается, что вы уже можете правильно нарисовать муравьев и просто добавляете следы.