矩形运动似乎口吃

时间:2014-02-03 10:41:05

标签: c# winforms

我正在尝试编写一个程序,它会在屏幕顶部显示一条图标,以便快速访问文件。为了进行早期测试,我正在绘制一个矩形,我正在按照一个临时位置来检查它在屏幕上移动的顺畅程度。

    public Pen defaultPen;

    public PointF tempLocation = new PointF( 10, 10 );

    public Timer updateTimer = new Timer();

    public DesktopStrip()
    {
        this.Size = new Size( Screen.PrimaryScreen.Bounds.Width, 88 );
        this.Top = 10;

        this.FormBorderStyle = FormBorderStyle.None;
        this.BackColor = Color.Black;
        this.Paint += new PaintEventHandler( PaintDesktop );

        this.SetStyle( ControlStyles.AllPaintingInWmPaint |
                       ControlStyles.OptimizedDoubleBuffer |
                       ControlStyles.UserPaint, true );

        this.defaultPen = new Pen( Color.White );

        this.updateTimer.Interval = 30;
        this.updateTimer.Tick += new EventHandler( anim_Tick );
        this.updateTimer.Start();
    }

    private void anim_Tick( object sender, EventArgs e )
    {
        tempLocation.X++;

        Refresh();
    }

    private void PaintDesktop( object sender, PaintEventArgs e )
    {
        Graphics g = e.Graphics;
        g.InterpolationMode = InterpolationMode.Low;
        g.PixelOffsetMode = PixelOffsetMode.None;
        g.SmoothingMode = SmoothingMode.None;

        g.DrawRectangle( defaultPen, new Rectangle( (int)tempLocation.X, (int)tempLocation.Y, 64, 64 ) );
    }

我的问题是,当它在屏幕上移动时,我可以看到它在点上口吃,我需要它尽可能地平滑。我有什么遗失或者我可以改变吗?

我尝试过使用invalidate而不是刷新,但它不会在视觉上改变任何东西。

有没有其他方法可以做到这一点而不是使用winforms?什么东西可能更适合动画?

编辑:我更改了anim_Tick方法以合并插值:

tempLocation.X = (float)Lerp( tempLocation.X, moveLoc.X, 0.05 );

我的插值方法是:

public double Lerp( double value1, double value2, double amount )
{
    value1 = value1 + ( value2 - value1 ) * amount;

    return value1;
}

我还将定时器间隔更改为30ms。尽管如此,我仍然可以看到动作中的一个口吃。

1 个答案:

答案 0 :(得分:0)

你的问题就是问题。

您要求UI每隔1 ms刷新一次位置。那太频繁了。计算偏移量并达到实际渲染代码所需的时间最多可能需要5倍(如果不是10倍)。考虑在更新之间使用插值位置,并将它们隔开,每30毫秒说一次。

基本上你需要每秒移动矩形几个像素。您需要使用Lerp函数来执行此操作。

以下是open source project应该有用的链接。