Daniel Minnaar
Daniel Minnaar

Reputation: 6305

Drawing multiple moving objects with GDI+

I'm drawing a few shapes on a PictureBox Image canvas, but I've run into a problem where I need to animate them around the canvas at the same time.

Because I need to update the positions of the shapes on the canvas, it means that I need to clear the canvas and redraw everything, which obviously creates a flickering effect on the update.

What options do I have to get around this problem? The only way I've found to move them around is by having the shapes 'trail' around, which is not what I want.

Here's some code to explain my predicament:

Form_Load:
      OriginalImage = pictureBox1.Image;

Timer_Tick:
    pictureBox1.Image = OriginalImage;
    Image canvas = (Image)pictureBox1.Image.Clone();
    Graphics g = Graphics.FromImage(canvas);
    g.DrawRectangle(newPosition);

Timer2_Tick:
    // This will clear the canvas and only draw the ellipse, which means I can't get both shapes on at the same time.
    pictureBox1.Image = OriginalImage;
    Image canvas = (Image)pictureBox1.Image.Clone();
    Graphics g = Graphics.FromImage(canvas);
    g.FillEllipse(newPosition);
    pictureBox1.Image = 

Upvotes: 1

Views: 1989

Answers (1)

Mitch
Mitch

Reputation: 526

Keep track of all shapes locations (which I assume you already are) and use the pictureBox's Paint event.

Then do something like this:

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawRectangle(your_rectangle);
        e.Graphics.DrawEllipse(your_ellipse);
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        pictureBox1.Invalidate();
    }

Everytime your pictureBox is now redrawn it will draw the rectangle and the ellipse at their relevant positions. To make the pictureBox update (redraw) you use the .Invalidate() method in the timer so every time your timer fires it updates your pictureBox. Set the timers interval to how often you want your image to update.

You don't need to paint the image of the pictureBox every time either, just set it once in your forms Load event.

    private void Form1_Load(object sender, EventArgs e)
    {
        pictureBox1.Image = myImage;
    }

A PictureBox is DoubleBuffered as per standard so you shouldn't get flickering.

Upvotes: 0

Related Questions