0

I had a task to move an element(Button, Label...) around a panel within Winforms with C#.

I solved it like this, it works:

 private void button1_Click(object sender, EventArgs e)
    {

        // System.Threading.Thread.Sleep(100 - auto.Geschwindigkeit);
        for (int i = 0; i < panel1.Width; i++)
        {
            label1.Location = new Point(i, label1.Location.Y);
            label2.Location = new Point(i, label2.Location.Y);
            System.Threading.Thread.Sleep(50);//speed
            Application.DoEvents();
        }


    }

But is there another way to do this, for example when I want to programm a game and I have 10 Labels(which represent a driving car), I think this would be to overloaded to work with Threads, because the CPU goes higher and higher ?! "System.Threading.Thread.Sleep(50);" would be the speed of an element, I think I need something which is more performant ?!

Thank You

user254197
  • 883
  • 2
  • 9
  • 31
  • 1
    Replace `System.Threading.Thread.Sleep(50); Application.DoEvents();` with `await Task.Delay(50);` – EZI Jul 30 '15 at 12:51
  • Thank you for helping :) – user254197 Jul 30 '15 at 12:56
  • 1
    `DoEvents` is [evil](http://stackoverflow.com/questions/11352301/how-to-use-doevents-without-being-evil). Making event handler `async` and using `await Task.Run(longrunningmethod())` is a cool replacement. More classic approach (because you anyway have **animation steps**) is to put it into UI timer. – Sinatr Jul 30 '15 at 13:00

1 Answers1

5

Do not use Thread.Sleep for timing. Use a timer instead:

private void btnStart_Click(object sender, EventArgs e)
{
    timer1.Interval = 100; // animation speed
    timer1.Enabled = true; // starting animation
}

private void timer1_Tick(object sender, EventArgs e)
{
    // do the replacements here
}

But honestly, I would not use controls to represent animated objects. They have a million of properties, events and other data that you do not need. Instead, I would use dedicated Car objects and custom drawing.

public class Car
{
    public Size Size { get; set; }
    public Color Color { get; set; }
    public Point Location { get; set; }
    public int Speed { get; set; }
    // and whatever you need, eg. direction, etc.
}

private List<Car> cars;

public Form1()
{
    InitializeComponent();
    cars = new List<Car>
    {
        new Car { Size = new Size(30, 15), Color = Color.Blue, Location = new Point(100, 100), Speed = 1 },
        new Car { Size = new Size(50, 20), Color = Color.Red, Location = new Point(200, 150), Speed = 3 },
    };
}

private void btnStart_Click(object sender, EventArgs e)
{
    timer1.Interval = 100; // animation speed
    timer1.Enabled = true; // starting animation
}

private void timer1_Tick(object sender, EventArgs e)
{
    foreach (Car car in cars)
        RecalculateLocation(car); // update Location by speed here
    panel1.Invalidate();
}

private void panel1_Paint(object sender, PaintEventArgs e)
{
    // now we are just drawing colored rectangles but you can draw car.Image or anything you want
    foreach (Car car in cars)
    {
        using (Brush brush = new SolidBrush(car.Color))
        {
            e.Graphics.FillRectangle(brush, new Rectangle(car.Location, car.Size));
        }
    }
}
sm.abdullah
  • 1,777
  • 1
  • 17
  • 34
György Kőszeg
  • 17,093
  • 6
  • 37
  • 65