• Vui lòng đọc nội qui diễn đàn để tránh bị xóa bài viết
  • Tìm kiếm trước khi đặt câu hỏi

Hiệu ứng sóng nước

Bộ sưu tập các thư viện hỗ trợ sẳn cho Visual Basic .NET và C#

Điều hành viên: tungcan5diop, QUANITGROBEST

Nội qui chuyên mục
1. Gửi bài viết tại đây, Tester sẽ chuyển vào trong nếu bài viết đạt yêu cầu.
2. Gửi bài theo mẫu qui định: viewtopic.php?f=2&t=5
[ten][/ten]
[loai][/loai]
[ngonngu][/ngonngu]
[tacgia][/tacgia]
[chucnang][/chucnang]
[end][/end]
Hình đại diện của người dùng
akira
Thành viên danh dự
Thành viên danh dự
Bài viết: 354
Ngày tham gia: T.Bảy 25/10/2008 11:11 pm
Has thanked: 6 time
Been thanked: 69 time

Hiệu ứng sóng nước

Gửi bàigửi bởi akira » T.Ba 10/07/2012 2:56 pm

Tên: Hiệu ứng sóng nước
Loại: UserControl
Ngôn ngữ lập trình: VB.Net
Tác giả: Sưu tầm
Chức năng: Tạo hiệu ứng sóng nước trên PictureBox



Hình ảnh

