然后我的水波特效是写在一个模块中的,然后因为我做的美化是半透明+模糊,然后再加水波特效的,因此在水波特效进行前必须要初始化一下,将要进行水波特效的图片读取进来,代码如下: Friend Sub Ini() For i = 0 To number ‘这里初始化了波幅用的两个数组 Buff1(i) = 0 Buff2(i) = 0 Next WBMG = BMG.Clone ’创建了要进行水波特效的图片的副本以便保存水波化后的图片 Dim source As BitmapData = BMG.LockBits(rt, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb) ‘将图片锁定到内存中提高处理速度 ReDim soudata(number) Marshal.Copy(source.Scan0, soudata, 0, number) ‘上面两句是将内存中图片的Argb通道以整型的形式拷贝到数组方便处理 BMG.UnlockBits(source) ’内存解锁,防止图片再次使用时提示内存被锁定的错误 End Sub
下面的代码给出的是波源投放的代码,因为我的图片是800*600的,因此波源直径5,波源影响范围调成64是比较合适的,这两个值需要根据自己图片的大小来调整的 Friend Function DropSton(ByVal x As Integer, ByVal y As Integer, Optional ByVal SouSize As Integer = 5, Optional ByVal SouWeight As Integer = 64) If x + SouSize > w OrElse y + SouSize > h Or x - SouSize < 0 Or y - SouSize < 0 Then Return Nothing ‘这里用来进行边界判断,防止数组溢出 End If For posx = x - SouSize To x + SouSize For posy = y - SouSize To y + SouSize If ((posx - x) * (posx - x) + (posy - y) * (posy - y) < SouSize * SouSize) Then Buff1(w * posy + posx) = -SouWeight ’波源投放,其实就是在波源直径区域将Buff数组赋初始值,以便进一步产生水波 End If Next Next Return Nothing End Function
接下来的代码是波幅计算的,为了提高计算速度,采用移位计算,没什么好说的,就是这么算的,具体原因去看原始的网址吧,涉及到数学归纳法,我没仔细算,只是把结果挪过来了 Friend Function RippleSpread() On Error Resume Next For i = w to w*h-w-1 Buff2(i) = ((Buff1(i - 1) + Buff1(i+ 1) + Buff1(i- w) + Buff1(i+ w)) >> 1) - Buff2(i) Buff2(i) -= Buff2(i) >>4 '波幅衰减 Next Next dim tmp as short()=buff1 ‘这里开始交换buff1和buff2,是为了让波源能继续传播下去 buff1=buff2 buff2=tmp End Sub
然后是画面渲染 Private Function RenderRipple(ByRef soudata As Integer(), ByRef desdata As Integer()) Dim xoff, yoff As Integer Dim k As Integer = w For i = 1 To h - 2 For j = 0 To w - 1 xoff = Buff1(k - 1) - Buff1(k + 1) ’x方向的偏移 yoff = Buff1(k - w) - Buff1(k + w) ‘y方向的偏移 If (xoff = 0 AndAlso yoff = 0) OrElse i + yoff <= 0 OrElse i + yoff >= h OrElse j + xoff <= 0 OrElse j + xoff >= w Then k += 1 ’这个是边界判断,用Orelse提高判断效率 Continue For End If Dim pos1, pos2 As Integer pos1 = (i + yoff) * w + j + xoff pos2 = i * w + j desdata(pos2) = soudata(pos1) ‘然后就是根据偏移量重新渲染界面 k += 1 Next Next Return Nothing End Function