What is the most effective method to make an animation on the Form?

Now I'm doing the following: I paint the rectangle in order to clear the old picture, and I draw the new picture after that.
It was working properly in C++ Builder. But it's working very slowly in Visual C++ 2008.

Is there any other more effective way to make the animation on the Form? Basicly I use the simple shapes like DrawLines, FillPolygon and other.

Thank you!

Edited 6 Years Ago by valeriy_zf: n/a

The best way in your case (with the .NET) is to create 2 timer objects, one for the "background" animation and one to pace the foreground changes.

You can have two methods, one in each of the timers (one for drawing the foreground elements and one for the background) that makes all the necessary positional changes and then you can call Invalidate() at the end of the timer_tick event.

Also important is to go to the properties page of the form and make sure double buffering is set to true.

Ok, Thanks for the answer.
But what is the difference between these two methods?:

1) You proposed:
To create 2 timer objects, one for the "background" animation and one to pace the foreground changes.

2)I'm using:
I create 1 timer object only and 1 method for it. I draw the "background" first (in this method), and the foreground changes after that in the same method.

---------
I just read some articles about the InvalidateRect() method. I'm not sure if I understand:
How does the InvalidateRect() method actually work? It just calls all the drawing methods above him and draw everything in the limited rectangle area?

---------
Another issue: I draw the picture not directly on the Form, but on the Panel. The DoubleBuffering property is protected here :(

I draw the "background" first (in this method), and the foreground changes

The difference is twofold. First, your background (I'm guessing) probably requires a lower refresh rate. This way you can update the background only 3/4 as often or whatnot and give some of the performance to your foreground elements. Also, each timer is in its own thread. That may be one of those "for better or for worse" kind of situations. See this about having 2 timers work together.

I'm not familiar with InvalidateRect but the information I found on it would lead me to believe that you can specify a region of your window to invalidate (like if you had a rapidly changing region and perhaps didn't need to repaint the rest of the scene as often). Analogous to the way Invalidate() calls the Paint method of the form in .NET, InvalidateRect works at a more fundamental level. I don't know the details. It's a Win32 function so it means you'd have to use DllImport with it to use it with .NET (there's a MFC version too but that won't help you in this instance).

Take a look around about double buffering. I don't know the answer to that one. I know that Panel doesn't have a double-buffering property to change but I don't know whether it falls under the blanket of the entire form.

I wish I had more information for you. Poke around in the C# forum archives for the answers to some of these because they'll be directly transferable.

Another issue: I draw the picture not directly on the Form, but on the Panel. The DoubleBuffering property is protected here :(

You might derive from Panel class and use the derived class as your Panel with DoubleBuffering enabled. Lukezzz was doing the same thing here. Though it seemed that the double-buffering did not help him too much, then again, he has 200 buttons on that derived Panel (which is a lot of buttons) and your situation might be very different.

mitrmkar, I have reassigned my panel to the DoubleBufferPanel class. Thanks to this thread, it's working properly.
But it is not working faster, unfortunately. The animation is blinking with the same frequency. And my Form was totally destroyed in the Form1.h[Constructor] after that. Instead of my Form components, I saw the scope of Errors alerts. So, I had to return back the normal Panel.

What I'm doing now: I'm trying to apply the Invalidate() method to my Project. But I'm not sure if this method applicable in my case (I mean making the movie picture).
As I understood, this is being used for the Bitmap picture (or other picture from file), but not for the picture drawing by the C++ code (DrawLines, FillPolygon, etc).

Let's see the simple example. There is the procedure that draws the circle every time in new position:

float Move_Circle(float circle_x_coordinate)
{
  Pen^ pen = gcnew Pen(col->Black);
  Graphics^ panel_picture=  Form1->panel1->CreateGraphics();

  panel_picture->Clear(); // I clean the panel with the circle in the old position

  circle_x_coordinate += 5; // reassign the next circle position

  panel_picture->DrawEllipse(pen, circle_x_coordinate, 100, 10, 10); // draw the circle in the new position

  return circle_x_coordinate;
}

There is the cycle somewhere in the code which calls this function:

....
for (int i=1; i<50; i++)
{
  static float circle_x_coordinate= Move_Circle(circle_x_coordinate);
  Delay(100); // delay programm for 100 msec
}

I would be really happy if someone can explain using this example, how the Invalidate() method is working. Where I shoud insert it here?
The MSDN help shows it on the picture loaded from file and a bit complicated for understanding.

I think, It should be the method that draws all the picture objects at the same time (but not the separately clear form first, and draw other objects next). For example, some method, which filles the picture to some bitmap array first, and draw the picture on the form from this array. Just replace the old picture with the new one. It will not be blinnking while moving objects in this case...

Thanks to all!

You don't need the delay function, use a timer. Drag one over to your form from the ToolBox (or create it in code). Place your Move_circle method into the Paint event of the form. Within your timer call Invalidate() with each cycle which will invoke the Paint method.

Yeh, I did it. Thanks for the explanations.
Unfortunatelly there is no better effect enyway. May be my picture is too much complicated...

This article has been dead for over six months. Start a new discussion instead.