我的动画几乎没有问题c#

时间:2013-06-20 02:10:07

标签: c# winforms animation while-loop

我正在开发一个动画重量级的winforms应用程序,我将自己的所有动画制作完成。 我使用枚举,其中包含用于调用新线程的所有动画,该线程运行适当控件的相应动画。这是一个例子:

    private void animateBackColor(Control control)
    {
        int i = 0;
        while (i <= 255)
        {
            control.BackColor = Color.FromArgb(i, control.BackColor);
            i += 15;
            Thread.Sleep(15);
        }
    }

问题如下:

+有时候,动画会变得过于暴躁和迟钝而且会变得很糟糕。

+由移动的控件重叠的控件需要很长时间来重新绘制看起来很难看的内容。

+我很少得到这个错误“在枚举器被实例化之后修改了集合”在更改控件属性的部分中。

这个动画在图像中消失也存在问题:

    private void animateFadeOut(Control control)
    {
        int i = 255;
        while (i > 15)
        {
            control.BackColor = Color.FromArgb(i, control.BackColor);
            i -= 30;
            Thread.Sleep(5);
        }
        PNL_runningDownloads.Controls.Remove(control);
    }

    public static Bitmap ChangeOpacity(Image img, float opacityvalue)
    {
            Bitmap bmp = new Bitmap(img.Width, img.Height); // Determining Width and Height of Source Image
            Graphics graphics = Graphics.FromImage(bmp);
            ColorMatrix colormatrix = new ColorMatrix {Matrix33 = opacityvalue};
            ImageAttributes imgAttribute = new ImageAttributes();
            imgAttribute.SetColorMatrix(colormatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
            graphics.DrawImage(img, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, img.Width, img.Height,
            GraphicsUnit.Pixel, imgAttribute);
        graphics.Dispose(); // Releasing all resource used by graphics 
        return bmp;
    }

+它说该控件目前在其他地方使用 非常感谢你:))

1 个答案:

答案 0 :(得分:1)

我设法找到了我使用重型动画的程序。以下是主循环的样子:

static void Main() {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    Form1 form = new Form1();
    Clock clk = new Clock();
    FPSCounter counter = new FPSCounter();

    form.Show();
    clk.Reset();
    counter.Frequency = clk.Frequency;
    counter.RefreshRate = clk.Frequency / 2;

    double delta, time = 0f;
    long tick;


    while (form.Created) {
        tick = clk.TicksDelta();
        delta = (double)tick / clk.Frequency;
        time += delta;


        form.Update(delta, time);
        Application.DoEvents();

        counter.tick(tick);
        form.Text = counter.ToString();
    }
}

时钟类实现:

public class Clock {
    [DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
    private static extern bool QueryPerformanceCounter(out long ticks);
    [DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
    private static extern bool QueryPerformanceFrequency(out long freq);


    private long myTmpFreq;
    private long myTmpCtr;
    private long myDeltaCtr;
    private long myDelta;

    public long Frequency {
        get {
            return myTmpFreq;
        }
    }
    public long Counter {
        get {
            QueryPerformanceCounter(out myTmpCtr);
            return myTmpCtr;
        }
    }

    public void Reset() {
        myDeltaCtr = Counter;
    }
    public long TicksDelta() {
        QueryPerformanceCounter(out myTmpCtr);
        myDelta = myTmpCtr - myDeltaCtr;
        myDeltaCtr = myTmpCtr;
        return myDelta;
    }
    public double Delta() {
        return (double)TicksDelta() / myTmpFreq;
    }


    public Clock() {
        QueryPerformanceFrequency(out myTmpFreq);
    }
}

如果以这种方式制作WinForms应用程序,您将能够运行“实时”动画并使用UI线程。一切都会顺利而美好。

希望这会有所帮助。如果您还有其他问题,请告诉我们。

编辑:FPS计数器实施

public class FPSCounter {
    private const int BUFFER_SIZE = 25;
    private long[] myTicks = new long[BUFFER_SIZE];
    private int myIdx;


    private decimal myFPS;
    public decimal FPS {
        get {
            return myFPS;
        }
    }

    private long myRefreshRate;
    public long RefreshRate {
        get {
            return myRefreshRate;
        }
        set {
            myRefreshRate = value;
        }
    }

    private long myFreq;

    public long Frequency {
        get { return myFreq; }
        set { myFreq = value; }
    }

    private long myTick;
    public void tick(long tick) {
        myTicks[myIdx++] = tick;
        if (myIdx >= BUFFER_SIZE)
            myIdx = 0;

        myTick += tick;
        if (myTick > myRefreshRate) {
            myTick = 0;
            myFPS = count();
        }
    }

    private decimal count() {
        long sum = 0;
        foreach (long i in myTicks)
            sum += i;

        if (sum == 0)
            return 0;

        return myFreq / (sum / myTicks.Length);
    }

    public override string ToString() {
        return String.Format("FPS: {0}", FPS);
    }

}