I am trying to make an animation in WinForms, C#. I have a timer, and for each tick, I move a circle around a panel on a form. It works, but the display is not smooth, it seems to flicker. Anyone can point me in the right direction?
code generated for form:
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.panel1 = new System.Windows.Forms.Panel();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.White;
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panel1.Location = new System.Drawing.Point(12, 12);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(435, 313);
this.panel1.TabIndex = 0;
this.panel1.Paint = new System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
//
// timer1
//
this.timer1.Tick = new System.EventHandler(this.timer1_Tick);
//
// frmBoxerTest
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(459, 337);
this.Controls.Add(this.panel1);
this.Name = "frmBoxerTest";
this.Text = "frmBoxerTest";
this.Load = new System.EventHandler(this.frmBoxerTest_Load);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Timer timer1;
own code for animation:
public partial class frmBoxerTest : Form
{
float myLeft = 100F;
float myTop = 100F;
float horDirection = 10F;
float verDirection = 8F;
public frmBoxerTest()
{
InitializeComponent();
}
private void frmBoxerTest_Load(object sender, EventArgs e)
{
this.CenterToScreen();
this.DoubleBuffered = true;
StartShowing();
}
private void StartShowing()
{
timer1.Interval = 100;
timer1.Enabled = true;
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
//same result if I do the graphics here.
//e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
//e.Graphics.FillEllipse(Brushes.Black, myLeft, myTop, 50F, 50F);
}
private void timer1_Tick(object sender, EventArgs e)
{
if (panel1.Width <= myLeft 50F || myLeft <= -1)
{
horDirection = horDirection * -1; //reverse horizontal direciton
}
myLeft = horDirection;
if (panel1.Height <= myTop 50F || myTop <= -1)
{
verDirection = verDirection * -1; //reverse vertical direciton
}
myTop = verDirection;
Graphics g = panel1.CreateGraphics();
g.FillRectangle(Brushes.White, 0, 0, panel1.Width, panel1.Height);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.FillEllipse(Brushes.Black, myLeft, myTop, 50F, 50F);
}
}
CodePudding user response:
Thanks Jimi - that seemed to have been exactly the problem. I changed it to a PictureBox and it works smoothly
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.FillEllipse(Brushes.Black, myLeft, myTop, 50F, 50F);
}
private void timer1_Tick(object sender, EventArgs e)
{
if (pictureBox1.Width <= myLeft 50F || myLeft <= -1)
{
horDirection = horDirection * -1; //reverse horizontal direciton
}
myLeft = horDirection;
if (pictureBox1.Height <= myTop 50F || myTop <= -1)
{
verDirection = verDirection * -1; //reverse vertical direciton
}
myTop = verDirection;
//Graphics g = panel1.CreateGraphics();
//g.FillRectangle(Brushes.White, 0, 0, panel1.Width, panel1.Height);
//g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
//g.FillEllipse(Brushes.Black, myLeft, myTop, 50F, 50F);
//pictureBox1.Invalidate();
pictureBox1.Refresh();
}