Các bác có thể tùy chỉnh lại để hiệu ứng được mượt hơn nhé :)

  1. Imports System
  2. Imports System.Collections
  3. Imports System.Drawing
  4. Imports System.Drawing.Imaging
  5. Imports System.Runtime.InteropServices
  6. Imports System.Windows.Forms
  7.  
  8. Public Class WaterFX
  9.  
  10.     Inherits System.Windows.Forms.Panel
  11.  
  12.     Private effectTimer As System.Windows.Forms.Timer
  13.     Private tmrBalance As System.Windows.Forms.Timer
  14.     Private components As System.ComponentModel.IContainer
  15.  
  16.     Private _bmp As Bitmap
  17.     Private _waves As Short(,,)
  18.     Private _waveWidth As Integer
  19.     Private _waveHeight As Integer
  20.     Private _activeBuffer As Integer = 0
  21.     Private _weHaveWaves As Boolean
  22.     Private _bmpHeight As Integer, _bmpWidth As Integer
  23.     Private _bmpBytes As Byte()
  24.     Private _bmpBitmapData As BitmapData
  25.     Private _scale As Integer
  26.  
  27.     Private __IsBusy As Boolean
  28.  
  29.     Private Sub InitializeComponent()
  30.         Me.components = New System.ComponentModel.Container()
  31.         Me.effectTimer = New System.Windows.Forms.Timer(Me.components)
  32.         Me.tmrBalance = New System.Windows.Forms.Timer(Me.components)
  33.  
  34.         AddHandler Me.effectTimer.Tick, AddressOf Me.effectTimer_Tick
  35.         AddHandler Me.tmrBalance.Tick, AddressOf Me.tmrBalance_Tick
  36.  
  37.         AddHandler Me.Paint, AddressOf Me.WaterEffectControl_Paint
  38.         AddHandler Me.MouseMove, AddressOf Me.WaterEffectControl_MouseMove
  39.     End Sub
  40.  
  41.     Public Sub New()
  42.         InitializeComponent()
  43.         effectTimer.Enabled = True
  44.         effectTimer.Interval = 50
  45.         tmrBalance.Interval = 100
  46.         SetStyle(ControlStyles.UserPaint, True)
  47.         SetStyle(ControlStyles.AllPaintingInWmPaint, True)
  48.         SetStyle(ControlStyles.DoubleBuffer, True)
  49.         Me.BackColor = Color.Transparent
  50.         _weHaveWaves = False
  51.         _scale = 1
  52.     End Sub
  53.  
  54.     Public Sub New(ByVal bmp As Bitmap)
  55.         Me.New()
  56.         Me.ImageBitmap = bmp
  57.     End Sub
  58.  
  59.     Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
  60.         If disposing Then If components IsNot Nothing Then components.Dispose()
  61.         MyBase.Dispose(disposing)
  62.     End Sub
  63.  
  64.     Private Sub effectTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs)
  65.         If _weHaveWaves Then
  66.             Invalidate()
  67.             ProcessWaves()
  68.         End If
  69.     End Sub
  70.  
  71.     Private Sub tmrBalance_Tick(ByVal sender As Object, ByVal e As System.EventArgs)
  72.         __IsBusy = Not __IsBusy
  73.     End Sub
  74.  
  75.     Public Sub WaterEffectControl_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
  76.         If IsNothing(_bmp) Then Return
  77.         Dim tmp As Bitmap = Nothing
  78.  
  79.         On Error Resume Next
  80.  
  81.         tmp = DirectCast(_bmp.Clone(), Bitmap)
  82.         Dim xOffset As Integer, yOffset As Integer
  83.         Dim alpha As Byte
  84.  
  85.         If _weHaveWaves Then
  86.             Dim tmpData As BitmapData = tmp.LockBits(New Rectangle(0, 0, _bmpWidth, _bmpHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)
  87.             Dim tmpBytes As Byte() = New Byte(_bmpWidth * _bmpHeight * 4 - 1) {}
  88.             Marshal.Copy(tmpData.Scan0, tmpBytes, 0, _bmpWidth * _bmpHeight * 4)
  89.  
  90.             For x As Integer = 1 To _bmpWidth - 2
  91.                 For y As Integer = 1 To _bmpHeight - 2
  92.                     Dim waveX As Integer = CInt(x) >> _scale
  93.                     Dim waveY As Integer = CInt(y) >> _scale
  94.  
  95.                     If waveX <= 0 Then waveX = 1
  96.                     If waveY <= 0 Then waveY = 1
  97.                     If waveX >= _waveWidth - 1 Then waveX = _waveWidth - 2
  98.                     If waveY >= _waveHeight - 1 Then waveY = _waveHeight - 2
  99.  
  100.                     xOffset = (_waves(waveX - 1, waveY, _activeBuffer) - _waves(waveX + 1, waveY, _activeBuffer)) >> 3
  101.                     yOffset = (_waves(waveX, waveY - 1, _activeBuffer) - _waves(waveX, waveY + 1, _activeBuffer)) >> 3
  102.  
  103.                     If (xOffset <> 0) OrElse (yOffset <> 0) Then
  104.                         If x + xOffset >= _bmpWidth - 1 Then xOffset = _bmpWidth - x - 1
  105.                         If y + yOffset >= _bmpHeight - 1 Then yOffset = _bmpHeight - y - 1
  106.                         If x + xOffset < 0 Then xOffset = -x
  107.                         If y + yOffset < 0 Then yOffset = -y
  108.                         If xOffset <= 0 Then xOffset = 0
  109.  
  110.                         alpha = CByte(200 - xOffset)
  111.                         If alpha < 0 Then alpha = 0
  112.                         If alpha > 255 Then alpha = 254
  113.  
  114.                         tmpBytes(4 * (x + y * _bmpWidth)) = _bmpBytes(4 * (x + xOffset + (y + yOffset) * _bmpWidth))
  115.                         tmpBytes(4 * (x + y * _bmpWidth) + 1) = _bmpBytes(4 * (x + xOffset + (y + yOffset) * _bmpWidth) + 1)
  116.                         tmpBytes(4 * (x + y * _bmpWidth) + 2) = _bmpBytes(4 * (x + xOffset + (y + yOffset) * _bmpWidth) + 2)
  117.                         tmpBytes(4 * (x + y * _bmpWidth) + 3) = alpha
  118.  
  119.                     End If
  120.                 Next
  121.                 If Not Err.Number = 0 Then Exit For
  122.             Next
  123.  
  124.             Marshal.Copy(tmpBytes, 0, tmpData.Scan0, _bmpWidth * _bmpHeight * 4)
  125.             tmp.UnlockBits(tmpData)
  126.         End If
  127.         e.Graphics.DrawImage(tmp, 0, 0, Me.ClientRectangle.Width, Me.ClientRectangle.Height)
  128.         If Not Err.Number = 0 Then Debug.WriteLine("WaterEffectControl_Paint: " & Err.Description)
  129.         If Not IsNothing(tmp) Then tmp.Dispose()
  130.     End Sub
  131.  
  132.     Private Sub ProcessWaves()
  133.         Dim newBuffer As Integer = If((_activeBuffer = 0), 1, 0)
  134.         Dim wavesFound As Boolean = False
  135.         If newBuffer < 0 Then newBuffer = 1
  136.  
  137.         On Error Resume Next
  138.         For x As Integer = 1 To _waveWidth - 2
  139.             For y As Integer = 1 To _waveHeight - 2
  140.                 _waves(x, y, newBuffer) = CShort((((_waves(x - 1, y - 1, _activeBuffer) + _waves(x, y - 1, _activeBuffer) +
  141.                                                     _waves(x + 1, y - 1, _activeBuffer) + _waves(x - 1, y, _activeBuffer) +
  142.                                                     _waves(x + 1, y, _activeBuffer) + _waves(x - 1, y + 1, _activeBuffer) +
  143.                                                     _waves(x, y + 1, _activeBuffer) + _waves(x + 1, y + 1, _activeBuffer)) >> 2) - _waves(x, y, newBuffer)))
  144.                 If _waves(x, y, newBuffer) <> 0 Then
  145.                     _waves(x, y, newBuffer) -= CShort((_waves(x, y, newBuffer) >> 4))
  146.                     wavesFound = True
  147.                 End If
  148.                 If Not Err.Number = 0 Then Exit For
  149.             Next
  150.             If Not Err.Number = 0 Then Exit For
  151.         Next
  152.         _weHaveWaves = wavesFound
  153.         _activeBuffer = newBuffer
  154.     End Sub
  155.  
  156.     Private Sub PutDrop(ByVal x As Integer, ByVal y As Integer, ByVal height As Short)
  157.         _weHaveWaves = True
  158.         Dim radius As Integer = 20
  159.         Dim dist As Double
  160.         On Error Resume Next
  161.         For i As Integer = -radius To radius
  162.             For j As Integer = -radius To radius
  163.                 If ((x + i >= 0) AndAlso (x + i < _waveWidth - 1)) AndAlso ((y + j >= 0) AndAlso (y + j < _waveHeight - 1)) Then
  164.                     dist = Math.Sqrt(i * i + j * j)
  165.                     If dist < radius Then
  166.                         _waves(x + i, y + j, _activeBuffer) = CShort((Math.Cos(dist * Math.PI / radius) * height))
  167.                     End If
  168.                 End If
  169.                 If Not Err.Number = 0 Then Return
  170.             Next
  171.             If Not Err.Number = 0 Then Return
  172.         Next
  173.     End Sub
  174.  
  175.     Private Sub WaterEffectControl_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  176.         On Error Resume Next
  177.         If Not __IsBusy Then
  178.             Dim realX As Integer = CInt(((e.X / CDbl(Me.ClientRectangle.Width)) * _waveWidth))
  179.             Dim realY As Integer = CInt(((e.Y / CDbl(Me.ClientRectangle.Height)) * _waveHeight))
  180.             If Not Err.Number = 0 Then Return
  181.             PutDrop(realX, realY, 200)
  182.         End If
  183.         If Not tmrBalance.Enabled Then tmrBalance.Start()
  184.     End Sub
  185.  
  186. #Region "Properties"
  187.  
  188.     Public Property ImageBitmap() As Bitmap
  189.         Get
  190.             Return _bmp
  191.         End Get
  192.         Set(ByVal value As Bitmap)
  193.             _bmp = value
  194.             If IsNothing(_bmp) Then
  195.                 effectTimer.Stop()
  196.                 tmrBalance.Stop()
  197.                 Return
  198.             Else
  199.                 effectTimer.Start()
  200.                 __IsBusy = False
  201.             End If
  202.             _bmpHeight = _bmp.Height
  203.             _bmpWidth = _bmp.Width
  204.  
  205.             _waveWidth = _bmpWidth >> _scale
  206.             _waveHeight = _bmpHeight >> _scale
  207.             _waves = New Int16(_waveWidth - 1, _waveHeight - 1, 1) {}
  208.  
  209.             _bmpBytes = New Byte(_bmpWidth * _bmpHeight * 4 - 1) {}
  210.             _bmpBitmapData = _bmp.LockBits(New Rectangle(0, 0, _bmpWidth, _bmpHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)
  211.             Marshal.Copy(_bmpBitmapData.Scan0, _bmpBytes, 0, _bmpWidth * _bmpHeight * 4)
  212.         End Set
  213.     End Property
  214.  
  215.     Public Shadows Property Scale() As Integer
  216.         Get
  217.             Return _scale
  218.         End Get
  219.         Set(ByVal value As Integer)
  220.             _scale = value
  221.         End Set
  222.     End Property
  223.  
  224. #End Region
  225.  
  226. End Class



Hình đại diện của người dùng
khoaakt
Thành viên năng nổ
Thành viên năng nổ
Bài viết: 75
Ngày tham gia: T.Ba 19/06/2012 6:30 pm
Đến từ: http://việtnam.vn/Kontum/Trường/THPT Chuyên Nguyễn Tất Thành.htm
Has thanked: 8 time
Been thanked: 7 time
Liên hệ:

Re: Hiệu ứng sóng nước

Gửi bàigửi bởi khoaakt » T.Bảy 04/05/2013 8:41 pm

Ế! không chỉ cách dùng sao làm


Quay về “[.NET] Module, Class, UserControl, DLL”

Đang trực tuyến

Đang xem chuyên mục này: Không có thành viên nào trực tuyến.2 khách