Skip to content

Instantly share code, notes, and snippets.

@kylehowells
Last active December 18, 2015 22:38
Show Gist options
  • Save kylehowells/5855365 to your computer and use it in GitHub Desktop.
Save kylehowells/5855365 to your computer and use it in GitHub Desktop.
Little Animation controller written in Visual Basic I wrote for a simple game I had to do for College. (Why does VB not have animations built in?)
Public Class Animation
' Property delegate property for each animation
Private _delegate As AnimationFinished
Public Property didFinishDelegate() As AnimationFinished
Get
Return _delegate
End Get
Set(ByVal value As AnimationFinished)
_delegate = value
End Set
End Property
' Property for length of animation
Private _duration As Decimal = 1
Public Property duration() As Decimal
Get
Return _duration
End Get
Set(ByVal value As Decimal)
_duration = value
End Set
End Property
' Property for the animation curve, currently not implemented (linear only)
Private _animationCurve As String
Public Property animationCurve() As String
Get
Return _animationCurve
End Get
Set(ByVal value As String)
_animationCurve = value
End Set
End Property
' The target y position of the on screen element
Private _tagretY As Double
Public Property targetY() As Double
Get
Return _tagretY
End Get
Set(ByVal value As Double)
_tagretY = value
End Set
End Property
' The target x position of the on screen element
Private _targetX As String
Public Property targetX() As String
Get
Return _targetX
End Get
Set(ByVal value As String)
_targetX = value
End Set
End Property
End Class
' Declare a delegate to provide a callback when the animation ends
Public Delegate Sub AnimationFinished(ByVal control As Control)
' Declare the animation controller singleton (only one of them)
Public NotInheritable Class AnimationController
'Declare internal variables
Private Shared _thisInstance As AnimationController
Private animations As ArrayList = New ArrayList
' Setup
Protected Sub New()
timer = New Timer
timer.Interval = ((1 / 60) * 100)
timer.Enabled = True
End Sub
' Public accessor to the single copy of this object
Public Shared Function SharedAnimator() As AnimationController
' If the object hasn't been created yet start it
If _thisInstance Is Nothing Then
_thisInstance = New AnimationController
End If
Return _thisInstance
End Function
' Main run loop function, called at 60fps
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timer.Tick
Dim animationsTemp As ArrayList = animations.Clone
' If we are paused don't bother
If Me.paused = False Then
For Each animationHolder As AnimationHolder In animationsTemp
' Check if the individual animation is paused
If animationHolder.paused = False Then
Dim animation As Animation = animationHolder.animation
Dim duration As Double = animation.duration
Dim offset As Double = animationHolder.timeOffset
Dim control As Control = animationHolder.control
Dim startX As Double = animationHolder.startX
Dim startY As Double = animationHolder.startY
Dim bounds As Rectangle = control.Bounds
bounds.X = deltaForStartEndDuractionAndOffset(startX, animation.targetX, duration, offset)
bounds.Y = deltaForStartEndDuractionAndOffset(startY, animation.targetY, duration, offset)
control.Bounds = bounds
animationHolder.timeOffset = animationHolder.timeOffset + (1 / 60)
' Check if the animation should have ended now
If offset >= duration Then
' Remove the animation from our list of
animation.didFinishDelegate.Invoke(control)
cancelAnimationsForControl(control)
End If
End If
Next
End If
End Sub
' Property to pause all animations
Private _paused As Boolean = False
Public Property paused() As Boolean
Get
Return _paused
End Get
Set(ByVal value As Boolean)
_paused = value
End Set
End Property
' Pause the animation for a set user control
Private Sub setControlPaused(ByVal _pause As Boolean, ByVal control As Control)
animationForControl(control).paused = _pause
End Sub
' Add new animation for a certain user control
Public Sub AnimateControl(ByVal control As Control, ByVal animation As Object)
Dim animationContainer As AnimationHolder = New AnimationHolder
animationContainer.animation = animation
animationContainer.control = control
animations.Add(animationContainer)
End Sub
' Find the animation for a certain user control
Private Function animationForControl(ByVal control As Control) As AnimationHolder
For Each animationHolder As AnimationHolder In animations
If animationHolder.control.Equals(control) Then
Return animationHolder
End If
Next
Return Nothing
End Function
' Cancel an animation for a certain user control
Public Sub cancelAnimationsForControl(ByVal control As Control)
animations.Remove(animationForControl(control))
End Sub
' From the start point, and the target end point. Work out the current position, for an animation of a certain length, and a certain offset.
Private Function deltaForStartEndDuractionAndOffset(ByVal _start As Double, ByVal _end As Double, ByVal duration As Double, ByVal offset As Double) As Double
Dim timePercentage As Double = (offset / duration)
Dim distance As Double = _end - _start
Dim delta As Double = distance * timePercentage
Return (_start + delta)
End Function
' Private container class so animation objects can be reused
Private Class AnimationHolder
' Start Y position for the user control
Private _startY As Double
Public Property startY() As Double
Get
Return _startY
End Get
Set(ByVal value As Double)
_startY = value
End Set
End Property
' Start X position for the user control
Private _startX As Double
Public Property startX() As Double
Get
Return _startX
End Get
Set(ByVal value As Double)
_startX = value
End Set
End Property
' Property controlling pausing of the individual animation
Private _paused As Boolean = False
Public Property paused() As Boolean
Get
Return _paused
End Get
Set(ByVal value As Boolean)
_paused = value
End Set
End Property
' Property for the amount of time into the animation
Private _time As Double = 0
Public Property timeOffset() As Double
Get
Return _time
End Get
Set(ByVal value As Double)
_time = value
End Set
End Property
' Property for the user control the animation is acting on
Private _control As Control
Public Property control() As Control
Get
Return _control
End Get
Set(ByVal value As Control)
_control = value
Me.startX = _control.Left
Me.startY = _control.Top
End Set
End Property
' Property for the actual animation which is being run on the user control
Private _animation As Animation
Public Property animation() As Animation
Get
Return _animation
End Get
Set(ByVal value As Animation)
_animation = value
End Set
End Property
End Class
Friend WithEvents timer As System.Windows.Forms.Timer
End Class
' Create a new laser, the animation for it, and send it on its way
Private Sub fireLaser()
Dim y = Me.Height / 2
Dim x = Me.Width / 2
Dim laser As PictureBox = New PictureBox
laser.SizeMode = PictureBoxSizeMode.StretchImage
laser.BackColor = Color.Yellow
laser.Size = New Size(30, 16)
laser.Top = y
laser.Left = x
Me.Controls.Add(laser)
Dim animation As Animation = New Animation
animation.duration = 1 'Seconds
animation.targetX = Me.Width + 5
animation.targetY = y
animation.didFinishDelegate = New AnimationFinished(AddressOf RemoveLaser)
AnimationController.SharedAnimator.AnimateControl(laser, animation)
End Sub
Public Sub RemoveLaser(ByVal control As Control)
AnimationController.SharedAnimator.cancelAnimationsForControl(control)
If control IsNot Nothing And control.Parent IsNot Nothing Then
If control.IsDisposed <> True And control.Parent.IsDisposed <> True Then
control.Parent.Controls.Remove(control)
control.Dispose()
End If
End If
End Sub
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment