我的动画c#有几个问题

本文关键字:几个问题 动画 我的 | 更新日期: 2023-09-27 18:19:03

我正在制作一个动画量很大的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;
    }

+表示控件当前正在其他地方使用非常感谢

我的动画c#有几个问题

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

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