VB.Net中的GDI +动画滞后

时间:2015-07-25 11:20:39

标签: vb.net animation visual-studio-2013 timer

所以我在VB.Net中使用GDI来动画各种位图,位于我的根目录中的所有.png文件。现在,我在我的表单背景中绘制了一个大图像(~2MB)和动画(平移),然后在顶部绘制按钮和装饰等UI元素。我使用透明图片框代替实际按钮。我有一个功能,其中一个动画下拉菜单出现鼠标悬停,但它口吃和移动非常猛烈。它基于1ms间隔计时器改变位置以获得最大平滑度。现在,Form.Paint事件非常大:

 Private Sub scrLogin_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    'Painting the big picture in the background
    e.Graphics.DrawImage(BGbmp, bgPos.X, bgPos.Y, bgSize.Width, bgSize.Height)
    e.Graphics.FillRectangle(brushColor, Ttrim)

    'the trim around the screen
    e.Graphics.FillRectangle(brushColor, Ltrim)
    e.Graphics.FillRectangle(brushColor, Rtrim)
    e.Graphics.FillRectangle(brushColor, Btrim)

    'the middle panel
    e.Graphics.FillRectangle(brushColor, MPanel)

    ' textbox seperators
    e.Graphics.DrawLine(penWhite, txtsep1.pos1, txtsep1.pos2)
    e.Graphics.DrawLine(penWhite, txtsep2.pos1, txtsep2.pos2)

    'textbox icons
    e.Graphics.DrawImage(userbmp, 539, 312, 28, 33)
    e.Graphics.DrawImage(lockbmp, 539, 369, 28, 33)

    'login button
    e.Graphics.DrawImage(loginBmp, 539, 452, 167, 46)

    'guest button
    e.Graphics.DrawImage(guestbmp, 705, 452, 122, 46)

    'menu dropdown: position
    e.Graphics.FillRectangle(brushColor, menuBak)
    e.Graphics.DrawImage(menuBmp, menuLPos.X, menuLPos.Y, 64, 88)

    'error label text
    e.Graphics.DrawString(lblerror.Text, lblerror.Font, lblerrorBrush, lblerror.X, lblerror.Y)

    'capslock label text
    e.Graphics.DrawString(lblcaps.Text, lblcaps.Font, lblcapsBrush, lblcaps.X, lblcaps.Y)

End Sub

我想知道可能导致动画滞后的原因,我已经考虑过用鼠标点击位置检测器替换透明图片框了,但我不想不必要地做这件事。这不是问题。另一个问题是我有多个运行时间可能会相互冲突,或者1ms间隔可能太短?

这是我用来设置菜单动画的代码:

Private Sub Animation()
    Select Case menuLDir
        Case "down.png"
            If menuLPos.Y <> 0 Then
                If menuLPos.Y = -56 Then
                    menuAnimated = True
                    btnSettings.Hide()
                    btnDrop.Hide()
                    menuLPos.Y = -54
                Else
                    menuLPos.Y += 3
                End If
            Else
                menuAnimated = False
                menuLDir = "up.png"
                menuBmp = New Bitmap(menuLoc + menuLDir)
                tmrMenu.Stop()
                btnSettings.Enabled = True
                btnSettings.Show()
                btnDrop.Show()
                btnDrop.Top += 56
                menuState = "open"
            End If
        Case "up.png"
            If menuLPos.Y <> -56 Then
                If menuLPos.Y = 0 Then
                    menuAnimated = True
                    btnSettings.Hide()
                    btnDrop.Hide()
                    menuLPos.Y = -2
                Else
                    menuLPos.Y -= 3
                End If
            Else
                menuAnimated = False
                menuLDir = "down.png"
                menuBmp = New Bitmap(menuLoc + menuLDir)
                tmrMenuDelay.Stop()
                tmrMenu.Stop()
                btnSettings.Enabled = False
                btnSettings.Hide()
                btnDrop.Show()
                btnDrop.Top -= 56
                menuState = "closed"
            End If
    End Select
    menuBak = New Rectangle(menuLPos.X, menuLPos.Y, 64, 88)
    Me.Invalidate(menuRect)
End Sub

其中menuRect是菜单动画的一般区域,因此我不会不必要地刷新整个表单。 我使用DoubleBuffering和AllPaintingInWMPaint控件样式,因此不是问题所在。 为了防止这个问题变得漫长,我会发布背景动画代码(如果需要),但它基本上是2个定时器 - 1个用于控制更改图像的定时器,1个用于控制实际平移的定时器(也是1ms定时器时间) )。此外,我尽力确保我不会在.tick事件中不断声明新的位图。我还想在1ms的时间内使用一个全局计时器并运行我所有的.tick事件,但再一次,不想急于做任何事情。 对不起,很长的帖子!

0 个答案:

没有答案