On this episode, we will be fixing our Floaters so that they have more functionality. Of course, this will come at a price: the floaters have to have their own structure, and all important members of this structure will have to be saved to and loaded from file when we save them. Now, a Floater that moves in a circle is fine, but it would be nice if it moved in other shapes as well. This, of course, requires us to make more periodic functions and, since we cannot store a function into a variable, we'll have to have a number to represent which function to use. This screams "Enumeration", so we'll use an Enumeration to determine which function to use. Of course, with all periodic functions, we need to determine an origin, a radius, and a frequency. The origin is just the initial position of the floater, which can be represented as the initial rectangle values, so the origin can be omitted. Our periodic functions are defining how much the floater moves during each frame, so we'll just call the radius a radispeed (or whatever). Since there will be a periodic function for horizontal and another for vertical movement (right now we're using Cos for horizontal and Sin for vertical), we need to have a pair of enumeration variables, a pair of radispeed, and of frequency. In order to make frequency values be stored in an integer, we will be dividing the frequency by a number like 64 or 128, so that we can have a value that represents a frequency of 1, and lower numbers will represent a frequency that is less than 1. Side Note: Since our periodic functions are defining how much the floater moves each frame, the actual radius (let's call it r) is multiplied by the frequency of the periodic function (let's say f) to give us the new coefficient (radispeed) of the periodic function (s, let's say). In our last example, the coefficient which multiplied the sine and cosine was 5 and the frequency is 1/8, so the actual radius of the floater here is s/f = r. So 5 divided by one-eighth (not divided by eight) gives us 40. Now, let's get to declaring the floater function enumeration and structure. First, the enumeration:

Public Enum PeriodicDesignation Stable = 0 'Denotes that the object will not move in this direction. CosineFxn 'Moves using the cosine function. SineFxn 'Moves using the sine function. End Enum |

Public Structure LevFloater Private rect As Rectangle Private horizfxn As PeriodicDesignation Private vertfxn As PeriodicDesignation Private xrspeed As Integer Private yrspeed As Integer Private xfreq As Integer Private yfreq As Integer End Structure |

Public Property Loc() As Rectangle Get Return rect End Get Set(ByVal Value As Rectangle) rect = Value End Set End Property Public Property FunctionHorizontal() As PeriodicDesignation Get Return horizfxn End Get Set(ByVal Value As PeriodicDesignation) horizfxn = Value End Set End Property Public Property FunctionVertical() As PeriodicDesignation Get Return vertfxn End Get Set(ByVal Value As PeriodicDesignation) vertfxn = Value End Set End Property Public Property RadispeedX() As Integer Get Return xrspeed End Get Set(ByVal Value As Integer) xrspeed = Value End Set End Property Public Property RadispeedY() As Integer Get Return yrspeed End Get Set(ByVal Value As Integer) yrspeed = Value End Set End Property Public Property FrequencyX() As Integer Get Return xfreq End Get Set(ByVal Value As Integer) xfreq = Value End Set End Property Public Property FrequencyY() As Integer Get Return yfreq End Get Set(ByVal Value As Integer) yfreq = Value End Set End Property |

Public Sub New(ByVal R As Rectangle, ByVal RadispdX As Integer, ByVal RadispdY As Integer, ByVal FreqX As Integer, ByVal FreqY As Integer, ByVal HFxn As PeriodicDesignation, ByVal VFxn As PeriodicDesignation) Me.horizfxn = HFxn Me.rect = R Me.vertfxn = VFxn Me.xfreq = FreqX Me.xrspeed = RadispdX Me.yfreq = FreqY Me.yrspeed = RadispdY End Sub |

Public Sub Offset(ByVal dX As Integer, ByVal dY As Integer) rect.Offset(dX, dY) End Sub |

Dim Floater As LevFloater 'This is the floater's location and movement information on the field. |

Const FREQUENCYDIVIDER As Integer = 128 'The number that will divide the frequency of periodic functions. |

Floater = New LevFloater(New Rectangle(420, 400, FLOATERSIZE, FLOATERSIZE), 5, 5, 16, 16, PeriodicDesignation.CosineFxn, PeriodicDesignation.SineFxn) 'Information about the floater. The width and height are all determined by the floatersize constant. |

GFX.DrawImage(FloatBmp, Floater.Loc.X, Floater.Loc.Y) 'Draw the floater to the display. There's only one frame, so no selection involved. |

If Floater.Loc.IntersectsWith(PlayerLoc) Then IsGoner = True 'The player has touched the floater. Lose a life. PlayerVeloc = SBARINITIALVELOCITY End If |

Dim dX, dY As Integer 'Indicates how much an object moves during this frame. |

Select Case Floater.FunctionHorizontal 'Looking at the function that we have designated, we choose the proper periodic function for setting to dX and dY. Case PeriodicDesignation.CosineFxn dX = Convert.ToInt32(Floater.RadispeedX * Math.Cos(Convert.ToDouble(FloatTick) * Floater.FrequencyX / Me.FREQUENCYDIVIDER)) Case PeriodicDesignation.SineFxn dX = Convert.ToInt32(Floater.RadispeedX * Math.Cos(Convert.ToDouble(FloatTick) * Floater.FrequencyX / Me.FREQUENCYDIVIDER)) Case PeriodicDesignation.Stable dX = 0 End Select Select Case Floater.FunctionVertical 'Looking at the function that we have designated, we choose the proper periodic function for setting to dX and dY. Case PeriodicDesignation.CosineFxn dY = Convert.ToInt32(Floater.RadispeedY * Math.Cos(Convert.ToDouble(FloatTick) * Floater.FrequencyY / Me.FREQUENCYDIVIDER)) Case PeriodicDesignation.SineFxn dY = Convert.ToInt32(Floater.RadispeedY * Math.Cos(Convert.ToDouble(FloatTick) * Floater.FrequencyY / Me.FREQUENCYDIVIDER)) Case PeriodicDesignation.Stable dY = 0 End Select Floater.Offset(dX, dY) 'Move the floater using our offset subroutine. |