c# 带有计时器滴答闪烁的图形动画

c# graphics animation with timer tick flickering

我正在尝试在 WinForms、C# 中制作动画。我有一个计时器,对于每个滴答声,我都会围绕表单上的面板移动一个圆圈。能用,但是显示不流畅,好像有闪烁。谁能给我指出正确的方向?

为表单生成的代码:

#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;

    

自己的动画代码:

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);

        }
    }

谢谢 Jimi - 这似乎正是问题所在。 我把它改成 PictureBox 了,用起来很流畅

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();

        }