vb用双缓冲让Picture绘图不闪?
我用Picture1.Line画图在一个长方形的Picture里面,用timer控制。画一个小圆,从长方形Picture的左边移动到右边。慢速移动不会闪。高速移动就很闪。...
我用Picture1.Line画图 在一个长方形的 Picture里面,用timer控制。画一个小圆,从长方形 Picture的 左边移动到右边。慢速移动不会闪。高速移动就很闪。我在网上查了下,他们说用双缓冲可以解决。双缓冲这个概念很陌生。查询API,下了好多例,套用不到我这个题目上。谁写个实例吧,或其用其他的方法实现在长方形的 Picture里面 绘图,让小圆在里面来回高速顺畅的移动。调试能用多给分。
当然是清除原来所画的在新位置再重新画.然后还是会闪。刷新速度跟不上。
有把Pictuer的Autoredraw设成True
一般方法行不通
=================================
怎么说呢?不是一闪一闪的。是不顺畅。长方形分10等分,1、2、3、4、...10
从1开始移动。按照常理是234顺序移动,但是快速移动就跳了。1 3 6 9 10 这样移动。感觉不顺畅。
写段代码吧?
===============================
来回显示?车轮战行不通。我看见别人好像用其他API写的。N个小球在picture里面来回飞超顺畅的。
===============================
找不到好的解决方法。用image代替绘图也卡。找不到可以模拟小球(不管事绘制的,还是image或者其他)在picture里面顺畅的高速来回移动。不跳帧。 展开
当然是清除原来所画的在新位置再重新画.然后还是会闪。刷新速度跟不上。
有把Pictuer的Autoredraw设成True
一般方法行不通
=================================
怎么说呢?不是一闪一闪的。是不顺畅。长方形分10等分,1、2、3、4、...10
从1开始移动。按照常理是234顺序移动,但是快速移动就跳了。1 3 6 9 10 这样移动。感觉不顺畅。
写段代码吧?
===============================
来回显示?车轮战行不通。我看见别人好像用其他API写的。N个小球在picture里面来回飞超顺畅的。
===============================
找不到好的解决方法。用image代替绘图也卡。找不到可以模拟小球(不管事绘制的,还是image或者其他)在picture里面顺畅的高速来回移动。不跳帧。 展开
3个回答
展开全部
这个,等着学习学习
个人感觉timer,不论是函数还是控件,都不是太精确,1秒只有18次时钟触发,最小时间间隔是0.055秒左右,而现在电脑的处理能力都很强大,0.001秒内能处理很多句VB的代码了,所以应该用kernel32.dll下的GetTickCount函数来处理时间间隔,这个函数可以产生一个长整型的数值,该数值是从系统启动后经过的毫秒数,很精确,基本上可以精确到0.001秒。
还有,把Pictuer的Autoredraw设成True试试。
那个,问个问题,双缓冲是不是因为要执行两遍,所以会慢很多?
找到一种不闪的方法,先把Autoredraw设成True,然后用Pset画点,呵呵,一定不闪,只是那个效率吗,可以说是比较惨。
如果有更好的方法就好了。
试了试,效率上真是比较差啊。
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub Command1_Click()
Const Tz As Long = 10
Dim i As Long, j As Long, k As Long, n As Long
Dim Px As Long, Py As Long
Dim C As Long, Ti As Long
Picture1.ScaleMode = 3
Picture1.DrawWidth = 1
Picture1.AutoRedraw = True
Px = Picture1.ScaleWidth
Py = Picture1.ScaleHeight
Randomize
i = Int(Rnd * 256)
Randomize
j = Int(Rnd * 256)
Randomize
k = Int(Rnd * 256)
C = RGB(i, j, k)
k = IIf(Px > Py, Py, Px) \ 8
Randomize
i = Int(Rnd * (Px - 2 * k))
Randomize
j = Int(Rnd * (Py - 2 * k))
Do
Ti = GetTickCount
Do
DoEvents
Loop While GetTickCount - Ti < Tz
Randomize
n = Int(Rnd * 4)
Select Case n
Case 0
If i > k Then i = i - 1
Case 1
If i < Px - k Then i = i + 1
Case 2
If j > k Then j = j - 1
Case 3
If j < Py - k Then j = j + 1
End Select
Picture1.Cls
Picture1.Circle (i, j), k, C
Loop
End Sub
Private Sub Command2_Click()
Const Tz As Long = 10
Dim i As Long, j As Long, k As Long, n As Long
Dim Px As Long, Py As Long
Dim C As Long, Ti As Long
Picture1.ScaleMode = 3
Picture1.DrawWidth = 1
Picture1.AutoRedraw = True
Px = Picture1.ScaleWidth - 1
Py = Picture1.ScaleHeight - 1
Randomize
i = Int(Rnd * 256)
Randomize
j = Int(Rnd * 256)
Randomize
k = Int(Rnd * 256)
C = RGB(i, j, k)
k = IIf(Px > Py, Py, Px) \ 8
Randomize
i = Int(Rnd * (Px - 2 * k))
Randomize
j = Int(Rnd * (Py - 2 * k))
i = k
j = k
n = 1
Do
Ti = GetTickCount
Do
DoEvents
Loop While GetTickCount - Ti < Tz
Select Case n
Case 1
If i < Px - k Then
i = i + 1
Else
n = 2
j = j + 1
End If
Case 2
If j < Py - k Then
j = j + 1
Else
n = 3
i = i - 1
End If
Case 3
If i > k Then
i = i - 1
Else
n = 4
j = j - 1
End If
Case 4
If j > k Then
j = j - 1
Else
n = 1
i = i + 1
End If
End Select
Picture1.Cls
Picture1.Circle (i, j), k, C
Loop
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
End
End Sub
个人感觉timer,不论是函数还是控件,都不是太精确,1秒只有18次时钟触发,最小时间间隔是0.055秒左右,而现在电脑的处理能力都很强大,0.001秒内能处理很多句VB的代码了,所以应该用kernel32.dll下的GetTickCount函数来处理时间间隔,这个函数可以产生一个长整型的数值,该数值是从系统启动后经过的毫秒数,很精确,基本上可以精确到0.001秒。
还有,把Pictuer的Autoredraw设成True试试。
那个,问个问题,双缓冲是不是因为要执行两遍,所以会慢很多?
找到一种不闪的方法,先把Autoredraw设成True,然后用Pset画点,呵呵,一定不闪,只是那个效率吗,可以说是比较惨。
如果有更好的方法就好了。
试了试,效率上真是比较差啊。
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub Command1_Click()
Const Tz As Long = 10
Dim i As Long, j As Long, k As Long, n As Long
Dim Px As Long, Py As Long
Dim C As Long, Ti As Long
Picture1.ScaleMode = 3
Picture1.DrawWidth = 1
Picture1.AutoRedraw = True
Px = Picture1.ScaleWidth
Py = Picture1.ScaleHeight
Randomize
i = Int(Rnd * 256)
Randomize
j = Int(Rnd * 256)
Randomize
k = Int(Rnd * 256)
C = RGB(i, j, k)
k = IIf(Px > Py, Py, Px) \ 8
Randomize
i = Int(Rnd * (Px - 2 * k))
Randomize
j = Int(Rnd * (Py - 2 * k))
Do
Ti = GetTickCount
Do
DoEvents
Loop While GetTickCount - Ti < Tz
Randomize
n = Int(Rnd * 4)
Select Case n
Case 0
If i > k Then i = i - 1
Case 1
If i < Px - k Then i = i + 1
Case 2
If j > k Then j = j - 1
Case 3
If j < Py - k Then j = j + 1
End Select
Picture1.Cls
Picture1.Circle (i, j), k, C
Loop
End Sub
Private Sub Command2_Click()
Const Tz As Long = 10
Dim i As Long, j As Long, k As Long, n As Long
Dim Px As Long, Py As Long
Dim C As Long, Ti As Long
Picture1.ScaleMode = 3
Picture1.DrawWidth = 1
Picture1.AutoRedraw = True
Px = Picture1.ScaleWidth - 1
Py = Picture1.ScaleHeight - 1
Randomize
i = Int(Rnd * 256)
Randomize
j = Int(Rnd * 256)
Randomize
k = Int(Rnd * 256)
C = RGB(i, j, k)
k = IIf(Px > Py, Py, Px) \ 8
Randomize
i = Int(Rnd * (Px - 2 * k))
Randomize
j = Int(Rnd * (Py - 2 * k))
i = k
j = k
n = 1
Do
Ti = GetTickCount
Do
DoEvents
Loop While GetTickCount - Ti < Tz
Select Case n
Case 1
If i < Px - k Then
i = i + 1
Else
n = 2
j = j + 1
End If
Case 2
If j < Py - k Then
j = j + 1
Else
n = 3
i = i - 1
End If
Case 3
If i > k Then
i = i - 1
Else
n = 4
j = j - 1
End If
Case 4
If j > k Then
j = j - 1
Else
n = 1
i = i + 1
End If
End Select
Picture1.Cls
Picture1.Circle (i, j), k, C
Loop
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
End
End Sub
展开全部
如果是 画的圆,移动的话,一般就是先用背景色,清除原来所画的
在新位置再重新画,如果是移动过快或是移动的同时还有其他绘图操作,
往往会出现明显的闪烁。
双缓冲就是在另外的不可见的 比如 Picture上把清除和重画全部处理完毕,
再一次性复制到可见画面,这样就会避免闪烁
闪就是因为在 Picture 直接清除 重画,由于人眼的视觉暂留会感觉到闪烁
双缓冲是在另外的隐藏的 Picture 上完成整个操作,再将画面贴出来
在新位置再重新画,如果是移动过快或是移动的同时还有其他绘图操作,
往往会出现明显的闪烁。
双缓冲就是在另外的不可见的 比如 Picture上把清除和重画全部处理完毕,
再一次性复制到可见画面,这样就会避免闪烁
闪就是因为在 Picture 直接清除 重画,由于人眼的视觉暂留会感觉到闪烁
双缓冲是在另外的隐藏的 Picture 上完成整个操作,再将画面贴出来
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
1用两个picture
2叠起来一在上二在下
3先显示第一个,清除第二个,在第二个上面画画
4设置第一个不可见,清除第一个,在第一个上面画画,设置第一个可见
5循环3、4
还要把picture的Autoredraw都设成True
2叠起来一在上二在下
3先显示第一个,清除第二个,在第二个上面画画
4设置第一个不可见,清除第一个,在第一个上面画画,设置第一个可见
5循环3、4
还要把picture的Autoredraw都设成True
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询