# 使用win2d实现萤火虫粒子效果

Public Class FireflyParticle
Inherits Particle

Public Property CenterColor As Color
Public Property Opacity As Single = 1
Public Property Parent As FireFlyParticleSystem
Public Sub New(acceleration As Vector2, lifeTime As Integer, location As Vector2, velocity As Vector2, radius As Single, centerColor As Color, parent As FireFlyParticleSystem)
Me.Parent = parent
Me.CenterColor = centerColor
delta = 0.3 + 0.12 * Rndf()
End Sub

Dim delta!

Public Overrides Sub Update()
MyBase.Update()
Opacity -= delta!
Dim ub = Math.Max(0, 1 - Age / LifeTime)
If Opacity < 0 OrElse Opacity > ub Then
delta = -delta
If Opacity < 0 Then
Opacity = 0
ElseIf Opacity > ub Then
Opacity = ub
End If
End If
Velocity += New Vector2(Rndf() - 0.5, Rndf() - 0.5).WithLength(0.5)
Const bound = 20
Dim lx = Location.X, ly = Location.Y, vx = Velocity.X, vy = Velocity.Y
If lx < -bound Then
lx = -bound
vx = -vx
ElseIf lx - bound > Parent.Width Then
lx = Parent.Width + bound
vx = -vx
End If
If ly < -bound Then
ly = -bound
vy = -vy
ElseIf ly - bound > Parent.Height Then
ly = Parent.Height + bound
vy = -vy
End If
Location = New Vector2(lx, ly)
Velocity = New Vector2(vx, vy).WithLength(Parent.MaxSpeed)
End Sub
End Class

FireflyParticle类实现的是单独的萤火虫的飞舞，闪烁产生的数据变动。大多数的变量名很规范，所以不多解释了。

Public Class FireFlyParticleSystem
Inherits ParticleSystem(Of FireflyParticle)

Public Sub New(spawnInterval As Integer, initialCount As Integer, width As Integer, height As Integer, baseColor As Color)
Me.InitialCount = initialCount
Me.SpawnInterval = spawnInterval
Me.Width = width
Me.Height = height
Me.BaseColor = baseColor
For i = 0 To initialCount - 1
Dim part = CreateParticle()
Particles.Enqueue(part)
Next
End Sub
Protected Overrides Sub OnParticleRemoved()
MyBase.OnParticleRemoved()
Particles.Enqueue(CreateParticle())
End Sub
Public Overrides Property Particles As New Queue(Of FireflyParticle)
Public Overrides ReadOnly Property Presenter As GameVisualView = New FireFlyParticleSystemView(Me)
Public Overrides Property SpawnCount As Integer = 1
Public Overrides Property SpawnDuration As Integer = Integer.MaxValue
Public Property InitialCount As Integer
Public Overrides Property SpawnInterval As Integer = Integer.MaxValue
Public Property Width As Integer
Public Property Height As Integer
Public Property BaseColor As Color
Public Property MaxSpeed As Double = 1.4
Protected Overrides Function CreateParticle() As FireflyParticle
Return New FireflyParticle(New Vector2, (SpawnInterval * (0.6 + 0.4 * Rndf())), New Vector2(Rndf() * Width, Height * Rndf()), New Vector2(Rndf() - 0.5, Rndf() - 0.5).WithLength(MaxSpeed), 5 + Rndf(), BaseColor, Me)
End Function
End Class

Public Class ImTheBossTitleScreenN2ViewModel
Inherits GamePanel

Public Sub New(SpaceSize As Size)
MyBase.New(SpaceSize)
End Sub

Dim FireflySys As FireFlyParticleSystem
Protected Overrides Sub InitializeGameVisuals()
FireflySys = New FireFlyParticleSystem(10000, 20, SpaceSize.Width, SpaceSize.Height, Colors.YellowGreen)
End Sub

Private Sub ImTheBossTitleScreenN2ViewModel_SizeChanged(NewSize As Size) Handles Me.SizeChanged
FireflySys.Width = NewSize.Width
FireflySys.Height = NewSize.Height
End Sub
End Class

View代码只发呈现萤火虫。

Friend Class FireFlyParticleSystemView
Inherits TypedGameVisualPresenter(Of FireFlyParticleSystem)

Public Sub New(Target As FireFlyParticleSystem)
MyBase.New(Target)
End Sub

Public Overrides Sub OnDraw(sender As GamePanelView, DrawingSession As CanvasDrawingSession, Canvas As ICanvasResourceCreator)
For Each fireFly In Target.Particles
Using cl As New CanvasCommandList(DrawingSession), ds = cl.CreateDrawingSession
Using glow As New GlowEffectGraph
Dim color = fireFly.CenterColor
color.A = CByte(fireFly.Opacity * 255)
DrawingSession.DrawImage(glow.Output)
End Using
End Using
Next
End Sub

Public Overrides Sub OnGlobalQualityChanged(Quality As GraphicQualityManager)

End Sub
End Class

Class GlowEffectGraph
Implements IDisposable

Public ReadOnly Property Output() As ICanvasImage
Get
Return blur
End Get
End Property

Private morphology As New MorphologyEffect() With {
.Mode = MorphologyEffectMode.Dilate,
.Width = 1,
.Height = 1
}

Private blur As New GaussianBlurEffect() With {
.BlurAmount = 0,
.BorderMode = EffectBorderMode.Soft
}

Public Sub New()
blur.Source = morphology
End Sub

Public Sub Setup(source As ICanvasImage, amount As Single)
morphology.Source = source
Dim halfAmount = Math.Min(amount / 2, 100)
morphology.Width = CInt(Math.Truncate(Math.Ceiling(halfAmount)))
morphology.Height = CInt(Math.Truncate(Math.Ceiling(halfAmount)))
blur.BlurAmount = halfAmount
End Sub

#Region "IDisposable Support"
Private disposedValue As Boolean ' 要检测冗余调用

' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not disposedValue Then
If disposing Then
' TODO: 释放托管状态(托管对象)。
Output?.Dispose()
morphology.Dispose()
blur.Dispose()
End If

' TODO: 释放未托管资源(未托管对象)并在以下内容中替代 Finalize()。
' TODO: 将大型字段设置为 null。
End If
disposedValue = True
End Sub

' TODO: 仅当以上 Dispose(disposing As Boolean)拥有用于释放未托管资源的代码时才替代 Finalize()。
'Protected Overrides Sub Finalize()
'    ' 请勿更改此代码。将清理代码放入以上 Dispose(disposing As Boolean)中。
'    Dispose(False)
'    MyBase.Finalize()
'End Sub

' Visual Basic 添加此代码以正确实现可释放模式。
Public Sub Dispose() Implements IDisposable.Dispose
' 请勿更改此代码。将清理代码放入以上 Dispose(disposing As Boolean)中。
Dispose(True)
' TODO: 如果在以上内容中替代了 Finalize()，则取消注释以下行。
' GC.SuppressFinalize(Me)
End Sub
#End Region
End Class

http://v.youku.com/v_show/id_XMTU3MzA1ODg3Ng==.html

posted @ 2016-05-16 23:44 Nukepayload2 阅读(...) 评论(...) 编辑 收藏